This is docs/info/allegro.info, produced by makeinfo version 4.8 from
docs/texi/allegro.texi.

INFO-DIR-SECTION Libraries
START-INFO-DIR-ENTRY
* Allegro: (allegro).                 The Allegro game programming library.
END-INFO-DIR-ENTRY
This is the Info version of the Allegro manual

By Shawn Hargreaves


File: allegro.info,  Node: Top,  Prev: (dir),  Up: (dir)

          ______   ___    ___
         /\  _  \ /\_ \  /\_ \
         \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
          \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
           \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
            \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
             \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
                                            /\____/
                                            \_/__/     Version 4.1.12 (WIP)


                     A game programming library.

                  By Shawn Hargreaves, Nov 10, 2003.

                     See the AUTHORS file for a
                    complete list of contributors.

#include <std_disclaimer.h>

"I do not accept responsibility for any effects, adverse or otherwise,
that this code may have on you, your computer, your sanity, your dog,
and anything else that you can think of. Use it at your own risk."

* Menu:

* Using::                   Using Allegro
* Structures::              Structures and types defined by Allegro
* Unicode::                 Unicode routines
* Configuration::           Configuration routines
* Mouse::                   Mouse routines
* Timer::                   Timer routines
* Keyboard::                Keyboard routines
* Joystick::                Joystick routines
* Graphics::                Graphics modes
* Bitmap::                  Bitmap objects
* Loading::                 Loading image files
* Palette::                 Palette routines
* Truecolor::               Truecolor pixel formats
* Drawing::                 Drawing primitives
* Blitting::                Blitting and sprites
* RLE::                     RLE sprites
* Compiled::                Compiled sprites
* Text::                    Text output
* Polygon::                 Polygon rendering
* Transparency::            Transparency and patterned drawing
* Converting::              Converting between color formats
* Direct::                  Direct access to video memory
* FLIC::                    FLIC routines
* Sound::                   Sound init routines
* Digital::                 Digital sample routines
* Music::                   Music routines (MIDI)
* Audio::                   Audio stream routines
* Recording::               Recording routines
* File::                    File and compression routines
* Datafile::                Datafile routines
* Fixed::                   Fixed point math routines
* 3D::                      3D math routines
* Quaternion::              Quaternion math routines
* GUI::                     GUI routines
* DOS::                     DOS specifics
* Windows::                 Windows specifics
* Unix::                    Unix specifics
* BeOS::                    BeOS specifics
* QNX::                     QNX specifics
* MacOS::                   MacOS X specifics
* Differences::             Differences between platforms
* Reducing::                Reducing your executable size
* Debugging::               Debugging
* Makefile::                Makefile targets
* Available::               Available Allegro examples
* Conclusion::              Conclusion
* Index::                   Index


File: allegro.info,  Node: Using,  Next: Structures,  Up: Top

1 Using Allegro
***************

See readme.txt for a general introduction, copyright details, and
information about how to install Allegro and link your program with it.

* Menu:

* install_allegro::
* allegro_init::
* allegro_exit::
* END_OF_MAIN::
* allegro_id::
* allegro_error::
* os_type::
* os_version::
* os_multitasking::
* allegro_message::
* set_window_title::
* set_close_button_callback::
* desktop_color_depth::
* get_desktop_resolution::
* yield_timeslice::
* check_cpu::
* cpu_vendor::
* cpu_family::
* cpu_model::
* cpu_capabilities::


File: allegro.info,  Node: install_allegro,  Next: allegro_init,  Up: Using

1.1 install_allegro
===================

int install_allegro(int system_id, int *errno_ptr, int (*atexit_ptr)());
     Initialises the Allegro library. You must call either this or
     allegro_init() before doing anything other than using the Unicode
     routines. If you want to use a text mode other than UTF-8, you can
     set it with set_uformat() before you call this. The other
     functions that can be called before this one will be marked
     explicitly in the documentation.

     The available system ID codes will vary from one platform to
     another, but you will almost always want to pass
     SYSTEM_AUTODETECT. Alternatively, SYSTEM_NONE installs a stripped
     down version of Allegro that won't even try to touch your hardware
     or do anything platform specific: this can be useful for
     situations where you only want to manipulate memory bitmaps, such
     as the text mode datafile tools or the Windows GDI interfacing
     functions.

     The `errno_ptr' and `atexit_ptr' parameters should point to the
     errno variable and atexit function from your libc: these are
     required because when Allegro is linked as a DLL, it doesn't have
     direct access to your local libc data. `atexit_ptr' may be NULL,
     in which case it is your responsibility to call allegro_exit()
     manually. Example:

          install_allegro(SYSTEM_AUTODETECT, &errno, atexit);

     This function returns zero on success and non-zero on failure
     (e.g. no system driver could be used). Note: in previous versions
     of Allegro this function would abort on error.

See also:
*Note allegro_init::.
*Note allegro_exit::.
*Note set_uformat::.

File: allegro.info,  Node: allegro_init,  Next: allegro_exit,  Prev: install_allegro,  Up: Using

1.2 allegro_init
================

int allegro_init();
     Macro which initialises the Allegro library. This is the same
     thing as calling install_allegro(SYSTEM_AUTODETECT, &errno,
     atexit).

See also:
*Note install_allegro::.
*Note allegro_exit::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: allegro_exit,  Next: END_OF_MAIN,  Prev: allegro_init,  Up: Using

1.3 allegro_exit
================

void allegro_exit();
     Closes down the Allegro system. This includes returning the system
     to text mode and removing whatever mouse, keyboard, and timer
     routines have been installed. You don't normally need to bother
     making an explicit call to this function, because allegro_init()
     installs it as an atexit() routine so it will be called
     automatically when your program exits.

     Note that after you call this function, other functions like
     destroy_bitmap() will most likely crash. This is a problem for C++
     global destructors, which usually get called after atexit(), so
     don't put Allegro calls in them. You can write the destructor code
     in another method which you can manually call before your program
     exits, avoiding this problem.

See also:
*Note install_allegro::.
*Note allegro_init::.
*Note destroy_bitmap::.
*Note ex3d::.
*Note exscn3d::.
*Note exswitch::.
*Note exxfade::.
*Note exzbuf::.

File: allegro.info,  Node: END_OF_MAIN,  Next: allegro_id,  Prev: allegro_exit,  Up: Using

1.4 END_OF_MAIN
===============

Macro END_OF_MAIN()
     In order to maintain cross-platform compatibility, you have to put
     this macro at the very end of your main function. This macro uses
     some `magic' to mangle your main procedure on platforms that need
     it like Windows, Linux or MacOS X. On the other platforms this
     macro compiles to nothing, so you don't have to #ifdef around it.
     Example:

          int main(void)
          {
             allegro_init();
             /* more stuff goes here */
             ...
             return 0;
          }
          END_OF_MAIN()

See also:
*Note Windows specifics: Windows.
*Note Unix specifics: Unix.
*Note MacOS X specifics: MacOS.
*Note Differences between platforms: Differences.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: allegro_id,  Next: allegro_error,  Prev: END_OF_MAIN,  Up: Using

1.5 allegro_id
==============

extern char allegro_id[];
     Text string containing a date and version number for the library,
     in case you want to display these somewhere.



File: allegro.info,  Node: allegro_error,  Next: os_type,  Prev: allegro_id,  Up: Using

1.6 allegro_error
=================

extern char allegro_error[ALLEGRO_ERROR_SIZE];
     Text string used by set_gfx_mode() and install_sound() to report
     error messages. If they fail and you want to tell the user why,
     this is the place to look for a description of the problem.

See also:
*Note set_gfx_mode::.
*Note install_sound::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: os_type,  Next: os_version,  Prev: allegro_error,  Up: Using

1.7 os_type
===========

extern int os_type;
     Set by allegro_init() to one of the values:

          OSTYPE_UNKNOWN    - unknown, or regular MSDOS
          OSTYPE_WIN3       - Windows 3.1 or earlier
          OSTYPE_WIN95      - Windows 95
          OSTYPE_WIN98      - Windows 98
          OSTYPE_WINME      - Windows ME
          OSTYPE_WINNT      - Windows NT
          OSTYPE_WIN2000    - Windows 2000
          OSTYPE_WINXP      - Windows XP
          OSTYPE_OS2        - OS/2
          OSTYPE_WARP       - OS/2 Warp 3
          OSTYPE_DOSEMU     - Linux DOSEMU
          OSTYPE_OPENDOS    - Caldera OpenDOS
          OSTYPE_LINUX      - Linux
          OSTYPE_SUNOS      - SunOS/Solaris
          OSTYPE_FREEBSD    - FreeBSD
          OSTYPE_NETBSD     - NetBSD
          OSTYPE_IRIX       - IRIX
          OSTYPE_DARWIN     - Darwin
          OSTYPE_QNX        - QNX
          OSTYPE_UNIX       - Unknown Unix variant
          OSTYPE_BEOS       - BeOS
          OSTYPE_MACOS      - MacOS
          OSTYPE_MACOSX     - MacOS X

See also:
*Note allegro_init::.
*Note os_version::.
*Note os_multitasking::.

File: allegro.info,  Node: os_version,  Next: os_multitasking,  Prev: os_type,  Up: Using

1.8 os_version
==============

extern int os_version;

extern int os_revision;
     The major and minor version of the Operating System currently
     running.  Set by allegro_init(). If Allegro for some reason was
     not able to retrieve the version of the Operating System,
     os_version and os_revision will be set to -1. For example: Under
     Win98 SE (v4.10.2222) os_version will be set to 4 and os_revision
     to 10.

See also:
*Note os_type::.
*Note os_multitasking::.

File: allegro.info,  Node: os_multitasking,  Next: allegro_message,  Prev: os_version,  Up: Using

1.9 os_multitasking
===================

extern int os_multitasking;
     Set by allegro_init() to either TRUE or FALSE depending on whether
     your Operating System is multitasking or not.

See also:
*Note os_type::.
*Note os_version::.
*Note exdodgy::.

File: allegro.info,  Node: allegro_message,  Next: set_window_title,  Prev: os_multitasking,  Up: Using

1.10 allegro_message
====================

void allegro_message(const char *text_format, ...);
     Outputs a message, using a printf() format string. This function
     must only be used when you aren't in graphics mode, eg. before
     calling set_gfx_mode(), or after a set_gfx_mode(GFX_TEXT). On
     platforms that have a text console (DOS and Unix) it will print
     the string to that console, attempting to work around codepage
     differences by reducing any accented characters to 7-bit ASCII
     approximations, and on platforms featuring a windowing system it
     will bring up a GUI message box. Example:

          ret = allegro_init();
          if (ret != 0) {
             allegro_message("Sorry, couldn't init Allegro (%d).\n", ret);
             exit(ret);
          }

See also:
*Note set_uformat::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: set_window_title,  Next: set_close_button_callback,  Prev: allegro_message,  Up: Using

1.11 set_window_title
=====================

void set_window_title(const char *name);
     On platforms that are capable of it, this routine alters the
     window title for your Allegro program. Note that Allegro cannot
     set the window title when running in a DOS box under Windows.

See also:
*Note set_close_button_callback::.
*Note set_uformat::.
*Note exunicod::.

File: allegro.info,  Node: set_close_button_callback,  Next: desktop_color_depth,  Prev: set_window_title,  Up: Using

1.12 set_close_button_callback
==============================

int set_close_button_callback(void (*proc)(void));
     On platforms that have a close button, this routine installs a
     callback function to handle the close event. In other words, when
     the user clicks the close button on your program's window or any
     equivalent device, the function you specify here will be called.

     This function should not generally attempt to exit the program or
     save any data itself. The function could be called at any time,
     and there is usually a risk of conflict with the main thread of
     the program. Instead, you should set a flag during this function,
     and test it on a regular basis in the main loop of the program.

     Pass NULL as the `proc' argument to this function to disable the
     close button functionality, which is the default state.

     Note that Allegro cannot intercept the close button of a DOS box in
     Windows.

     Returns zero on success and non-zero on failure (e.g. the feature
     is not supported by the platform).

See also:
*Note set_window_title::.

File: allegro.info,  Node: desktop_color_depth,  Next: get_desktop_resolution,  Prev: set_close_button_callback,  Up: Using

1.13 desktop_color_depth
========================

int desktop_color_depth();
     Finds out the currently selected desktop color depth. You can use
     this information to make your program use the same color depth as
     the desktop, which will likely make it run faster because the
     graphic driver won't be doing unnecessary color conversions behind
     your back.

     Under some OSes, switching to a full screen graphics mode may
     automatically change the desktop color depth. You have, therefore,
     to call this function before setting any graphics mode in order to
     retrieve the real desktop color depth. Example:

          allegro_init();
          ...
          if ((depth = desktop_color_depth()) != 0) {
             set_color_depth(depth);
          }

     Returns the color depth or zero on platforms where this
     information is not available or does not apply.

See also:
*Note get_desktop_resolution::.
*Note set_color_depth::.
*Note set_gfx_mode::.

File: allegro.info,  Node: get_desktop_resolution,  Next: yield_timeslice,  Prev: desktop_color_depth,  Up: Using

1.14 get_desktop_resolution
===========================

int get_desktop_resolution(int *width, int *height);
     Finds out the currently selected desktop resolution. You can use
     this information to avoid creating windows bigger than the current
     resolution.  This is especially important for some windowed
     drivers which are unable to create windows bigger than the
     desktop. Each parameter is a pointer to an integer where one
     dimension of the screen will be stored.

     Under some OSes, switching to a full screen graphics mode may
     automatically change the desktop resolution. You have, therefore,
     to call this function before setting any graphics mode in order to
     retrieve the real desktop resolution. Example:

          int width, height;

          allegro_init();
          ...
          if (get_desktop_resolution(&width, &height) == 0) {
             /* Got the resolution correctly */
          }

     Returns zero on success, or a negative number if this information
     is not available or does not apply, in which case the values
     stored in the variables you provided for `width' and `height' are
     undefined.

See also:
*Note desktop_color_depth::.
*Note set_gfx_mode::.

File: allegro.info,  Node: yield_timeslice,  Next: check_cpu,  Prev: get_desktop_resolution,  Up: Using

1.15 yield_timeslice
====================

void yield_timeslice();
     To "play nice" with other processes you can call this function. On
     systems that support it, it will give up the rest of the current
     scheduler timeslice and offer it to some other process. Your CPU
     consumption rate will drop *only* if there is another process
     ready to use the freed timeslice.

     Note that calling this inside your active game loop is a very bad
     idea, you never know when the OS will give you the CPU back, so
     you could end up missing the vertical retrace and skipping frames.

See also:
*Note vsync::.

File: allegro.info,  Node: check_cpu,  Next: cpu_vendor,  Prev: yield_timeslice,  Up: Using

1.16 check_cpu
==============

void check_cpu();
     Detects the CPU type, setting the following global variables. You
     don't normally need to call this, because allegro_init() will do
     it for you.

See also:
*Note cpu_vendor::.
*Note cpu_family::.
*Note cpu_model::.
*Note cpu_capabilities::.
*Note allegro_init::.

File: allegro.info,  Node: cpu_vendor,  Next: cpu_family,  Prev: check_cpu,  Up: Using

1.17 cpu_vendor
===============

extern char cpu_vendor[];
     Contains the CPU vendor name, if known (empty string on non-Intel
     platforms). You can read this variable after you have called
     check_cpu() (which is automatically called by allegro_init()).

See also:
*Note check_cpu::.
*Note cpu_family::.
*Note cpu_model::.
*Note cpu_capabilities::.
*Note allegro_init::.

File: allegro.info,  Node: cpu_family,  Next: cpu_model,  Prev: cpu_vendor,  Up: Using

1.18 cpu_family
===============

extern int cpu_family;
     Contains the Intel CPU type, where applicable: 3=386, 4=486,
     5=Pentium, 6=PPro, etc. You can read this variable after you have
     called check_cpu() (which is automatically called by
     allegro_init()).

See also:
*Note check_cpu::.
*Note cpu_vendor::.
*Note cpu_model::.
*Note cpu_capabilities::.
*Note allegro_init::.

File: allegro.info,  Node: cpu_model,  Next: cpu_capabilities,  Prev: cpu_family,  Up: Using

1.19 cpu_model
==============

extern int cpu_model;
     Contains the Intel CPU submodel, where applicable. On a 486
     (cpu_family=4), zero or one indicates a DX chip, 2 an SX, 3 a 487
     (SX) or 486 DX, 4 an SL, 5 an SX2, 7 a DX2 write-back enhanced, 8
     a DX4 or DX4 overdrive, 14 a Cyrix, and 15 is unknown. On a
     Pentium chip (cpu_family=5), 1 indicates a Pentium (510\66,
     567\66), 2 is a Pentium P54C, 3 is a Pentium overdrive processor,
     5 is a Pentium overdrive for IntelDX4, 14 is a Cyrix, and 15 is
     unknown. You can read this variable after you have called
     check_cpu() (which is automatically called by allegro_init()).

See also:
*Note check_cpu::.
*Note cpu_vendor::.
*Note cpu_family::.
*Note cpu_capabilities::.
*Note allegro_init::.

File: allegro.info,  Node: cpu_capabilities,  Next: fixed,  Prev: cpu_model,  Up: Using

1.20 cpu_capabilities
=====================

extern int cpu_capabilities;
     Contains CPU flags indicating what features are available on the
     current CPU. The flags can be any combination of these:

          CPU_ID       - Indicates that the "cpuid" instruction is
                         available. If this is set, then all Allegro CPU
                         variables are 100% reliable, otherwise there
                         may be some mistakes.
          CPU_FPU      - An x87 FPU is available.
          CPU_MMX      - Intel MMX  instruction set is available.
          CPU_MMXPLUS  - Intel MMX+ instruction set is available.
          CPU_SSE      - Intel SSE  instruction set is available.
          CPU_SSE2     - Intel SSE2 instruction set is available.
          CPU_3DNOW    - AMD 3DNow! instruction set is available.
          CPU_ENH3DNOW - AMD Enhanced 3DNow! instruction set is
                         available.
          CPU_CMOV     - Pentium Pro "cmov" instruction is available.

     You can check for multiple features by OR-ing the flags together.
     For example, to check if the CPU has an FPU and MMX instructions
     available, you'd do:

          if ((cpu_capabilities & (CPU_FPU | CPU_MMX)) ==
              (CPU_FPU | CPU_MMX)) {
             printf("CPU has both an FPU and MMX instructions!\n");
          }

     You can read this variable after you have called check_cpu()
     (which is automatically called by allegro_init()).

See also:
*Note check_cpu::.
*Note cpu_vendor::.
*Note cpu_family::.
*Note cpu_model::.
*Note cpu_capabilities::.
*Note allegro_init::.

File: allegro.info,  Node: Structures,  Next: Unicode,  Prev: Using,  Up: Top

2 Structures and types defined by Allegro
*****************************************

There are several structures and types defined by Allegro which are used
in many functions (like the BITMAP structure). This section of the
manual describes their useful content from a user point of view when
they don't fit very well any of the existing manual sections, and
redirects you to the appropiate section when it's already described
there. Note that unless stated otherwise, the contents shown here are
just for read only purposes, there might be other internal flags, but
you shouldn't depend on them being available in past/future versions of
Allegro.

* Menu:

* fixed::
* BITMAP::
* RLE_SPRITE::
* COMPILED_SPRITE::
* JOYSTICK_INFO::
* JOYSTICK_BUTTON_INFO::
* JOYSTICK_STICK_INFO::
* JOYSTIC_AXIS_INFO::
* GFX_MODE_LIST::
* GFX_MODE::
* PALETTE::
* RGB::
* V3D::
* V3D_f::
* COLOR_MAP::
* RGB_MAP::
* al_ffblk::
* DATAFILE::
* MATRIX::
* MATRIX_f::
* QUAT::
* DIALOG::
* MENU::
* DIALOG_PLAYER::
* MENU_PLAYER::
* FONT::
* ZBUFFER::
* SAMPLE::
* MIDI::
* AUDIOSTREAM::
* PACKFILE::


File: allegro.info,  Node: fixed,  Next: BITMAP,  Prev: cpu_capabilities,  Up: Structures

2.1 fixed
=========

typedef long fixed
     This is a fixed point integer which can replace float with similar
     results and is faster than float on low end machines. Read chapter
     "Fixed point math routines" for the full explanation.

See also:
*Note Fixed point math routines: Fixed.
*Note ex12bit::.
*Note ex3buf::.
*Note ex3d::.
*Note excustom::.
*Note exfixed::.
*Note exspline::.
*Note exsprite::.
*Note exstars::.
*Note exupdate::.

File: allegro.info,  Node: BITMAP,  Next: RLE_SPRITE,  Prev: fixed,  Up: Structures

2.2 BITMAP
==========

typedef struct BITMAP

          int w, h;               - size of the bitmap in pixels
          int clip;               - non-zero if clipping is turned on
          int cl, cr, ct, cb;     - clip rectangle left, right, top,
                                    and bottom
          unsigned char *line[];  - pointers to the start of each line

     There is some other stuff in the structure as well, but it is
     liable to change and you shouldn't use anything except the above.
     The `w' and `h' fields can be used to obtain the size of an
     existing bitmap:

          bmp = load_bitmap("file.bmp", pal);
          allegro_message("Bitmap size: (%dx%d)\n", bmp->w, bmp->h);

     The clipping rectangle is inclusive on the left and top (0 allows
     drawing to position 0) but exclusive on the right and bottom (10
     allows drawing to position 9, but not to 10). Note this is not the
     same format as you pass to set_clip(), which takes inclusive
     coordinates for all four corners. All the values of this structure
     should be regarded as read-only, with the exception of the line
     field, whose access is described in depth in the "Direct access to
     video memory" section of the manual. If you want to modify the
     clipping region, please refrain from changing this structure. Use
     set_clip() instead.

See also:
*Note create_bitmap::.
*Note set_clip::.
*Note bitmap_color_depth::.
*Note RLE_SPRITE::.
*Note COMPILED_SPRITE::.
*Note Direct access to video memory: Direct.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: RLE_SPRITE,  Next: COMPILED_SPRITE,  Prev: BITMAP,  Up: Structures

2.3 RLE_SPRITE
==============

typedef struct RLE_SPRITE

          int w, h;           - width and height in pixels
          int color_depth;    - color depth of the image

     RLE sprites store the image in a simple run-length encoded format,
     where repeated zero pixels are replaced by a single length count,
     and strings of non-zero pixels are preceded by a counter giving
     the length of the solid run. Read chapter "RLE sprites" for a
     description of the restrictions and how to obtain/use this
     structure.

See also:
*Note get_rle_sprite::.
*Note BITMAP::.
*Note COMPILED_SPRITE::.
*Note RLE sprites: RLE.

File: allegro.info,  Node: COMPILED_SPRITE,  Next: JOYSTICK_INFO,  Prev: RLE_SPRITE,  Up: Structures

2.4 COMPILED_SPRITE
===================

typedef struct COMPILED_SPRITE

          short planar;        - set if it's a planar (mode-X) sprite
          short color_depth;   - color depth of the image
          short w, h;          - size of the sprite

     Compiled sprites are stored as actual machine code instructions
     that draw a specific image onto a bitmap, using mov instructions
     with immediate data values. Read chapter "Compiled sprites" for a
     description of the restrictions and how to obtain/use this
     structure.

See also:
*Note get_compiled_sprite::.
*Note BITMAP::.
*Note RLE_SPRITE::.
*Note Compiled sprites: Compiled.

File: allegro.info,  Node: JOYSTICK_INFO,  Next: JOYSTICK_BUTTON_INFO,  Prev: COMPILED_SPRITE,  Up: Structures

2.5 JOYSTICK_INFO
=================

typedef struct JOYSTICK_INFO

          int flags;                       - status flags for this
                                             joystick
          int num_sticks;                  - how many stick inputs?
          int num_buttons;                 - how many buttons?
          JOYSTICK_STICK_INFO stick[n];    - stick state information
          JOYSTICK_BUTTON_INFO button[n];  - button state information

     Read chapter "Joystick routines" for a description on how to
     obtain/use this structure.

See also:
*Note joy::.
*Note Joystick routines: Joystick.

File: allegro.info,  Node: JOYSTICK_BUTTON_INFO,  Next: JOYSTICK_STICK_INFO,  Prev: JOYSTICK_INFO,  Up: Structures

2.6 JOYSTICK_BUTTON_INFO
========================

typedef struct JOYSTICK_BUTTON_INFO

          int b;                           - boolean on/off flag
          char *name;                      - description of this
                                             button

     Read chapter "Joystick routines" for a description on how to
     obtain/use this structure.

See also:
*Note joy::.
*Note Joystick routines: Joystick.

File: allegro.info,  Node: JOYSTICK_STICK_INFO,  Next: JOYSTIC_AXIS_INFO,  Prev: JOYSTICK_BUTTON_INFO,  Up: Structures

2.7 JOYSTICK_STICK_INFO
=======================

typedef struct JOYSTICK_STICK_INFO

          int flags;                       - status flags for this
                                             input
          int num_axis;                    - how many axis do we
                                             have?
          JOYSTICK_AXIS_INFO axis[n];      - axis state information
          char *name;                      - description of this
                                             input

     Read chapter "Joystick routines" for a description on how to
     obtain/use this structure.

See also:
*Note joy::.
*Note Joystick routines: Joystick.

File: allegro.info,  Node: JOYSTIC_AXIS_INFO,  Next: GFX_MODE_LIST,  Prev: JOYSTICK_STICK_INFO,  Up: Structures

2.8 JOYSTIC_AXIS_INFO
=====================

typedef struct JOYSTIC_AXIS_INFO

          int pos;                         - analogue axis position
          int d1, d2;                      - digital axis position
          char *name;                      - description of this axis

     Read chapter "Joystick routines" for a description on how to
     obtain/use this structure.

See also:
*Note joy::.
*Note Joystick routines: Joystick.

File: allegro.info,  Node: GFX_MODE_LIST,  Next: GFX_MODE,  Prev: JOYSTIC_AXIS_INFO,  Up: Structures

2.9 GFX_MODE_LIST
=================

typedef struct GFX_MODE_LIST

          int num_modes;
          GFX_MODE *mode;

     Structure returned by get_gfx_mode_list, which contains an array of
     GFX_MODE structures.

See also:
*Note GFX_MODE::.
*Note get_gfx_mode_list::.

File: allegro.info,  Node: GFX_MODE,  Next: PALETTE,  Prev: GFX_MODE_LIST,  Up: Structures

2.10 GFX_MODE
=============

typedef struct GFX_MODE

          int width, height, bpp;

     Structure contained in GFX_MODE_LIST.

See also:
*Note GFX_MODE_LIST::.
*Note get_gfx_mode_list::.

File: allegro.info,  Node: PALETTE,  Next: RGB,  Prev: GFX_MODE,  Up: Structures

2.11 PALETTE
============

typedef RGB PALETTE[PAL_SIZE]
     Allegro palettes are arrays of PAL_SIZE RGB entries.

See also:
*Note RGB::.
*Note Palette routines: Palette.
*Note Available Allegro examples: Available.
*Note RGB::.

File: allegro.info,  Node: RGB,  Next: V3D,  Prev: PALETTE,  Up: Structures

2.12 RGB
========

typedef struct RGB

          unsigned char r, g, b;

     Palette entry. It contains an additional field for the purpose of
     padding but you should not usually care about it. Read chapter
     "Palette routines" for a description on how to obtain/use this
     structure.

See also:
*Note Palette routines: Palette.
*Note PALETTE::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: V3D,  Next: V3D_f,  Prev: RGB,  Up: Structures

2.13 V3D
========

typedef struct V3D

          fixed x, y, z;       - position
          fixed u, v;          - texture map coordinates
          int c;               - color

     A vertex structure used by polygon3d and other polygon rendering
     functions. Read the description of polygon3d for a description on
     how to obtain/use this structure.

See also:
*Note V3D_f::.
*Note polygon3d::.
*Note Fixed point trig::.
*Note ex3d::.

File: allegro.info,  Node: V3D_f,  Next: COLOR_MAP,  Prev: V3D,  Up: Structures

2.14 V3D_f
==========

typedef struct V3D_f

          float x, y, z;       - position
          float u, v;          - texture map coordinates
          int c;               - color

     Like V3D but using float values instead of fixed ones.

See also:
*Note V3D::.
*Note polygon3d::.
*Note Fixed point trig::.
*Note excamera::.
*Note exscn3d::.
*Note exzbuf::.

File: allegro.info,  Node: COLOR_MAP,  Next: RGB_MAP,  Prev: V3D_f,  Up: Structures

2.15 COLOR_MAP
==============

typedef struct COLOR_MAP

          unsigned char data[PAL_SIZE][PAL_SIZE];

     Read chapter "Transparency and patterned drawing", section
     "256-color transparency" for a description on how to obtain/use
     this structure.

See also:
*Note 256-color transparency::.
*Note color_map::.
*Note ex3d::.
*Note excolmap::.
*Note exlights::.
*Note exshade::.
*Note extrans::.

File: allegro.info,  Node: RGB_MAP,  Next: al_ffblk,  Prev: COLOR_MAP,  Up: Structures

2.16 RGB_MAP
============

typedef struct RGB_MAP

          unsigned char data[32][32][32];

     Read chapter "Converting between color formats" for a description
     on how to obtain/use this structure.

See also:
*Note Converting between color formats: Converting.
*Note create_rgb_table::.
*Note ex3d::.
*Note excolmap::.
*Note exrgbhsv::.
*Note exshade::.
*Note extrans::.

File: allegro.info,  Node: al_ffblk,  Next: DATAFILE,  Prev: RGB_MAP,  Up: Structures

2.17 al_ffblk
=============

struct al_ffblk

          int attrib;       - actual attributes of the file found
          time_t time;      - modification time of file
          long size;        - size of file
          char name[512];   - name of file

     Read the description of al_findfirst for a description on how to
     obtain/use this structure.

See also:
*Note al_findfirst::.

File: allegro.info,  Node: DATAFILE,  Next: MATRIX,  Prev: al_ffblk,  Up: Structures

2.18 DATAFILE
=============

typedef struct DATAFILE

          void *dat;     - pointer to the actual data
          int type;      - type of the data
          long size;     - size of the data in bytes
          void *prop;    - list of object properties

     Read chapter "Datafile routines", section "Using datafiles" for a
     description on how to obtain/use this structure.

See also:
*Note load_datafile::.
*Note Using datafiles::.
*Note excustom::.
*Note exdata::.
*Note exexedat::.
*Note exgui::.
*Note exsprite::.
*Note exunicod::.

File: allegro.info,  Node: MATRIX,  Next: MATRIX_f,  Prev: DATAFILE,  Up: Structures

2.19 MATRIX
===========

typedef struct MATRIX

          fixed v[3][3];           - 3x3 scaling and rotation component
          fixed t[3];              - x/y/z translation component

     Fixed point matrix structure. Read chapter "3D math routines" for a
     description on how to obtain/use this structure.

See also:
*Note MATRIX_f::.
*Note 3D math routines: 3D.
*Note ex12bit::.
*Note ex3d::.
*Note exstars::.

File: allegro.info,  Node: MATRIX_f,  Next: QUAT,  Prev: MATRIX,  Up: Structures

2.20 MATRIX_f
=============

typedef struct MATRIX_f

          float v[3][3];           - 3x3 scaling and rotation component
          float t[3];              - x/y/z translation component

     Floating point matrix structure. Read chapter "3D math routines"
     for a description on how to obtain/use this structure.

See also:
*Note MATRIX::.
*Note 3D math routines: 3D.
*Note excamera::.
*Note exquat::.
*Note exscn3d::.
*Note exzbuf::.

File: allegro.info,  Node: QUAT,  Next: DIALOG,  Prev: MATRIX_f,  Up: Structures

2.21 QUAT
=========

typedef struct QUAT

          float w, x, y, z;

     Read chapter "Quaternion math routines" for a description on how to
     obtain/use this structure.

See also:
*Note Quaternion math routines: Quaternion.
*Note exquat::.

File: allegro.info,  Node: DIALOG,  Next: MENU,  Prev: QUAT,  Up: Structures

2.22 DIALOG
===========

typedef struct DIALOG

          int (*proc)(int, DIALOG *, int); - dialog procedure
                                             (message handler)
          int x, y, w, h;       - position and size of the object
          int fg, bg;           - foreground and background colors
          int key;              - ASCII keyboard shortcut
          int flags;            - flags about the status of the object
          int d1, d2;           - whatever you want to use them for
          void *dp, *dp2, *dp3; - pointers to more object-specific data

     This is the structure which contains a GUI object. Read chapter
     "GUI routines" for a description on how to obtain/use this
     structure.

See also:
*Note do_dialog::.
*Note GUI routines: GUI.
*Note excustom::.
*Note exgui::.
*Note exrgbhsv::.

File: allegro.info,  Node: MENU,  Next: DIALOG_PLAYER,  Prev: DIALOG,  Up: Structures

2.23 MENU
=========

typedef struct MENU

          char *text;          - the text to display for the menu item
          int (*proc)(void);   - called when the menu item is clicked
          struct MENU *child;  - nested child menu
          int flags;           - disabled or checked state
          void *dp;            - pointer to any data you need

     Structure used to hold an entry of a menu. Read chapter "GUI
     routines", section "GUI menus" for a description on how to
     obtain/use this structure.

See also:
*Note do_menu::.
*Note GUI menus::.
*Note exgui::.

File: allegro.info,  Node: DIALOG_PLAYER,  Next: MENU_PLAYER,  Prev: MENU,  Up: Structures

2.24 DIALOG_PLAYER
==================

typedef struct DIALOG_PLAYER
     A structure which holds GUI data used internally by Allegro. Read
     the documentation of init_dialog() for a description on how to
     obtain/use this structure.

See also:
*Note init_dialog::.
*Note update_dialog::.
*Note shutdown_dialog::.
*Note GUI routines: GUI.

File: allegro.info,  Node: MENU_PLAYER,  Next: FONT,  Prev: DIALOG_PLAYER,  Up: Structures

2.25 MENU_PLAYER
================

typedef struct MENU_PLAYER
     A structure which holds GUI data used internally by Allegro. Read
     the documentation of init_menu() for a description on how to
     obtain/use this structure.

See also:
*Note init_menu::.
*Note update_menu::.
*Note shutdown_menu::.
*Note GUI menus::.

File: allegro.info,  Node: FONT,  Next: ZBUFFER,  Prev: MENU_PLAYER,  Up: Structures

2.26 FONT
=========

typedef struct FONT
     A structure holding an Allegro font, usually created beforehand
     with the grabber tool or Allegro's default font.

See also:
*Note font::.
*Note excustom::.
*Note exunicod::.

File: allegro.info,  Node: ZBUFFER,  Next: SAMPLE,  Prev: FONT,  Up: Structures

2.27 ZBUFFER
============

typedef struct BITMAP ZBUFFER
     Structure used by Allegro's 3d zbuffered rendering functions. You
     are not supposed to mix ZBUFFER with BITMAP even though it is
     currently possible to do so. This is just an internal
     representation, and it may change in the future.

See also:
*Note Zbuffered rendering::.
*Note BITMAP::.
*Note exzbuf::.
*Note BITMAP::.

File: allegro.info,  Node: SAMPLE,  Next: MIDI,  Prev: ZBUFFER,  Up: Structures

2.28 SAMPLE
===========

typedef struct SAMPLE

          int bits;                   - 8 or 16
          int stereo;                 - sample type flag
          int freq;                   - sample frequency
          int priority;               - 0-255 */
          unsigned long len;          - length (in samples)
          unsigned long loop_start;   - loop start position
          unsigned long loop_end;     - loop finish position

     A sample structure, which holds sound data, used by the digital
     sample routines.

See also:
*Note load_sample::.
*Note Digital sample routines: Digital.
*Note exsample::.

File: allegro.info,  Node: MIDI,  Next: AUDIOSTREAM,  Prev: SAMPLE,  Up: Structures

2.29 MIDI
=========

typedef struct MIDI
     A structure holding MIDI data. Read chapter "Music routines
     (MIDI)" for a description on how to obtain/use this structure.

See also:
*Note load_midi::.
*Note Music routines (MIDI): Music.
*Note exdodgy::.
*Note exmidi::.

File: allegro.info,  Node: AUDIOSTREAM,  Next: PACKFILE,  Prev: MIDI,  Up: Structures

2.30 AUDIOSTREAM
================

typedef struct AUDIOSTREAM
     A structure holding an audiostream. Read chapter "Audio stream
     routines" for a description on how to obtain/use this structure.

See also:
*Note play_audio_stream::.
*Note Audio stream routines: Audio.
*Note exstream::.

File: allegro.info,  Node: PACKFILE,  Next: set_uformat,  Prev: AUDIOSTREAM,  Up: Structures

2.31 PACKFILE
=============

typedef struct PACKFILE

          int hndl;                   - DOS file handle
          int flags;                  - PACKFILE_FLAG_* constants
          char *filename;             - name of the file

     A packfile structure, similar to a stdio.h FILE structure. Read
     chapter "File and compression routines" for a description on how
     to obtain/use this structure.

See also:
*Note File and compression routines: File.
*Note pack_fopen::.
*Note pack_fopen_chunk::.

File: allegro.info,  Node: Unicode,  Next: Configuration,  Prev: Structures,  Up: Top

3 Unicode routines
******************

Allegro can manipulate and display text using any character values from
0 right up to 2^32-1 (although the current implementation of the
grabber can only create fonts using characters up to 2^16-1). You can
choose between a number of different text encoding formats, which
controls how strings are stored and how Allegro interprets strings that
you pass to it. This setting affects all aspects of the system:
whenever you see a function that returns a char * type, or that takes a
char * as an argument, that text will be in whatever format you have
told Allegro to use.

By default, Allegro uses UTF-8 encoded text (U_UTF8). This is a
variable-width format, where characters can occupy anywhere from one to
six bytes. The nice thing about it is that characters ranging from
0-127 are encoded directly as themselves, so UTF-8 is upwardly
compatible with 7-bit ASCII ("Hello, World!" means the same thing
regardless of whether you interpret it as ASCII or UTF-8 data). Any
character values above 128, such as accented vowels, the UK currency
symbol, and Arabic or Chinese characters, will be encoded as a sequence
of two or more bytes, each in the range 128-255. This means you will
never get what looks like a 7-bit ASCII character as part of the
encoding of a different character value, which makes it very easy to
manipulate UTF-8 strings.

There are a few editing programs that understand UTF-8 format text
files.  Alternatively, you can write your strings in plain ASCII or
16-bit Unicode formats, and then use the Allegro textconv program to
convert them into UTF-8.

If you prefer to use some other text format, you can set Allegro to work
with normal 8-bit ASCII (U_ASCII), or 16-bit Unicode (U_UNICODE)
instead, or you can provide some handler functions to make it support
whatever other text encoding you like (for example it would be easy to
add support for 32 bit UCS-4 characters, or the Chinese GB-code format).

There is some limited support for alternative 8-bit codepages, via the
U_ASCII_CP mode. This is very slow, so you shouldn't use it for serious
work, but it can be handy as an easy way to convert text between
different codepages. By default the U_ASCII_CP mode is set up to reduce
text to a clean 7-bit ASCII format, trying to replace any accented
vowels with their simpler equivalents (this is used by the
allegro_message() function when it needs to print an error report onto
a text mode DOS screen). If you want to work with other codepages, you
can do this by passing a character mapping table to the set_ucodepage()
function.

Note that you can use the Unicode routines before you call
install_allegro() or allegro_init(). If you want to work in a text mode
other than UTF-8, it is best to set it with set_uformat() just before
you call these.

* Menu:

* set_uformat::
* get_uformat::
* register_uformat::
* set_ucodepage::
* need_uconvert::
* uconvert_size::
* do_uconvert::
* uconvert::
* uconvert_ascii::
* uconvert_toascii::
* empty_string::
* ugetc::
* ugetx::
* usetc::
* uwidth::
* ucwidth::
* uisok::
* uoffset::
* ugetat::
* usetat::
* uinsert::
* uremove::
* ustrsize::
* ustrsizez::
* uwidth_max::
* utolower::
* utoupper::
* uisspace::
* uisdigit::
* ustrdup::
* _ustrdup::
* ustrcpy::
* ustrzcpy::
* ustrcat::
* ustrzcat::
* ustrlen::
* ustrcmp::
* ustrncpy::
* ustrzncpy::
* ustrncat::
* ustrzncat::
* ustrncmp::
* ustricmp::
* ustrnicmp::
* ustrlwr::
* ustrupr::
* ustrchr::
* ustrrchr::
* ustrstr::
* ustrpbrk::
* ustrtok::
* ustrtok_r::
* uatof::
* ustrtol::
* ustrtod::
* ustrerror::
* usprintf::
* uszprintf::
* uvsprintf::
* uvszprintf::


File: allegro.info,  Node: set_uformat,  Next: get_uformat,  Prev: PACKFILE,  Up: Unicode

3.1 set_uformat
===============

void set_uformat(int type);
     Sets the current text encoding format. This will affect all parts
     of Allegro, wherever you see a function that returns a char *, or
     takes a char * as a parameter. `type' should be one of these
     values:

          U_ASCII     - fixed size, 8-bit ASCII characters
          U_ASCII_CP  - alternative 8-bit codepage (see set_ucodepage())
          U_UNICODE   - fixed size, 16-bit Unicode characters
          U_UTF8      - variable size, UTF-8 format Unicode characters

     Although you can change the text format on the fly, this is not a
     good idea. Many strings, for example the names of your hardware
     drivers and any language translations, are loaded when you call
     allegro_init(), so if you change the encoding format after this,
     they will be in the wrong format, and things will not work
     properly. Generally you should only call set_uformat() once,
     before allegro_init(), and then leave it on the same setting for
     the duration of your program.

See also:
*Note get_uformat::.
*Note register_uformat::.
*Note set_ucodepage::.
*Note set_uformat::.
*Note uconvert::.
*Note ustrsize::.
*Note ugetc::.
*Note ugetx::.
*Note usetc::.
*Note uwidth::.
*Note ucwidth::.
*Note uisok::.
*Note uoffset::.
*Note ugetat::.
*Note usetat::.
*Note uinsert::.
*Note uremove::.
*Note allegro_init::.
*Note exunicod::.

File: allegro.info,  Node: get_uformat,  Next: register_uformat,  Prev: set_uformat,  Up: Unicode

3.2 get_uformat
===============

int get_uformat(void);
     Finds out what text encoding format is currently selected. This
     function is probably useful only if you are writing an Allegro
     addon dealing with text strings and you use a different codepath
     for each possible format.  Example:

          switch(get_uformat()) {
             case U_ASCII:
                do_something();
                break;
             case U_UTF8:
                do_something_else();
                break;
             ...
          }

     Returns the currently selected text encoding format. See the
     documentation of set_uformat for a list of encoding formats.

See also:
*Note set_uformat::.

File: allegro.info,  Node: register_uformat,  Next: set_ucodepage,  Prev: get_uformat,  Up: Unicode

3.3 register_uformat
====================

void register_uformat(int type, int (*u_getc)(const char *s), int (*u_getx)(char **s), int (*u_setc)(char *s, int c), int (*u_width)(const char *s), int (*u_cwidth)(int c), int (*u_isok)(int c));
     Installs a set of custom handler functions for a new text encoding
     format. The `type' is the ID code for your new format, which
     should be a 4-character string as produced by the AL_ID() macro,
     and which can later be passed to functions like set_uformat() and
     uconvert(). The function parameters are handlers that implement
     the character access for your new type: see below for details of
     these.

See also:
*Note set_uformat::.
*Note uconvert::.
*Note ugetc::.
*Note ugetx::.
*Note usetc::.
*Note uwidth::.
*Note ucwidth::.
*Note uisok::.

File: allegro.info,  Node: set_ucodepage,  Next: need_uconvert,  Prev: register_uformat,  Up: Unicode

3.4 set_ucodepage
=================

void set_ucodepage(const unsigned short *table, const unsigned short *extras);
     When you select the U_ASCII_CP encoding mode, a set of tables are
     used to convert between 8-bit characters and their Unicode
     equivalents. You can use this function to specify a custom set of
     mapping tables, which allows you to support different 8-bit
     codepages. The `table' parameter points to an array of 256 shorts,
     which contain the Unicode value for each character in your
     codepage. The `extras' parameter, if not NULL, points to a list of
     mapping pairs, which will be used when reducing Unicode data to
     your codepage. Each pair consists of a Unicode value, followed by
     the way it should be represented in your codepage. The table is
     terminated by a zero Unicode value. This allows you to create a
     many->one mapping, where many different Unicode characters can be
     represented by a single codepage value (eg. for reducing accented
     vowels to 7-bit ASCII).

See also:
*Note set_uformat::.

File: allegro.info,  Node: need_uconvert,  Next: uconvert_size,  Prev: set_ucodepage,  Up: Unicode

3.5 need_uconvert
=================

int need_uconvert(const char *s, int type, int newtype);
     Given a pointer to a string (`s'), a description of the type of
     the string (`type'), and the type that you would like this string
     to be converted into (`newtype'), this function tells you whether
     any conversion is required. No conversion will be needed if `type'
     and `newtype' are the same, or if one type is ASCII, the other is
     UTF-8, and the string contains only character values less than
     128. As a convenience shortcut, you can pass the value U_CURRENT
     as either of the type parameters, to represent whatever text
     encoding format is currently selected. Example:

          if (need_uconvert(text, U_UTF8, U_CURRENT)) {
             /* conversion is required */
          }

     Returns non-zero if any conversion is required or zero otherwise.

See also:
*Note set_uformat::.
*Note get_uformat::.
*Note do_uconvert::.
*Note uconvert::.

File: allegro.info,  Node: uconvert_size,  Next: do_uconvert,  Prev: need_uconvert,  Up: Unicode

3.6 uconvert_size
=================

int uconvert_size(const char *s, int type, int newtype);
     Finds out how many bytes are required to store the specified
     string `s' after a conversion from `type' to `newtype', including
     the mandatory zero terminator of the string. You can use U_CURRENT
     for either `type' or `newtype' as a shortcut to represent whatever
     text encoding format is currently selected. Example:

          length = uconvert_size(old_string, U_CURRENT, U_UNICODE);
          new_string = malloc(length);
          ustrcpy(new_string, old_string);

     Returns the number of bytes required to store the string after
     conversion.

See also:
*Note need_uconvert::.
*Note do_uconvert::.

File: allegro.info,  Node: do_uconvert,  Next: uconvert,  Prev: uconvert_size,  Up: Unicode

3.7 do_uconvert
===============

void do_uconvert(const char *s, int type, char *buf, int newtype, int size);
     Converts the specified string `s' from `type' to `newtype',
     storing at most `size' bytes into the output `buf'. The type
     parameters can use the value U_CURRENT as a shortcut to represent
     the currently selected encoding format. Example:

          char temp_string[256];
          do_uconvert(input_string, U_CURRENT, temp_string, U_ASCII, 256);

     Note that, even for empty strings, your destination string must
     have at least enough bytes to store the terminating null character
     of the string, and your parameter size must reflect this.
     Otherwise, the debug version of Allegro will abort at an
     assertion, and the release version of Allegro will overrun the
     destination buffer.

See also:
*Note uconvert::.

File: allegro.info,  Node: uconvert,  Next: uconvert_ascii,  Prev: do_uconvert,  Up: Unicode

3.8 uconvert
============

char *uconvert(const char *s, int type, char *buf, int newtype, int size);
     Higher level function running on top of do_uconvert(). This
     function converts the specified string `s' from `type' to
     `newtype', storing at most `size' bytes into the output `buf'
     (including the terminating null character), but it checks before
     doing the conversion, and doesn't bother if the string formats are
     already the same (either both types are equal, or one is ASCII,
     the other is UTF-8, and the string contains only 7-bit ASCII
     characters).

     As a convenience, if `buf' is NULL it will convert the string into
     an internal static buffer and the `size' parameter will be
     ignored. You should be wary of using this feature, though, because
     that buffer will be overwritten the next time this routine is
     called, so don't expect the data to persist across any other
     library calls. The static buffer has a size shorter than 1K, so
     you won't be able to convert large chunks of text.  Example:

          char *p = uconvert(input_string, U_CURRENT, buffer, U_ASCII, 256);

     Returns a pointer to `buf' (or the static buffer if you used NULL)
     if a conversion was performed. Otherwise returns a copy of `s'. In
     any cases, you should use the return value rather than assuming
     that the string will always be moved to `buf'.

See also:
*Note set_uformat::.
*Note need_uconvert::.
*Note uconvert::.
*Note uconvert_ascii::.
*Note uconvert_toascii::.
*Note do_uconvert::.

File: allegro.info,  Node: uconvert_ascii,  Next: uconvert_toascii,  Prev: uconvert,  Up: Unicode

3.9 uconvert_ascii
==================

char *uconvert_ascii(const char *s, char buf[]);
     Helper macro for converting strings from ASCII into the current
     encoding format. Expands to uconvert(s, U_ASCII, buf, U_CURRENT,
     sizeof(buf)).

See also:
*Note uconvert::.
*Note exunicod::.

File: allegro.info,  Node: uconvert_toascii,  Next: empty_string,  Prev: uconvert_ascii,  Up: Unicode

3.10 uconvert_toascii
=====================

char *uconvert_toascii(const char *s, char buf[]);
     Helper macro for converting strings from the current encoding
     format into ASCII. Expands to uconvert(s, U_CURRENT, buf, U_ASCII,
     sizeof(buf)).

See also:
*Note uconvert::.

File: allegro.info,  Node: empty_string,  Next: ugetc,  Prev: uconvert_toascii,  Up: Unicode

3.11 empty_string
=================

extern char empty_string[];
     You can't just rely on "" to be a valid empty string in any
     encoding format. This global buffer contains a number of
     consecutive zeros, so it will be a valid empty string no matter
     whether the program is running in ASCII, Unicode, or UTF-8 mode.



File: allegro.info,  Node: ugetc,  Next: ugetx,  Prev: empty_string,  Up: Unicode

3.12 ugetc
==========

int ugetc(const char *s);
     Low level helper function for reading Unicode text data. Example:

          int first_unicode_letter = ugetc(text_string);

     Returns the character pointed to by `s' in the current encoding
     format.

See also:
*Note ugetx::.
*Note usetc::.
*Note uwidth::.
*Note ucwidth::.
*Note uisok::.

File: allegro.info,  Node: ugetx,  Next: usetc,  Prev: ugetc,  Up: Unicode

3.13 ugetx
==========

int ugetx(char **s);

int ugetxc(const char **s);
     Low level helper function for reading Unicode text data. ugetxc is
     provided for working with pointer-to-pointer-to-const char data.
     Example:

          char *p = string;
          int first_letter, second_letter, third_letter;
          first_letter = ugetx(&p);
          second_letter = ugetx(&p);
          third_letter = ugetx(&p);

     Returns the character pointed to by `s' in the current encoding
     format, and advances the pointer to the next character after the
     one just returned.

See also:
*Note ugetc::.
*Note usetc::.
*Note uwidth::.
*Note ucwidth::.
*Note uisok::.

File: allegro.info,  Node: usetc,  Next: uwidth,  Prev: ugetx,  Up: Unicode

3.14 usetc
==========

int usetc(char *s, int c);
     Low level helper function for writing Unicode text data. Writes the
     character `c' to the address pointed to by `s'.

     Returns the number of bytes written, which is equal to the width
     of the character in the current encoding format.

See also:
*Note ugetc::.
*Note ugetx::.
*Note uwidth::.
*Note ucwidth::.
*Note uisok::.

File: allegro.info,  Node: uwidth,  Next: ucwidth,  Prev: usetc,  Up: Unicode

3.15 uwidth
===========

int uwidth(const char *s);
     Low level helper function for testing Unicode text data.

     Returns the number of bytes occupied by the first character of the
     specified string, in the current encoding format.

See also:
*Note uwidth_max::.
*Note ugetc::.
*Note ugetx::.
*Note usetc::.
*Note ucwidth::.
*Note uisok::.

File: allegro.info,  Node: ucwidth,  Next: uisok,  Prev: uwidth,  Up: Unicode

3.16 ucwidth
============

int ucwidth(int c);
     Low level helper function for testing Unicode text data.

     Returns the number of bytes that would be occupied by the specified
     character value, when encoded in the current format.

See also:
*Note uwidth_max::.
*Note ugetc::.
*Note ugetx::.
*Note usetc::.
*Note uwidth::.
*Note uisok::.

File: allegro.info,  Node: uisok,  Next: uoffset,  Prev: ucwidth,  Up: Unicode

3.17 uisok
==========

int uisok(int c);
     Low level helper function for testing Unicode text data. Finds out
     if the character value `c' can be encoded correctly in the current
     format, which can be useful if you are converting from Unicode to
     ASCII or another encoding format where the range of valid
     characters is limited.

     Returns non-zero if the value can be correctly encoded, zero
     otherwise.

See also:
*Note ugetc::.
*Note ugetx::.
*Note usetc::.
*Note uwidth::.
*Note ucwidth::.

File: allegro.info,  Node: uoffset,  Next: ugetat,  Prev: uisok,  Up: Unicode

3.18 uoffset
============

int uoffset(const char *s, int index);
     Finds out the offset (in bytes from the start of the string) of the
     character at the specified `index' in the string `s'. 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
     character. Example:

          int from_third_letter = uoffset(text_string, 2);

     Returns the offset in bytes to the specified character.

See also:
*Note ugetat::.
*Note usetat::.
*Note uinsert::.
*Note uremove::.

File: allegro.info,  Node: ugetat,  Next: usetat,  Prev: uoffset,  Up: Unicode

3.19 ugetat
===========

int ugetat(const char *s, int index);
     Finds out the character value 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 the last
     character of the string. Example:

          int third_letter = ugetat(text_string, 2);

     Returns the character value at the specified index in the string.

See also:
*Note uoffset::.
*Note usetat::.
*Note uinsert::.
*Note uremove::.

File: allegro.info,  Node: usetat,  Next: uinsert,  Prev: ugetat,  Up: Unicode

3.20 usetat
===========

int usetat(char *s, int index, int c);
     Replaces the character at the specified index in the string with
     value `c', handling any adjustments for variable width data (ie.
     if `c' encodes to a different width than the previous value at
     that location). If `index' is negative, it counts backward from
     the end of the string. Example:

          usetat(text_string, 2, letter_a);

     Returns the number of bytes by which the trailing part of the
     string was moved. This is of interest only with text encoding
     formats where characters have a variable length, like UTF-8.

See also:
*Note uoffset::.
*Note ugetat::.
*Note uinsert::.
*Note uremove::.

File: allegro.info,  Node: uinsert,  Next: uremove,  Prev: usetat,  Up: Unicode

3.21 uinsert
============

int uinsert(char *s, int index, int c);
     Inserts the character `c' at the specified `index' in the string,
     sliding the rest of the data along to make room. If `index' is
     negative, it counts backward from the end of the string. Example:

          uinsert(text_string, 0, prefix_letter);

     Returns the number of bytes by which the trailing part of the
     string was moved.

See also:
*Note uoffset::.
*Note ugetat::.
*Note usetat::.
*Note uremove::.

File: allegro.info,  Node: uremove,  Next: ustrsize,  Prev: uinsert,  Up: Unicode

3.22 uremove
============

int uremove(char *s, int index);
     Removes the character at the specified `index' within the string,
     sliding the rest of the data back to fill the gap. If `index' is
     negative, it counts backward from the end of the string. Example:

          int length_in_bytes = ustrsizez(text_string);
          ...
          length_in_bytes -= uremove(text_string, -1);

     Returns the number of bytes by which the trailing part of the
     string was moved.

See also:
*Note uoffset::.
*Note ugetat::.
*Note usetat::.
*Note uinsert::.

File: allegro.info,  Node: ustrsize,  Next: ustrsizez,  Prev: uremove,  Up: Unicode

3.23 ustrsize
=============

int ustrsize(const char *s);
     Returns the size of the specified string in bytes, not including
     the trailing null character.

See also:
*Note ustrsizez::.
*Note empty_string::.
*Note exunicod::.

File: allegro.info,  Node: ustrsizez,  Next: uwidth_max,  Prev: ustrsize,  Up: Unicode

3.24 ustrsizez
==============

int ustrsizez(const char *s);
     Returns the size of the specified string in bytes, including the
     trailing null character.

See also:
*Note ustrsize::.
*Note empty_string::.
*Note exunicod::.

File: allegro.info,  Node: uwidth_max,  Next: utolower,  Prev: ustrsizez,  Up: Unicode

3.25 uwidth_max
===============

int uwidth_max(int type);
     Low level helper function for working with Unicode text data.
     Returns the largest number of bytes that one character can occupy
     in the given encoding format. Pass U_CURRENT to represent the
     current format. Example:

          char *temp_buffer = malloc(256 * uwidth_max(U_UTF8));

See also:
*Note uwidth::.
*Note ucwidth::.

File: allegro.info,  Node: utolower,  Next: utoupper,  Prev: uwidth_max,  Up: Unicode

3.26 utolower
=============

int utolower(int c);
     This function returns `c', converting it to lower case if it is
     upper case.

See also:
*Note utoupper::.
*Note ugetc::.
*Note ugetx::.
*Note usetc::.
*Note uwidth::.
*Note ucwidth::.
*Note uisok::.

File: allegro.info,  Node: utoupper,  Next: uisspace,  Prev: utolower,  Up: Unicode

3.27 utoupper
=============

int utoupper(int c);
     This function returns `c', converting it to upper case if it is
     lower case.

See also:
*Note utolower::.
*Note ugetc::.
*Note ugetx::.
*Note usetc::.
*Note uwidth::.
*Note ucwidth::.
*Note uisok::.

File: allegro.info,  Node: uisspace,  Next: uisdigit,  Prev: utoupper,  Up: Unicode

3.28 uisspace
=============

int uisspace(int c);
     Returns nonzero if `c' is whitespace, that is, carriage return,
     newline, form feed, tab, vertical tab, or space. Example:

          for (counter = 0; counter < ustrlen(text_string); counter++) {
             if (uisspace(ugetat(text_string, counter)))
                usetat(text_string, counter, '_');
          }

See also:
*Note uisdigit::.
*Note ugetc::.
*Note usetc::.
*Note uwidth::.
*Note ucwidth::.
*Note uisok::.

File: allegro.info,  Node: uisdigit,  Next: ustrdup,  Prev: uisspace,  Up: Unicode

3.29 uisdigit
=============

int uisdigit(int c);
     Returns nonzero if `c' is a digit.

          for (counter = 0; counter < ustrlen(text_string); counter++) {
             if (uisdigit(ugetat(text_string, counter)))
                usetat(text_string, counter, '*');
          }

See also:
*Note uisspace::.
*Note ugetc::.
*Note usetc::.
*Note uwidth::.
*Note ucwidth::.
*Note uisok::.

File: allegro.info,  Node: ustrdup,  Next: _ustrdup,  Prev: uisdigit,  Up: Unicode

3.30 ustrdup
============

char *ustrdup(const char *src)
     This functions copies the null-terminated string `src' into a newly
     allocated area of memory, effectively duplicating it. Example:

          void manipulate_string(const char *input_string)
          {
             char *temp_buffer = ustrdup(input_string);
             /* Now we can modify temp_buffer */
             ...

     Returns the newly allocated string. This memory must be freed by
     the caller. Returns NULL if it cannot allocate space for the
     duplicated string.

See also:
*Note _ustrdup::.
*Note uconvert::.
*Note ustrsize::.
*Note ustrsizez::.
*Note exconfig::.

File: allegro.info,  Node: _ustrdup,  Next: ustrcpy,  Prev: ustrdup,  Up: Unicode

3.31 _ustrdup
=============

char *_ustrdup(const char *src, void* (*malloc_func) (size_t))
     Does the same as ustrdup(), but allows the user to specify a
     custom memory allocator function.

See also:
*Note ustrdup::.
*Note uconvert::.
*Note ustrsize::.
*Note ustrsizez::.

File: allegro.info,  Node: ustrcpy,  Next: ustrzcpy,  Prev: _ustrdup,  Up: Unicode

3.32 ustrcpy
============

char *ustrcpy(char *dest, const char *src);
     This function copies `src' (including the terminating null
     character into `dest'. You should try to avoid this function
     because it is very easy to overflow the destination buffer. Use
     ustrzcpy instead.

     Returns the value of dest.

See also:
*Note uconvert::.
*Note ustrzcpy::.
*Note ustrncpy::.
*Note exunicod::.

File: allegro.info,  Node: ustrzcpy,  Next: ustrcat,  Prev: ustrcpy,  Up: Unicode

3.33 ustrzcpy
=============

char *ustrzcpy(char *dest, int size, const char *src);
     This function copies `src' (including the terminating NULL
     character into `dest', whose length in bytes is specified by
     `size' and which is guaranteed to be null-terminated even if `src'
     is bigger than `size'.

     Note that, even for empty strings, your destination string must
     have at least enough bytes to store the terminating null character
     of the string, and your parameter size must reflect this.
     Otherwise, the debug version of Allegro will abort at an
     assertion, and the release version of Allegro will overrun the
     destination buffer.

     Returns the value of `dest'.

See also:
*Note uconvert::.
*Note ustrcpy::.
*Note ustrzncpy::.
*Note exgui::.

File: allegro.info,  Node: ustrcat,  Next: ustrzcat,  Prev: ustrzcpy,  Up: Unicode

3.34 ustrcat
============

char *ustrcat(char *dest, const char *src);
     This function concatenates `src' to the end of `dest`'. You should
     try to avoid this function because it is very easy to overflow the
     destination buffer, use ustrzcat instead.

     Returns the value of `dest'.

See also:
*Note uconvert::.
*Note ustrzcat::.
*Note ustrncat::.
*Note exunicod::.

File: allegro.info,  Node: ustrzcat,  Next: ustrlen,  Prev: ustrcat,  Up: Unicode

3.35 ustrzcat
=============

char *ustrzcat(char *dest, int size, const char *src);
     This function concatenates `src' to the end of `dest', whose
     length in bytes is specified by `size' and which is guaranteed to
     be null-terminated even when `src' is bigger than `size'.

     Note that, even for empty strings, your destination string must
     have at least enough bytes to store the terminating null character
     of the string, and your parameter size must reflect this.
     Otherwise, the debug version of Allegro will abort at an
     assertion, and the release version of Allegro will overrun the
     destination buffer.

     Returns the value of `dest'.

See also:
*Note uconvert::.
*Note ustrcat::.
*Note ustrzncat::.
*Note exgui::.

File: allegro.info,  Node: ustrlen,  Next: ustrcmp,  Prev: ustrzcat,  Up: Unicode

3.36 ustrlen
============

int ustrlen(const char *s);
     This function returns the number of characters in `s'. Note that
     this doesn't have to equal the string's size in bytes.

See also:
*Note uconvert::.
*Note ustrsize::.
*Note ustrsizez::.

File: allegro.info,  Node: ustrcmp,  Next: ustrncpy,  Prev: ustrlen,  Up: Unicode

3.37 ustrcmp
============

int ustrcmp(const char *s1, const char *s2);
     This function compares `s1' and `s2'.

     Returns zero if the strings are equal, a positive number if `s1'
     comes after `s2' in the ASCII collating sequence, else a negative
     number.

See also:
*Note uconvert::.
*Note ustrsize::.
*Note ustrsizez::.
*Note ustrncmp::.
*Note ustricmp::.
*Note ustrnicmp::.

File: allegro.info,  Node: ustrncpy,  Next: ustrzncpy,  Prev: ustrcmp,  Up: Unicode

3.38 ustrncpy
=============

char *ustrncpy(char *dest, const char *src, int n);
     This function is like ustrcpy() except that no more than `n'
     characters from `src' are copied into `dest'. If `src' is shorter
     than `n' characters, null characters are appended to `dest' as
     padding until `n' characters have been written.

     Note that if `src' is longer than `n' characters, `dest' will not
     be null-terminated.

     The return value is the value of `dest'.

See also:
*Note uconvert::.
*Note ustrcpy::.
*Note ustrzncpy::.

File: allegro.info,  Node: ustrzncpy,  Next: ustrncat,  Prev: ustrncpy,  Up: Unicode

3.39 ustrzncpy
==============

char *ustrzncpy(char *dest, int size, const char *src, int n);
     This function is like ustrzcpy() except that no more than `n'
     characters from `src' are copied into `dest'. If `src' is shorter
     than `n' characters, null characters are appended to `dest' as
     padding until `n' characters have been written. In any case,
     `dest' is guaranteed to be null-terminated.

     Note that, even for empty strings, your destination string must
     have at least enough bytes to store the terminating null character
     of the string, and your parameter `size' must reflect this.
     Otherwise, the debug version of Allegro will abort at an
     assertion, and the release version of Allegro will overrun the
     destination buffer.

     The return value is the value of `dest'.

See also:
*Note uconvert::.
*Note ustrzcpy::.
*Note ustrncpy::.

File: allegro.info,  Node: ustrncat,  Next: ustrzncat,  Prev: ustrzncpy,  Up: Unicode

3.40 ustrncat
=============

char *ustrncat(char *dest, const char *src, int n);
     This function is like ustrcat() except that no more than `n'
     characters from `src' are appended to the end of `dest'. If the
     terminating null character in `src' is reached before `n'
     characters have been written, the null character is copied, but no
     other characters are written. If `n' characters are written before
     a terminating null is encountered, the function appends its own
     null character to `dest', so that `n+1' characters are written.
     You should try to avoid this function because it is very easy to
     overflow the destination buffer. Use ustrzncat instead.

     The return value is the value of `dest'.

See also:
*Note uconvert::.
*Note ustrcat::.
*Note ustrzncat::.

File: allegro.info,  Node: ustrzncat,  Next: ustrncmp,  Prev: ustrncat,  Up: Unicode

3.41 ustrzncat
==============

char *ustrzncat(char *dest, int size, const char *src, int n);
     This function is like ustrzcat() except that no more than `n'
     characters from `src' are appended to the end of `dest'. If the
     terminating null character in `src' is reached before `n'
     characters have been written, the null character is copied, but no
     other characters are written. Note that `dest' is guaranteed to be
     null-terminated.

     The return value is the value of `dest'.

See also:
*Note uconvert::.
*Note ustrzcat::.
*Note ustrncat::.

File: allegro.info,  Node: ustrncmp,  Next: ustricmp,  Prev: ustrzncat,  Up: Unicode

3.42 ustrncmp
=============

int ustrncmp(const char *s1, const char *s2, int n);
     This function compares up to `n' characters of `s1' and `s2'.
     Example:

          if (ustrncmp(prefix, long_string, ustrlen(prefix)) == 0) {
             /* long_string starts with prefix */
          }

     Returns zero if the substrings are equal, a positive number if
     `s1' comes after `s2' in the ASCII collating sequence, else a
     negative number.

See also:
*Note uconvert::.
*Note ustrsize::.
*Note ustrsizez::.
*Note ustrcmp::.
*Note ustricmp::.
*Note ustrnicmp::.

File: allegro.info,  Node: ustricmp,  Next: ustrnicmp,  Prev: ustrncmp,  Up: Unicode

3.43 ustricmp
=============

int ustricmp(const char *s1, const char *s2);
     This function compares `s1' and `s2', ignoring case. Example:

          if (ustricmp(string, user_input) == 0) {
             /* string and user_input are equal (ignoring case) */
          }

     Returns zero if the strings are equal, a positive number if `s1'
     comes after `s2' in the ASCII collating sequence, else a negative
     number.

See also:
*Note uconvert::.
*Note ustrsize::.
*Note ustrsizez::.
*Note ustrnicmp::.
*Note ustrcmp::.
*Note ustrncmp::.
*Note exconfig::.

File: allegro.info,  Node: ustrnicmp,  Next: ustrlwr,  Prev: ustricmp,  Up: Unicode

3.44 ustrnicmp
==============

int ustrnicmp(const char *s1, const char *s2, int n);
     This function compares up to `n' characters of `s1' and `s2',
     ignoring case. Example:

          if (ustrnicmp(prefix, long_string, ustrlen(prefix)) == 0) {
             /* long_string starts with prefix (ignoring case) */
          }

     Returns zero if the strings are equal, a positive number if `s1'
     comes after `s2' in the ASCII collating sequence, else a negative
     number.

See also:
*Note uconvert::.
*Note ustrsize::.
*Note ustrsizez::.
*Note ustricmp::.
*Note ustrcmp::.
*Note ustrncmp::.

File: allegro.info,  Node: ustrlwr,  Next: ustrupr,  Prev: ustrnicmp,  Up: Unicode

3.45 ustrlwr
============

char *ustrlwr(char *s);
     This function replaces all upper case letters in `s' with lower
     case letters. Example:

          char buffer[] = "UPPER CASE STRING";
          allegro_message(ustrlwr(buffer));

     The return value is the value of `s'.

See also:
*Note uconvert::.
*Note utolower::.
*Note ustrupr::.

File: allegro.info,  Node: ustrupr,  Next: ustrchr,  Prev: ustrlwr,  Up: Unicode

3.46 ustrupr
============

char *ustrupr(char *s);
     This function replaces all lower case letters in `s' with upper
     case letters. Example:

          char buffer[] = "lower case string";
          allegro_message(ustrupr(buffer));

     The return value is the value of `s'.

See also:
*Note uconvert::.
*Note utolower::.
*Note ustrlwr::.

File: allegro.info,  Node: ustrchr,  Next: ustrrchr,  Prev: ustrupr,  Up: Unicode

3.47 ustrchr
============

char *ustrchr(const char *s, int c);
     Finds the first occurrence of the character `c' in the string `s'.
     Example:

          char *p = ustrchr("one,two,three,four", ',');

     Returns a pointer to the first occurrence of `c' in `s', or NULL
     if no match was found. Note that if `c' is NULL, this will return
     a pointer to the end of the string.

See also:
*Note uconvert::.
*Note ustrrchr::.
*Note ustrstr::.
*Note ustrpbrk::.
*Note ustrtok::.

File: allegro.info,  Node: ustrrchr,  Next: ustrstr,  Prev: ustrchr,  Up: Unicode

3.48 ustrrchr
=============

char *ustrrchr(const char *s, int c);
     Finds the last occurrence of the character `c' in the string `s'.
     Example:

          char *p = ustrrchr("one,two,three,four", ',');

     Returns a pointer fo the last occurrence of `c' in `s', or NULL if
     no match was found.

See also:
*Note uconvert::.
*Note ustrchr::.
*Note ustrstr::.
*Note ustrpbrk::.
*Note ustrtok::.

File: allegro.info,  Node: ustrstr,  Next: ustrpbrk,  Prev: ustrrchr,  Up: Unicode

3.49 ustrstr
============

char *ustrstr(const char *s1, const char *s2);
     This function finds the first occurence of string `s2' in string
     `s1'.  Example:

          char *p = ustrstr("hello world", "world");

     Returns a pointer within `s1', or NULL if `s2' wasn't found.

See also:
*Note uconvert::.
*Note ustrchr::.
*Note ustrrchr::.
*Note ustrpbrk::.
*Note ustrtok::.

File: allegro.info,  Node: ustrpbrk,  Next: ustrtok,  Prev: ustrstr,  Up: Unicode

3.50 ustrpbrk
=============

char *ustrpbrk(const char *s, const char *set);
     This function finds the first character in `s' that matches any
     character in `set'. Example:

          char *p = ustrpbrk("one,two-three.four", "-. ");

     Returns a pointer to the first match, or NULL if none are found.

See also:
*Note uconvert::.
*Note ustrchr::.
*Note ustrrchr::.
*Note ustrstr::.
*Note ustrtok::.

File: allegro.info,  Node: ustrtok,  Next: ustrtok_r,  Prev: ustrpbrk,  Up: Unicode

3.51 ustrtok
============

char *ustrtok(char *s, const char *set);
     This function retrieves tokens from `s' which are delimited by
     characters from `set'. To initiate the search, pass the string to
     be searched as `s'.  For the remaining tokens, pass NULL instead.
     Warning: Since ustrtok alters the string it is parsing, you should
     always copy the string to a temporary buffer before parsing it.
     Also, this function is not reentrant (ie. you cannot parse two
     strings at the same time). Example:

          char *word;
          char string[]="some-words with dashes";
          char *temp = ustrdup(string);
          word = ustrtok(temp, " -");
          while (word) {
             allegro_message("Found `%s'\n", word);
             word = ustrtok(NULL, " -");
          }
          free(temp);

     Returns a pointer to the token, or NULL if no more are found.

See also:
*Note uconvert::.
*Note ustrchr::.
*Note ustrrchr::.
*Note ustrstr::.
*Note ustrpbrk::.
*Note ustrtok_r::.
*Note allegro_message::.
*Note ustrncpy::.
*Note exgui::.

File: allegro.info,  Node: ustrtok_r,  Next: uatof,  Prev: ustrtok,  Up: Unicode

3.52 ustrtok_r
==============

char *ustrtok_r(char *s, const char *set, char **last);
     Reentrant version of ustrtok. The `last' parameter is used to keep
     track of where the parsing is up to and must be a pointer to a
     char * variable allocated by the user that remains the same while
     parsing the same string. Example:

          char *word, *last;
          char string[]="some-words with dashes";
          char *temp = ustrdup(string);
          word = ustrtok_r(string, " -", &last);
          while (word) {
             allegro_message("Found `%s'\n", word);
             word = ustrtok_r(NULL, " -", &last);
          }
          free(temp);

     Returns a pointer to the token, or NULL if no more are found. You
     can free the memory pointed to by `last' once NULL is returned.

See also:
*Note ustrtok::.

File: allegro.info,  Node: uatof,  Next: ustrtol,  Prev: ustrtok_r,  Up: Unicode

3.53 uatof
==========

double uatof(const char *s);
     Convert as much of the string as possible to an equivalent double
     precision real number. This function is almost like `ustrtod(s,
     NULL)'.

     Returns the equivalent value, or zero if the string does not
     represent a number.

See also:
*Note uconvert::.
*Note ustrtol::.
*Note ustrtod::.

File: allegro.info,  Node: ustrtol,  Next: ustrtod,  Prev: uatof,  Up: Unicode

3.54 ustrtol
============

long ustrtol(const char *s, char **endp, int base);
     This function converts the initial part of `s' to a signed
     integer, setting `*endp' to point to the first unused character,
     if `endp' is not a NULL pointer. The `base' argument indicates
     what base the digits (or letters) should be treated as. If `base'
     is zero, the base is determined by looking for `0x', `0X', or `0'
     as the first part of the string, and sets the base used to 16, 16,
     or 8 if it finds one. The default base is 10 if none of those
     prefixes are found. Example:

          char *endp, *string = "456.203 askdfg";
          int number = ustrtol(string, &endp, 10);

     Returns the string converted as a value of type `long int'. If
     nothing was converted, returns zero with `*endp' pointing to the
     beginning of `s'.

See also:
*Note uconvert::.
*Note ustrtod::.
*Note uatof::.

File: allegro.info,  Node: ustrtod,  Next: ustrerror,  Prev: ustrtol,  Up: Unicode

3.55 ustrtod
============

double ustrtod(const char *s, char **endp);
     This function converts as many characters of `s' that look like a
     floating point number into one, and sets `*endp' to point to the
     first unused character, if `endp' is not a NULL pointer. Example:

          char *endp, *string = "456.203 askdfg";
          double number = ustrtod(string, &endp);

     Returns the string converted as a value of type `double'. If
     nothing was converted, returns zero with *endp pointing to the
     beginning of s.

See also:
*Note uconvert::.
*Note ustrtol::.
*Note uatof::.

File: allegro.info,  Node: ustrerror,  Next: usprintf,  Prev: ustrtod,  Up: Unicode

3.56 ustrerror
==============

const char *ustrerror(int err);
     This function returns a string that describes the error code
     `err', which normally comes from the variable `errno'. Example:

          PACKFILE *input_file = pack_fopen("badname", "r");
          if (input_file == NULL)
             allegro_message("%s\nSorry!\n", ustrerror(errno));

     Returns a pointer to a static string that should not be modified or
     freed. If you make subsequent calls to ustrerror(), the string
     will be overwritten.

See also:
*Note uconvert::.
*Note allegro_error::.

File: allegro.info,  Node: usprintf,  Next: uszprintf,  Prev: ustrerror,  Up: Unicode

3.57 usprintf
=============

int usprintf(char *buf, const char *format, ...);
     This function writes formatted data into the output buffer. A NULL
     character is written to mark the end of the string. You should try
     to avoid this function because it is very easy to overflow the
     destination buffer.  Use uszprintf instead.

     Returns the number of characters written, not including the
     terminating null character.

See also:
*Note uconvert::.
*Note uszprintf::.
*Note uvsprintf::.
*Note exkeys::.

File: allegro.info,  Node: uszprintf,  Next: uvsprintf,  Prev: usprintf,  Up: Unicode

3.58 uszprintf
==============

int uszprintf(char *buf, int size, const char *format, ...);
     This function writes formatted data into the output buffer, whose
     length in bytes is specified by `size' and which is guaranteed to
     be NULL terminated. Example:

          char buffer[10];
          int player_score;
          ...
          uszprintf(buffer, sizeof(buffer), "Your score is: %d", player_score);

     Returns the number of characters that would have been written
     without eventual truncation (like with usprintf), not including
     the terminating null character.

See also:
*Note uconvert::.
*Note usprintf::.
*Note uvszprintf::.
*Note exgui::.

File: allegro.info,  Node: uvsprintf,  Next: uvszprintf,  Prev: uszprintf,  Up: Unicode

3.59 uvsprintf
==============

int uvsprintf(char *buf, const char *format, va_list args);
     This is like usprintf(), but you pass the variable argument list
     directly, instead of the arguments themselves. You can use this
     function to implement printf like functions, also called variadic
     functions. You should try to avoid this function because it is
     very easy to overflow the destination buffer. Use uvszprintf
     instead.

     Returns the number of characters written, not including the
     terminating null character.

See also:
*Note uconvert::.
*Note usprintf::.
*Note uvszprintf::.

File: allegro.info,  Node: uvszprintf,  Next: set_config_file,  Prev: uvsprintf,  Up: Unicode

3.60 uvszprintf
===============

int uvszprintf(char *buf, int size, const char *format, va_list args);
     This is like uszprintf(), but you pass the variable argument list
     directly, instead of the arguments themselves. Example:

          #include <stdarg.h>

          void log_message(const char *format, ...)
          {
             char buffer[100];
             va_list parameters;

             va_start(parameters, format);
             uvszprintf(buffer, sizeof(buffer), format, parameters);
             va_end(parameters);

             append_buffer_to_logfile(log_name, buffer);
             send_buffer_to_other_networked_players(multicast_ip, buffer);
             and_also_print_it_on_the_screen(cool_font, buffer);
          }

          void some_other_function(void)
          {
             log_message("Hello %s, are you %d years old?\n", "Dave", 25);
          }

     Returns the number of characters that would have been written
     without eventual truncation (like with uvsprintf), not including
     the terminating null character.

See also:
*Note uconvert::.
*Note uszprintf::.
*Note uvsprintf::.

File: allegro.info,  Node: Configuration,  Next: Mouse,  Prev: Unicode,  Up: Top

4 Configuration routines
************************

Various parts of Allegro, such as the sound routines and the
load_joystick_data() function, require some configuration information.
This data is stored in text files as a collection of "variable=value"
lines, along with comments that begin with a '#' character and continue
to the end of the line. The configuration file may optionally be
divided into sections, which begin with a "[sectionname]" line. Each
section has a unique namespace, to prevent variable name conflicts, but
any variables that aren't in a section are considered to belong to all
the sections simultaneously.

By default the configuration data is read from a file called
allegro.cfg, which can be located either in the same directory as the
program executable, or the directory pointed to by the ALLEGRO
environment variable. Under Unix, it also checks for ~/allegro.cfg,
~/.allegrorc, /etc/allegro.cfg, and /etc/allegrorc, in that order;
under BeOS only the last two are also checked.  MacOS X also checks in
the Contents/Resources directory of the application bundle, if any,
before doing the checks above.  If you don't like this approach, you
can specify any filename you like, or use a block of binary
configuration data provided by your program (which could for example be
loaded from a datafile).

You can store whatever custom information you like in the config file,
along with the standard variables that are used by Allegro (see below).

* Menu:

* set_config_file::
* set_config_data::
* override_config_file::
* override_config_data::
* push_config_state::
* pop_config_state::
* flush_config_file::
* reload_config_texts::
* hook_config_section::
* config_is_hooked::
* get_config_string::
* get_config_int::
* get_config_hex::
* get_config_float::
* get_config_id::
* get_config_argv::
* get_config_text::
* set_config_string::
* set_config_int::
* set_config_hex::
* set_config_float::
* set_config_id::
* Standard config variables::


File: allegro.info,  Node: set_config_file,  Next: set_config_data,  Prev: uvszprintf,  Up: Configuration

4.1 set_config_file
===================

void set_config_file(const char *filename);
     Sets the configuration file to be used by all subsequent config
     functions. If you don't call this function, Allegro will use the
     default allegro.cfg file, looking first in the same directory as
     your program and then in the directory pointed to by the ALLEGRO
     environment variable.

     All pointers returned by previous calls to get_config_string() and
     other related functions are invalidated when you call this
     function!

See also:
*Note set_config_data::.
*Note override_config_file::.
*Note push_config_state::.
*Note Standard config variables::.
*Note set_config_string::.
*Note get_config_string::.
*Note exconfig::.

File: allegro.info,  Node: set_config_data,  Next: override_config_file,  Prev: set_config_file,  Up: Configuration

4.2 set_config_data
===================

void set_config_data(const char *data, int length);
     Specifies a block of data to be used by all subsequent config
     functions, which you have already loaded from disk (eg. as part of
     some more complicated format of your own, or in a grabber
     datafile). This routine makes a copy of the information, so you
     can safely free the data after calling it.

See also:
*Note set_config_file::.
*Note override_config_data::.
*Note push_config_state::.
*Note Standard config variables::.
*Note set_config_string::.
*Note get_config_string::.

File: allegro.info,  Node: override_config_file,  Next: override_config_data,  Prev: set_config_data,  Up: Configuration

4.3 override_config_file
========================

void override_config_file(const char *filename);
     Specifies a file containing config overrides. These settings will
     be used in addition to the parameters in the main config file, and
     where a variable is present in both files this version will take
     priority. This can be used by application programmers to override
     some of the config settings from their code, while still leaving
     the main config file free for the end user to customise. For
     example, you could specify a particular sample frequency and IBK
     instrument file, but the user could still use an allegro.cfg file
     to specify the port settings and irq numbers.

See also:
*Note override_config_data::.
*Note set_config_file::.

File: allegro.info,  Node: override_config_data,  Next: push_config_state,  Prev: override_config_file,  Up: Configuration

4.4 override_config_data
========================

void override_config_data(const char *data, int length);
     Version of override_config_file() which uses a block of data that
     has already been read into memory.

See also:
*Note override_config_file::.
*Note set_config_data::.

File: allegro.info,  Node: push_config_state,  Next: pop_config_state,  Prev: override_config_data,  Up: Configuration

4.5 push_config_state
=====================

void push_config_state();
     Pushes the current configuration state (filename, variable values,
     etc).  onto an internal stack, allowing you to select some other
     config source and later restore the current settings by calling
     pop_config_state().  This function is mostly intended for internal
     use by other library functions, for example when you specify a
     config filename to the save_joystick_data() function, it pushes
     the config state before switching to the file you specified.

See also:
*Note pop_config_state::.
*Note set_config_file::.
*Note exconfig::.

File: allegro.info,  Node: pop_config_state,  Next: flush_config_file,  Prev: push_config_state,  Up: Configuration

4.6 pop_config_state
====================

void pop_config_state();
     Pops a configuration state previously stored by
     push_config_state(), replacing the current config source with it.

See also:
*Note push_config_state::.
*Note exconfig::.

File: allegro.info,  Node: flush_config_file,  Next: reload_config_texts,  Prev: pop_config_state,  Up: Configuration

4.7 flush_config_file
=====================

void flush_config_file();
     Writes the current config file to disk if the contents have changed
     since it was loaded or since the latest call to the function.

See also:
*Note set_config_file::.
*Note override_config_file::.
*Note push_config_state::.

File: allegro.info,  Node: reload_config_texts,  Next: hook_config_section,  Prev: flush_config_file,  Up: Configuration

4.8 reload_config_texts
=======================

void reload_config_texts(const char *new_language);
     Reloads the translated strings returned by get_config_text. This is
     useful to switch to another language in your program at runtime.
     If you want to modify the [system] language configuration variable
     yourself, or you have switched configuration files, you will want
     to pass NULL to just reload whatever language is currently
     selected. Or you can pass a string containing the two letter code
     of the language you desire to switch to, and the function will
     modify the language variable. After you call this function, the
     previously returned pointers of get_config_text will be invalid.

See also:
*Note get_config_text::.
*Note get_config_string::.
*Note Standard config variables::.

File: allegro.info,  Node: hook_config_section,  Next: config_is_hooked,  Prev: reload_config_texts,  Up: Configuration

4.9 hook_config_section
=======================

void hook_config_section(const char *section, int (*intgetter)(const char *name, int def), const char *(*stringgetter)(const char *name, const char *def), void (*stringsetter)(const char *name, const char *value));
     Takes control of the specified config file section, so that your
     hook functions will be used to manipulate it instead of the normal
     disk file access. If both the getter and setter functions are
     NULL, a currently present hook will be unhooked. Hooked functions
     have the highest priority. If a section is hooked, the hook will
     always be called, so you can also hook a '#' section: even
     override_config_file() cannot override a hooked section.

See also:
*Note config_is_hooked::.

File: allegro.info,  Node: config_is_hooked,  Next: get_config_string,  Prev: hook_config_section,  Up: Configuration

4.10 config_is_hooked
=====================

int config_is_hooked(const char *section);
     Returns TRUE if the specified config section has been hooked.

See also:
*Note hook_config_section::.

File: allegro.info,  Node: get_config_string,  Next: get_config_int,  Prev: config_is_hooked,  Up: Configuration

4.11 get_config_string
======================

const char *get_config_string(const char *section, const char *name, const char *def);
     Retrieves a string variable from the current config file. If the
     named variable cannot be found, or its entry in the config file is
     empty, the value of def is returned. The section name may be set
     to NULL to read variables from the root of the file, or used to
     control which set of parameters (eg. sound or joystick) you are
     interested in reading.

See also:
*Note set_config_file::.
*Note set_config_string::.
*Note get_config_argv::.
*Note get_config_float::.
*Note get_config_hex::.
*Note get_config_int::.
*Note get_config_id::.

File: allegro.info,  Node: get_config_int,  Next: get_config_hex,  Prev: get_config_string,  Up: Configuration

4.12 get_config_int
===================

int get_config_int(const char *section, const char *name, int def);
     Reads an integer variable from the current config file. See the
     comments about get_config_string().

See also:
*Note set_config_file::.
*Note set_config_int::.
*Note get_config_string::.
*Note get_config_argv::.
*Note get_config_float::.
*Note get_config_hex::.
*Note get_config_id::.
*Note exconfig::.

File: allegro.info,  Node: get_config_hex,  Next: get_config_float,  Prev: get_config_int,  Up: Configuration

4.13 get_config_hex
===================

int get_config_hex(const char *section, const char *name, int def);
     Reads an integer variable from the current config file, in
     hexadecimal format. See the comments about get_config_string().

See also:
*Note set_config_file::.
*Note set_config_hex::.
*Note get_config_string::.
*Note get_config_argv::.
*Note get_config_float::.
*Note get_config_int::.
*Note get_config_id::.

File: allegro.info,  Node: get_config_float,  Next: get_config_id,  Prev: get_config_hex,  Up: Configuration

4.14 get_config_float
=====================

float get_config_float(const char *section, const char *name, float def);
     Reads a floating point variable from the current config file. See
     the comments about get_config_string().

See also:
*Note set_config_file::.
*Note set_config_float::.
*Note get_config_string::.
*Note get_config_argv::.
*Note get_config_hex::.
*Note get_config_int::.
*Note get_config_id::.

File: allegro.info,  Node: get_config_id,  Next: get_config_argv,  Prev: get_config_float,  Up: Configuration

4.15 get_config_id
==================

int get_config_id(const char *section, const char *name, int def);
     Reads a 4-letter driver ID variable from the current config file.
     See the comments about get_config_string().

See also:
*Note set_config_file::.
*Note set_config_id::.
*Note get_config_string::.
*Note get_config_argv::.
*Note get_config_float::.
*Note get_config_hex::.
*Note get_config_int::.

File: allegro.info,  Node: get_config_argv,  Next: get_config_text,  Prev: get_config_id,  Up: Configuration

4.16 get_config_argv
====================

char **get_config_argv(const char *section, const char *name, int *argc);
     Reads a token list (words separated by spaces) from the current
     config file, returning a an argv style argument list, and setting
     argc to the number of tokens (unlike argc/argv, this list is zero
     based). Returns NULL and sets argc to zero if the variable is not
     present. The token list is stored in a temporary buffer that will
     be clobbered by the next call to get_config_argv(), so the data
     should not be expected to persist.

See also:
*Note set_config_file::.
*Note get_config_string::.
*Note get_config_float::.
*Note get_config_hex::.
*Note get_config_int::.
*Note get_config_id::.
*Note exconfig::.

File: allegro.info,  Node: get_config_text,  Next: set_config_string,  Prev: get_config_argv,  Up: Configuration

4.17 get_config_text
====================

const char *get_config_text(const char *msg);
     This function is primarily intended for use by internal library
     code, but it may perhaps be helpful to application programmers as
     well. It uses the language.dat or XXtext.cfg files (where XX is a
     language code) to look up a translated version of the parameter in
     the currently selected language, returning a suitable translation
     if one can be found or a copy of the parameter if nothing else is
     available. This is basically the same thing as calling
     get_config_string() with [language] as the section, msg as the
     variable name, and msg as the default value, but it contains some
     special code to handle Unicode format conversions. The msg
     parameter is always given in ASCII format, but the returned string
     will be converted into the current text encoding, with memory
     being allocated as required, so you can assume that this pointer
     will persist without having to manually allocate storage space for
     each string.

See also:
*Note get_config_string::.
*Note reload_config_texts::.
*Note Standard config variables::.

File: allegro.info,  Node: set_config_string,  Next: set_config_int,  Prev: get_config_text,  Up: Configuration

4.18 set_config_string
======================

void set_config_string(const char *section, const char *name, const char *val);
     Writes a string variable to the current config file, replacing any
     existing value it may have, or removes the variable if val is
     NULL. The section name may be set to NULL to write the variable to
     the root of the file, or used to control which section the
     variable is inserted into. The altered file will be cached in
     memory, and not actually written to disk until you call
     allegro_exit(). Note that you can only write to files in this way,
     so the function will have no effect if the current config source
     was specified with set_config_data() rather than set_config_file().

     As a special case, variable or section names that begin with a '#'
     character are treated specially and will not be read from or
     written to the disk. Addon packages can use this to store version
     info or other status information into the config module, from
     where it can be read with the get_config_string() function.

See also:
*Note set_config_file::.
*Note get_config_string::.
*Note set_config_float::.
*Note set_config_hex::.
*Note set_config_int::.
*Note set_config_id::.

File: allegro.info,  Node: set_config_int,  Next: set_config_hex,  Prev: set_config_string,  Up: Configuration

4.19 set_config_int
===================

void set_config_int(const char *section, const char *name, int val);
     Writes an integer variable to the current config file. See the
     comments about set_config_string().

See also:
*Note set_config_file::.
*Note get_config_int::.
*Note set_config_string::.
*Note set_config_float::.
*Note set_config_hex::.
*Note set_config_id::.

File: allegro.info,  Node: set_config_hex,  Next: set_config_float,  Prev: set_config_int,  Up: Configuration

4.20 set_config_hex
===================

void set_config_hex(const char *section, const char *name, int val);
     Writes an integer variable to the current config file, in
     hexadecimal format. See the comments about set_config_string().

See also:
*Note set_config_file::.
*Note get_config_hex::.
*Note set_config_string::.
*Note set_config_float::.
*Note set_config_int::.
*Note set_config_id::.

File: allegro.info,  Node: set_config_float,  Next: set_config_id,  Prev: set_config_hex,  Up: Configuration

4.21 set_config_float
=====================

void set_config_float(const char *section, const char *name, float val);
     Writes a floating point variable to the current config file. See
     the comments about set_config_string().

See also:
*Note set_config_file::.
*Note get_config_float::.
*Note set_config_string::.
*Note set_config_hex::.
*Note set_config_int::.
*Note set_config_id::.

File: allegro.info,  Node: set_config_id,  Next: Standard config variables,  Prev: set_config_float,  Up: Configuration

4.22 set_config_id
==================

void set_config_id(const char *section, const char *name, int val);
     Writes a 4-letter driver ID variable to the current config file.
     See the comments about set_config_string().

See also:
*Note set_config_file::.
*Note get_config_id::.
*Note set_config_string::.
*Note set_config_float::.
*Note set_config_hex::.
*Note set_config_int::.

File: allegro.info,  Node: Standard config variables,  Next: install_mouse,  Prev: set_config_id,  Up: Configuration

4.23 Standard config variables
==============================

Allegro uses these standard variables from the configuration file:

   * [system]
     Section containing general purpose variables:

        * system = x
          Specifies which system driver to use. This is currently only
          useful on Linux, for choosing between the XWindows ("XWIN")
          or console ("LNXC") modes.

        * keyboard = x
          Specifies which keyboard layout to use. The parameter is the
          name of a keyboard mapping file produced by the keyconf
          utility, and can either be a fully qualified file path or a
          basename like "us" or "uk". If the latter, Allegro will look
          first for a separate config file with that name (eg.
          "uk.cfg") and then for an object with that name in the
          keyboard.dat file (eg. "UK_CFG"). The config file or
          keyboard.dat file can be stored in the same directory as the
          program, or in the location pointed to by the ALLEGRO
          environment variable. Look in the keyboard.dat file to see
          what mappings are currently available.

        * language = x
          Specifies which language file to use for error messages and
          other bits of system text. The parameter is the name of a
          translation file, and can either be a fully qualified file
          path or a basename like "en" or "sp". If the latter, Allegro
          will look first for a separate config file with a name in the
          form "entext.cfg", and then for an object with that name in
          the language.dat file (eg. "ENTEXT_CFG"). The config file or
          language.dat file can be stored in the same directory as the
          program, or in the location pointed to by the ALLEGRO
          environment variable. Look in the language.dat file to see
          which mappings are currently available.

        * menu_opening_delay = x
          Sets how long the menus take to auto-open. The time is given
          in milliseconds (default is 300). Specifying -1 will disable
          the auto-opening feature.

        * dga_mouse = x
          X only: disable to work around a bug in some X servers' DGA
          modes, concerning the mouse.  Default is on; enable the
          workaround by setting the variable to "0".

        * dga_centre = x
          X only: instructs the DGA driver to centre the Allegro screen
          if the actual screen resolution is higher than Allegro's.
          Default is on; disable this feature by setting the variable
          to "0".

        * dga_clear = x
          X only: instructs the DGA driver to clear visible video
          memory on startup.  Default is on; disable this feature by
          setting the variable to "0".

   * [graphics]
     Section containing graphics configuration information, using the
     variables:

        * gfx_card = x
          Specifies which graphics driver to use when the program
          requests GFX_AUTODETECT. Multiple possible drivers can be
          suggested with extra lines in the form "gfx_card1 = x",
          "gfx_card2 = x", etc, or you can specify different drivers
          for each mode and color depth with variables in the form
          "gfx_card_24bpp = x", "gfx_card_640x480x16 = x", etc.

        * gfx_cardw = x
          Specifies which graphics driver to use when the program
          requests GFX_AUTODETECT_WINDOWED. This variable functions
          exactly like gfx_card in all other respects. If it is not
          set, Allegro will look for the gfx_card variable.

        * disable_vsync = x
          Specifies whether to disable synchronization with the
          vertical blank when page-flipping (yes or no). Disabling
          synchronization may increase the frame rate on slow systems,
          at the expense of introducing flicker on fast systems.

        * vbeaf_driver = x
          DOS and Linux only: specifies where to look for the VBE/AF
          driver (vbeaf.drv). If this variable is not set, Allegro will
          look in the same directory as the program, and then fall back
          on the standard locations (c:\ for DOS, /usr/local/lib,
          /usr/lib, /lib, and / for Linux, or the directory specified
          with the VBEAF_PATH environment variable).

        * framebuffer = x
          Linux only: specifies what device file to use for the fbcon
          driver. If this variable is not set, Allegro checks the
          FRAMEBUFFER environment variable, and then defaults to
          /dev/fb0.

        * force_centering = x
          Unix/X11 only: specifies whether to force window centering in
          fullscreen mode when the XWFS driver is used (yes or no).
          Enabling this setting may cause some artifacts to appear on
          KDE desktops.

        * disable_direct_updating = x
          Windows only: specifies whether to disable direct updating
          when the GFX_DIRECTX_WIN driver is used in color conversion
          mode (yes or no).  Direct updating can cause artifacts to be
          left on the desktop when the window is moved or minimized;
          disabling it results in a significant performance loss.

   * [mouse]
     Section containing mouse configuration information, using the
     variables:

        * mouse = x
          Mouse driver type. Available DOS drivers are:

               MICK - mickey mode driver (normally the best)
               I33  - int 0x33 callback driver
               POLL - timer polling (for use under NT)

          Linux console mouse drivers are:

               MS   - Microsoft serial mouse
               IMS  - Microsoft serial mouse with Intellimouse extension
               LPS2 - PS2 mouse
               LIPS - PS2 mouse with Intellimouse extension
               GPMD - GPM repeater data (Mouse Systems protocol)
               EV   - Event interfaces (EVDEV)

        * num_buttons = x
          Sets the number of mouse buttons viewed by Allegro. You don't
          normally need to set this variable because Allegro will
          autodetect it. You can only use it to restrict the set of
          actual mouse buttons.

        * emulate_three = x
          Sets whether to emulate a third mouse button by detecting
          chords of the left and right buttons (yes or no). Defaults to
          no.

        * mouse_device = x
          Linux only: specifies the name of the mouse device file (eg.
          /dev/mouse).

        * ev_absolute = x
          Linux only: specifies the mode for the default EV input: 0 -
          relative mode: pointer position changes if the input moves, 1
          - absolute mode: pointer position is the input position.  If
          unspecified, the mode is relative.  If the device supports
          several tools (such as a graphic tablet), the default input
          is the mouse. If the device has only one tool (e.g. a normal
          mouse) the default input is this tool. All additionnal tools
          work in absolute mode.

        * ev_min_x = x
          ev_max_x = x
          ev_min_y = x
          ev_max_y = x
          ev_min_z = x
          ev_max_z = x
          Linux only: for absolute EV inputs, minimum and maximum
          value. By default this information is autodetected.

        * mouse_accel_factor = x
          Windows only: specifies the mouse acceleration factor.
          Defaults to 1.  Set it to 0 in order to disable mouse
          acceleration. 2 accelerates twice as much as 1.

   * [sound]
     Section containing sound configuration information, using the
     variables:

        * digi_card = x
          Sets the driver to use for playing digital samples.

        * midi_card = x
          Sets the driver to use for MIDI music.

        * digi_input_card = x
          Sets the driver to use for digital sample input.

        * midi_input_card = x
          Sets the driver to use for MIDI data input.

        * digi_voices = x
          Specifies the minimum number of voices to reserve for use by
          the digital sound driver. How many are possible depends on
          the driver.

        * midi_voices = x
          Specifies the minimum number of voices to reserve for use by
          the MIDI sound driver. How many are possible depends on the
          driver.

        * digi_volume = x
          Sets the volume for digital sample playback, from 0 to 255.

        * midi_volume = x
          Sets the volume for midi music playback, from 0 to 255.

        * quality = x
          Controls the sound quality vs. performance tradeoff for the
          sample mixing code. This can be set to any of the values:

               0 - fast mixing of 8-bit data into 16-bit buffers
               1 - true 16-bit mixing (requires a 16-bit stereo soundcard)
               2 - interpolated 16-bit mixing

        * flip_pan = x
          Toggling this between 0 and 1 reverses the left/right panning
          of samples, which might be needed because some SB cards
          (including mine :-) get the stereo image the wrong way round.

        * sound_freq = x
          DOS, Unix and BeOS: sets the sample frequency. With the SB
          driver, possible rates are 11906 (any), 16129 (any), 22727
          (SB 2.0 and above), and 45454 (only on SB 2.0 or SB16, not
          the stereo SB Pro driver). On the ESS Audiodrive, possible
          rates are 11363, 17046, 22729, or 44194. On the Ensoniq
          Soundscape, possible rates are 11025, 16000, 22050, or 48000.
          On the Windows Sound System, possible rates are 11025, 22050,
          44100, or 48000. Don't worry if you set some other number by
          mistake: Allegro will automatically round it to the closest
          supported frequency.

        * sound_bits = x
          Unix and BeOS: sets the preferred number of bits (8 or 16).

        * sound_stereo = x
          Unix and BeOS: selects mono or stereo output (0 or 1).

        * sound_port = x
          DOS only: sets the soundcard port address (this is usually
          220).

        * sound_dma = x
          DOS only: sets the soundcard DMA channel (this is usually 1).

        * sound_irq = x
          DOS only: sets the soundcard IRQ number (this is usually 7).

        * fm_port = x
          DOS only: sets the port address of the OPL synth (this is
          usually 388).

        * mpu_port = x
          DOS only: sets the port address of the MPU-401 MIDI interface
          (this is usually 330).

        * mpu_irq = x
          DOS only: sets the IRQ for the MPU-401 (this is usually the
          same as sound_irq).

        * ibk_file = x
          DOS only: specifies the name of a .IBK file which will be
          used to replace the standard Adlib patch set.

        * ibk_drum_file = x
          DOS only: specifies the name of a .IBK file which will be
          used to replace the standard set of Adlib percussion patches.

        * oss_driver = x
          Unix only: sets the OSS device driver name. Usually /dev/dsp
          or /dev/audio, but could be a particular device (e.g.
          /dev/dsp2).

        * oss_numfrags = x
          oss_fragsize = x
          Unix only: sets number of OSS driver fragments (buffers) and
          size of each buffer in samples. Buffers are filled with data
          in the interrupts where interval between subsequent
          interrupts is not less than 10 ms. If hardware can play all
          information from buffers faster than 10 ms, then there will
          be clicks, when hardware have played all data and library has
          not prepared new data yet. On the other hand, if it takes too
          long for device driver to play data from all buffers, then
          there will be delays between action which triggers sound and
          sound itself.

        * oss_midi_driver = x
          Unix only: sets the OSS MIDI device name. Usually
          /dev/sequencer.

        * oss_mixer_driver = x
          Unix only: sets the OSS mixer device name. Usually /dev/mixer.

        * esd_server = x
          Unix only: where to find the ESD (Enlightened Sound Daemon)
          server.

        * alsa_card = x
          alsa_pcmdevice = x
          Unix only: card number and PCM device for the ALSA 0.5 sound
          driver.

        * alsa_device = x
          Unix only: device name for the ALSA 0.9 sound driver. The
          format is [:,], for example: hw:0,1.

        * alsa_mixer_elem = x
          Unix only: mixer element name for the ALSA 0.9 driver. The
          default is PCM.

        * alsa_numfrags = x
          Unix only: number of ALSA driver fragments (buffers).

        * alsa_fragsize = x
          Unix only: size of each ALSA fragment, in samples.

        * alsa_rawmidi_card = x
          Unix only: card number and device for the ALSA 0.5 midi
          driver.

        * alsa_rawmidi_device = x
          Unix only: device for the ALSA 0.5 midi driver or device name
          for the ALSA 0.9 midi driver (see alsa_device for the format).

        * be_midi_quality = x
          BeOS only: system MIDI synthesizer instruments quality. 0
          uses low quality 8-bit 11 kHz samples, 1 uses 16-bit 22 kHz
          samples.

        * be_midi_freq = x
          BeOS only: MIDI sample mixing frequency in Hz. Can be 11025,
          22050 or 44100.

        * be_midi_interpolation = x
          BeOS only: specifies the MIDI samples interpolation method. 0
          doesn't interpolate, it's fast but has the worst quality; 1
          does a fast interpolation with better performances, but it's
          a bit slower than the previous method; 2 does a linear
          interpolation between samples, it is the slowest method but
          gives the best performances.

        * be_midi_reverb = x
          BeOS only: reverberation intensity, from 0 to 5. 0 disables
          it, 5 is the strongest one.

        * ca_midi_quality = x
          MacOS X only: CoreAudio MIDI synthesizer rendering quality,
          from 0 to 127.  Higher qualities sound better but increase
          the CPU work load.

        * ca_midi_reverb = x
          MacOS X only: CoreAudio MIDI synthesizer reverberation
          intensity, from 0 to 5. 0 equals to a small room (low
          reverb), 5 to a plate (high reverb).

        * patches = x
          Specifies where to find the sample set for the DIGMID driver.
          This can either be a Gravis style directory containing a
          collection of .pat files and a default.cfg index, or an
          Allegro datafile produced by the pat2dat utility. If this
          variable is not set, Allegro will look either for a
          default.cfg or patches.dat file in the same directory as the
          program, the directory pointed to by the ALLEGRO environment
          variable, and the standard GUS directory pointed to by the
          ULTRASND environment variable.

   * [midimap]
     If you are using the SB MIDI output or MPU-401 drivers with an
     external synthesiser that is not General MIDI compatible, you can
     use the midimap section of the config file to specify a patch
     mapping table for converting GM patch numbers into whatever bank
     and program change messages will select the appropriate sound on
     your synth. This is a real piece of self-indulgence. I have a
     Yamaha TG500, which has some great sounds but no GM patch set, and
     I just had to make it work somehow...

     This section consists of a set of lines in the form:

        * p<n> = bank0 bank1 prog pitch
          With this statement, n is the GM program change number
          (1-128), bank0 and bank1 are the two bank change messages to
          send to your synth (on controllers #0 and #32), prog is the
          program change message to send to your synth, and pitch is
          the number of semitones to shift everything that is played
          with that sound. Setting the bank change numbers to -1 will
          prevent them from being sent.

          For example, the line:

          p36 = 0 34 9 12

          specifies that whenever GM program 36 (which happens to be a
          fretless bass) is selected, Allegro should send a bank change
          message #0 with a parameter of 0, a bank change message #32
          with a parameter of 34, a program change with a parameter of
          9, and then should shift everything up by an octave.

   * [joystick]
     Section containing joystick configuration information, using the
     variables:

        * joytype = x
          Specifies which joystick driver to use when the program
          requests JOY_TYPE_AUTODETECT.

        * joystick_device = x
          BeOS and Linux only: specifies the name of the joystick
          device to be used (as reported in the system joystick
          preferences under BeOS). The first device found is used by
          default. If you want to specify the device for each joystick,
          use variables of the form joystick_device_n, where n is the
          joystick number.

        * throttle_axis = x
          Linux only: sets the axis number the throttle is located at.
          This variable will be used for every detected joystick. If
          you want to specify the axis number for each joystick
          individually, use variables of the form throttle_axis_n,
          where n is the joystick number.


See also:
*Note set_config_file::.
*Note set_config_string::.
*Note get_config_string::.

File: allegro.info,  Node: Mouse,  Next: Timer,  Prev: Configuration,  Up: Top

5 Mouse routines
****************

* Menu:

* install_mouse::
* remove_mouse::
* poll_mouse::
* mouse_needs_poll::
* mouse_x::
* mouse_sprite::
* show_mouse::
* scare_mouse::
* scare_mouse_area::
* unscare_mouse::
* freeze_mouse_flag::
* position_mouse::
* position_mouse_z::
* set_mouse_range::
* set_mouse_speed::
* set_mouse_sprite::
* set_mouse_sprite_focus::
* get_mouse_mickeys::
* mouse_callback::


File: allegro.info,  Node: install_mouse,  Next: remove_mouse,  Prev: Standard config variables,  Up: Mouse

5.1 install_mouse
=================

int install_mouse();
     Installs the Allegro mouse handler. You must do this before using
     any other mouse functions. Returns -1 on failure, otherwise the
     number of buttons on the mouse.

See also:
*Note remove_mouse::.
*Note poll_mouse::.
*Note mouse_x::.
*Note show_mouse::.
*Note get_mouse_mickeys::.
*Note position_mouse::.
*Note set_mouse_range::.
*Note set_mouse_speed::.
*Note Standard config variables::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: remove_mouse,  Next: poll_mouse,  Prev: install_mouse,  Up: Mouse

5.2 remove_mouse
================

void remove_mouse();
     Removes the mouse handler. You don't normally need to bother
     calling this, because allegro_exit() will do it for you.

See also:
*Note install_mouse::.
*Note allegro_exit::.

File: allegro.info,  Node: poll_mouse,  Next: mouse_needs_poll,  Prev: remove_mouse,  Up: Mouse

5.3 poll_mouse
==============

int poll_mouse();
     Wherever possible, Allegro will read the mouse input
     asynchronously (ie.  from inside an interrupt handler), but on
     some platforms that may not be possible, in which case you must
     call this routine at regular intervals to update the mouse state
     variables. To help you test your mouse polling code even if you
     are programming on a platform that doesn't require it, after the
     first time that you call this function Allegro will switch into
     polling mode, so from that point onwards you will have to call this
     routine in order to get any mouse input at all, regardless of
     whether the current driver actually needs to be polled or not.
     Returns zero on success, or a negative number on failure (ie. no
     mouse driver installed).

See also:
*Note mouse_needs_poll::.
*Note install_mouse::.
*Note mouse_x::.
*Note exlights::.
*Note exmouse::.
*Note exshade::.
*Note exspline::.
*Note extrans::.

File: allegro.info,  Node: mouse_needs_poll,  Next: mouse_x,  Prev: poll_mouse,  Up: Mouse

5.4 mouse_needs_poll
====================

int mouse_needs_poll();
     Returns TRUE if the current mouse driver is operating in polling
     mode.

See also:
*Note poll_mouse::.
*Note install_mouse::.
*Note mouse_x::.

File: allegro.info,  Node: mouse_x,  Next: mouse_sprite,  Prev: mouse_needs_poll,  Up: Mouse

5.5 mouse_x
===========

extern volatile int mouse_x;

extern volatile int mouse_y;

extern volatile int mouse_z;

extern volatile int mouse_b;

extern volatile int mouse_pos;
     Global variables containing the current mouse position and button
     state.  Wherever possible these values will be updated
     asynchronously, but if mouse_needs_poll() returns TRUE, you must
     manually call poll_mouse() to update them with the current input
     state. The mouse_x and mouse_y positions are integers ranging from
     zero to the bottom right corner of the screen. The mouse_z
     variable holds the current wheel position, when using an input
     driver that supports wheel mice. The mouse_b variable is a
     bitfield indicating the state of each button: bit 0 is the left
     button, bit 1 the right, and bit 2 the middle button. For example:

          if (mouse_b & 1)
             printf("Left button is pressed\n");

          if (!(mouse_b & 2))
             printf("Right button is not pressed\n");

     The mouse_pos variable has the current X coordinate in the high
     word and the Y in the low word. This may be useful in tight
     polling loops where a mouse interrupt could occur between your
     reading of the two separate variables, since you can copy this
     value into a local variable with a single instruction and then
     split it up at your leisure.

See also:
*Note install_mouse::.
*Note poll_mouse::.
*Note mouse_needs_poll::.
*Note exalpha::.
*Note exlights::.
*Note exmouse::.
*Note exshade::.
*Note exspline::.
*Note extrans::.

File: allegro.info,  Node: mouse_sprite,  Next: show_mouse,  Prev: mouse_x,  Up: Mouse

5.6 mouse_sprite
================

extern BITMAP *mouse_sprite;

extern int mouse_x_focus;

extern int mouse_y_focus;
     Global variables containing the current mouse sprite and the focus
     point.  These are read-only, and only to be modified using the
     set_mouse_sprite() and set_mouse_sprite_focus() functions.

See also:
*Note set_mouse_sprite::.
*Note set_mouse_sprite_focus::.
*Note BITMAP::.

File: allegro.info,  Node: show_mouse,  Next: scare_mouse,  Prev: mouse_sprite,  Up: Mouse

5.7 show_mouse
==============

void show_mouse(BITMAP *bmp);
     Tells Allegro to display a mouse pointer on the screen. This will
     only work if the timer module has been installed. The mouse
     pointer will be drawn onto the specified bitmap, which should
     normally be 'screen' (see later for information about bitmaps). To
     hide the mouse pointer, call show_mouse(NULL). Warning: if you
     draw anything onto the screen while the pointer is visible, a
     mouse movement interrupt could occur in the middle of your drawing
     operation. If this happens the mouse buffering and SVGA bank
     switching code will get confused and will leave 'mouse droppings'
     all over the screen. To prevent this, you must make sure you turn
     off the mouse pointer whenever you draw onto the screen.

See also:
*Note install_mouse::.
*Note install_timer::.
*Note set_mouse_sprite::.
*Note scare_mouse::.
*Note freeze_mouse_flag::.
*Note exmouse::.
*Note exshade::.
*Note exspline::.
*Note BITMAP::.

File: allegro.info,  Node: scare_mouse,  Next: scare_mouse_area,  Prev: show_mouse,  Up: Mouse

5.8 scare_mouse
===============

void scare_mouse();
     Helper for hiding the mouse pointer prior to a drawing operation.
     This will temporarily get rid of the pointer, but only if that is
     really required (ie. the mouse is visible, and is displayed on the
     physical screen rather than some other memory surface, and it is
     not a hardware cursor). The previous mouse state is stored for
     subsequent calls to unscare_mouse().

See also:
*Note unscare_mouse::.
*Note scare_mouse_area::.
*Note show_mouse::.

File: allegro.info,  Node: scare_mouse_area,  Next: unscare_mouse,  Prev: scare_mouse,  Up: Mouse

5.9 scare_mouse_area
====================

void scare_mouse_area(int x, int y, int w, int h);
     Like scare_mouse(), but will only hide the cursor if it is inside
     the specified rectangle. Otherwise the cursor will simply be
     frozen in place until you call unscare_mouse(), so it cannot
     interfere with your drawing.

See also:
*Note unscare_mouse::.
*Note scare_mouse::.
*Note show_mouse::.

File: allegro.info,  Node: unscare_mouse,  Next: freeze_mouse_flag,  Prev: scare_mouse_area,  Up: Mouse

5.10 unscare_mouse
==================

void unscare_mouse();
     Undoes the effect of a previous call to scare_mouse() or
     scare_mouse_area(), restoring the original pointer state.

See also:
*Note scare_mouse::.
*Note scare_mouse_area::.

File: allegro.info,  Node: freeze_mouse_flag,  Next: position_mouse,  Prev: unscare_mouse,  Up: Mouse

5.11 freeze_mouse_flag
======================

extern volatile int freeze_mouse_flag;
     If this flag is set, the mouse pointer won't be redrawn when the
     mouse moves. This can avoid the need to hide the pointer every
     time you draw to the screen, as long as you make sure your drawing
     doesn't overlap with the current pointer position.

See also:
*Note show_mouse::.

File: allegro.info,  Node: position_mouse,  Next: position_mouse_z,  Prev: freeze_mouse_flag,  Up: Mouse

5.12 position_mouse
===================

void position_mouse(int x, int y);
     Moves the mouse to the specified screen position. It is safe to
     call even when a mouse pointer is being displayed.

See also:
*Note install_mouse::.
*Note position_mouse_z::.
*Note set_mouse_range::.
*Note set_mouse_speed::.

File: allegro.info,  Node: position_mouse_z,  Next: set_mouse_range,  Prev: position_mouse,  Up: Mouse

5.13 position_mouse_z
=====================

void position_mouse_z(int z);
     Sets the mouse wheel position variable to the specified value.

See also:
*Note install_mouse::.
*Note position_mouse::.

File: allegro.info,  Node: set_mouse_range,  Next: set_mouse_speed,  Prev: position_mouse_z,  Up: Mouse

5.14 set_mouse_range
====================

void set_mouse_range(int x1, int y1, int x2, int y2);
     Sets the area of the screen within which the mouse can move. Pass
     the top left corner and the bottom right corner (inclusive). If
     you don't call this function the range defaults to (0, 0,
     SCREEN_W-1, SCREEN_H-1).

See also:
*Note install_mouse::.
*Note set_mouse_speed::.
*Note position_mouse::.

File: allegro.info,  Node: set_mouse_speed,  Next: set_mouse_sprite,  Prev: set_mouse_range,  Up: Mouse

5.15 set_mouse_speed
====================

void set_mouse_speed(int xspeed, int yspeed);
     Sets the mouse speed. Larger values of xspeed and yspeed represent
     slower mouse movement: the default for both is 2.

See also:
*Note install_mouse::.
*Note set_mouse_range::.
*Note position_mouse::.

File: allegro.info,  Node: set_mouse_sprite,  Next: set_mouse_sprite_focus,  Prev: set_mouse_speed,  Up: Mouse

5.16 set_mouse_sprite
=====================

void set_mouse_sprite(BITMAP *sprite);
     You don't like my mouse pointer? No problem. Use this function to
     supply an alternative of your own. If you change the pointer and
     then want to get my lovely arrow back again, call
     set_mouse_sprite(NULL).

     As a bonus, set_mouse_sprite(NULL) uses the current palette in
     choosing colors for the arrow. So if your arrow mouse sprite looks
     ugly after changing the palette, call set_mouse_sprite(NULL).

See also:
*Note install_mouse::.
*Note show_mouse::.
*Note set_mouse_sprite_focus::.
*Note exmouse::.
*Note BITMAP::.

File: allegro.info,  Node: set_mouse_sprite_focus,  Next: get_mouse_mickeys,  Prev: set_mouse_sprite,  Up: Mouse

5.17 set_mouse_sprite_focus
===========================

void set_mouse_sprite_focus(int x, int y);
     The mouse focus is the bit of the pointer that represents the
     actual mouse position, ie. the (mouse_x, mouse_y) position. By
     default this is the top left corner of the arrow, but if you are
     using a different mouse pointer you might need to alter it.

See also:
*Note set_mouse_sprite::.
*Note exmouse::.

File: allegro.info,  Node: get_mouse_mickeys,  Next: mouse_callback,  Prev: set_mouse_sprite_focus,  Up: Mouse

5.18 get_mouse_mickeys
======================

void get_mouse_mickeys(int *mickeyx, int *mickeyy);
     Measures how far the mouse has moved since the last call to this
     function. The mouse will continue to generate movement mickeys
     even when it reaches the edge of the screen, so this form of input
     can be useful for games that require an infinite range of mouse
     movement.

See also:
*Note install_mouse::.
*Note exmouse::.

File: allegro.info,  Node: mouse_callback,  Next: install_timer,  Prev: get_mouse_mickeys,  Up: Mouse

5.19 mouse_callback
===================

extern void (*mouse_callback)(int flags);
     Called by the interrupt handler whenever the mouse moves or one of
     the buttons changes state. This function must be in locked memory,
     and must execute _very_ quickly! It is passed the event flags that
     triggered the call, which is a bitmask containing any of the
     values MOUSE_FLAG_MOVE, MOUSE_FLAG_LEFT_DOWN, MOUSE_FLAG_LEFT_UP,
     MOUSE_FLAG_RIGHT_DOWN, MOUSE_FLAG_RIGHT_UP,
     MOUSE_FLAG_MIDDLE_DOWN, MOUSE_FLAG_MIDDLE_UP, and
     MOUSE_FLAG_MOVE_Z.

See also:
*Note install_mouse::.

File: allegro.info,  Node: Timer,  Next: Keyboard,  Prev: Mouse,  Up: Top

6 Timer routines
****************

Allegro can set up several virtual timer functions, all going at
different speeds.

Under DOS it will constantly reprogram the clock to make sure they are
all called at the correct times. Because they alter the low level timer
chip settings, these routines should not be used together with other
DOS timer functions like the djgpp uclock() routine. Moreover, the FPU
state is not preserved across Allegro interrupts so you ought not to
use floating point or MMX code inside timer interrupt handlers.

Under other platforms, they are usually implemented using threads,
which run parallel to the main thread. Therefore timer callbacks on
such platforms will not block the main thread when called, so you may
need to use appropriate synchronisation devices (eg. mutexes,
semaphores, etc.) when accessing data that is shared by a callback and
the main thread. (Currently Allegro does not provide such devices.)

* Menu:

* install_timer::
* remove_timer::
* install_int::
* install_int_ex::
* remove_int::
* install_param_int::
* install_param_int_ex::
* remove_param_int::
* timer_can_simulate_retrace::
* timer_simulate_retrace::
* timer_is_using_retrace::
* retrace_count::
* retrace_proc::
* rest::
* rest_callback::


File: allegro.info,  Node: install_timer,  Next: remove_timer,  Prev: mouse_callback,  Up: Timer

6.1 install_timer
=================

int install_timer();
     Installs the Allegro timer interrupt handler. You must do this
     before installing any user timer routines, and also before
     displaying a mouse pointer, playing FLI animations or MIDI music,
     and using any of the GUI routines. Returns zero on success, or a
     negative number on failure (but you may decide not to check the
     return value as this function is very unlikely to fail).

See also:
*Note remove_timer::.
*Note install_int::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: remove_timer,  Next: install_int,  Prev: install_timer,  Up: Timer

6.2 remove_timer
================

void remove_timer();
     Removes the Allegro timer handler (and, under DOS, passes control
     of the clock back to the operating system). You don't normally
     need to bother calling this, because allegro_exit() will do it for
     you.

See also:
*Note install_timer::.
*Note allegro_exit::.

File: allegro.info,  Node: install_int,  Next: install_int_ex,  Prev: remove_timer,  Up: Timer

6.3 install_int
===============

int install_int(void (*proc)(), int speed);
     Installs a user timer handler, with the speed given as the number
     of milliseconds between ticks. This is the same thing as
     install_int_ex(proc, MSEC_TO_TIMER(speed)). If you call this
     routine without having first installed the timer module,
     install_timer() will be called automatically. If there is no room
     to add a new user timer, install_int() will return a negative
     number, otherwise it returns zero.

See also:
*Note install_timer::.
*Note remove_int::.
*Note install_int_ex::.
*Note install_param_int::.
*Note exscn3d::.
*Note exswitch::.
*Note extimer::.
*Note exzbuf::.

File: allegro.info,  Node: install_int_ex,  Next: remove_int,  Prev: install_int,  Up: Timer

6.4 install_int_ex
==================

int install_int_ex(void (*proc)(), int speed);
     Adds a function to the list of user timer handlers or, if it is
     already installed, retroactively adjusts its speed (i.e makes as
     though the speed change occured precisely at the last tick). The
     speed is given in hardware clock ticks, of which there are 1193181
     a second. You can convert from other time formats to hardware
     clock ticks with the macros:

          SECS_TO_TIMER(secs)  - give the number of seconds between
                                 each tick
          MSEC_TO_TIMER(msec)  - give the number of milliseconds
                                 between ticks
          BPS_TO_TIMER(bps)    - give the number of ticks each second
          BPM_TO_TIMER(bpm)    - give the number of ticks per minute

     If there is no room to add a new user timer, install_int_ex() will
     return a negative number, otherwise it returns zero. There can
     only be sixteen timers in use at a time, and some other parts of
     Allegro (the GUI code, the mouse pointer display routines, rest(),
     the FLI player, and the MIDI player) need to install handlers of
     their own, so you should avoid using too many at the same time. If
     you call this routine without having first installed the timer
     module, install_timer() will be called automatically.

     Your function will be called by the Allegro interrupt handler and
     not directly by the processor, so it can be a normal C function
     and does not need a special wrapper. You should be aware, however,
     that it will be called in an interrupt context, which imposes a
     lot of restrictions on what you can do in it. It should not use
     large amounts of stack, it must not make any calls to the
     operating system, use C library functions, or contain any floating
     point code, and it must execute very quickly. Don't try to do lots
     of complicated code in a timer handler: as a general rule you
     should just set some flags and respond to these later in your main
     control loop.

     In a DOS protected mode environment like djgpp, memory is
     virtualised and can be swapped to disk. Due to the non-reentrancy
     of DOS, if a disk swap occurs inside an interrupt handler the
     system will die a painful death, so you need to make sure you lock
     all the memory (both code and data) that is touched inside timer
     routines. Allegro will lock everything it uses, but you are
     responsible for locking your handler functions. The macros
     LOCK_VARIABLE (variable), END_OF_FUNCTION (function_name),
     END_OF_STATIC_FUNCTION (function_name), and LOCK_FUNCTION
     (function_name) can be used to simplify this task. For example, if
     you want an interrupt handler that increments a counter variable,
     you should write:

          volatile int counter;

          void my_timer_handler()
          {
             counter++;
          }

          END_OF_FUNCTION(my_timer_handler)

     and in your initialisation code you should lock the memory:

          LOCK_VARIABLE(counter);
          LOCK_FUNCTION(my_timer_handler);

     Obviously this can get awkward if you use complicated data
     structures and call other functions from within your handler, so
     you should try to keep your interrupt routines as simple as
     possible.

See also:
*Note install_timer::.
*Note remove_int::.
*Note install_int::.
*Note install_param_int_ex::.
*Note extimer::.
*Note exupdate::.

File: allegro.info,  Node: remove_int,  Next: install_param_int,  Prev: install_int_ex,  Up: Timer

6.5 remove_int
==============

void remove_int(void (*proc)());
     Removes a function from the list of user interrupt routines. At
     program termination, allegro_exit() does this automatically.

See also:
*Note install_int::.
*Note install_int_ex::.
*Note remove_param_int::.

File: allegro.info,  Node: install_param_int,  Next: install_param_int_ex,  Prev: remove_int,  Up: Timer

6.6 install_param_int
=====================

int install_param_int(void (*proc)(void *), void *param, int speed);
     Like install_int(), but the callback routine will be passed a copy
     of the specified void pointer parameter. To disable the handler,
     use remove_param_int() instead of remove_int().

See also:
*Note install_timer::.
*Note remove_param_int::.
*Note install_param_int_ex::.
*Note install_int::.

File: allegro.info,  Node: install_param_int_ex,  Next: remove_param_int,  Prev: install_param_int,  Up: Timer

6.7 install_param_int_ex
========================

int install_param_int_ex(void (*proc)(void *), void *param, int speed);
     Like install_int_ex(), but the callback routine will be passed a
     copy of the specified void pointer parameter. To disable the
     handler, use remove_param_int() instead of remove_int().

See also:
*Note install_timer::.
*Note remove_param_int::.
*Note install_param_int::.
*Note install_int_ex::.

File: allegro.info,  Node: remove_param_int,  Next: timer_can_simulate_retrace,  Prev: install_param_int_ex,  Up: Timer

6.8 remove_param_int
====================

void remove_param_int(void (*proc)(void *), void *param);
     Like remove_int(), but for use with timer callbacks that have
     parameter values. If there is more than one copy of the same
     callback active at a time, it identifies which one to remove by
     checking the parameter value (so you can't have more than one copy
     of a handler using an identical parameter).

See also:
*Note install_param_int::.
*Note install_param_int_ex::.
*Note remove_int::.

File: allegro.info,  Node: timer_can_simulate_retrace,  Next: timer_simulate_retrace,  Prev: remove_param_int,  Up: Timer

6.9 timer_can_simulate_retrace
==============================

int timer_can_simulate_retrace()
     Checks whether it is possible to sync the timer module with the
     monitor retrace, given the current platform and environment (at
     the moment this is only possible when running in clean DOS mode in
     a VGA or mode-X resolution). Returns non-zero if simulation is
     possible.

See also:
*Note timer_simulate_retrace::.
*Note timer_is_using_retrace::.
*Note ex3buf::.

File: allegro.info,  Node: timer_simulate_retrace,  Next: timer_is_using_retrace,  Prev: timer_can_simulate_retrace,  Up: Timer

6.10 timer_simulate_retrace
===========================

void timer_simulate_retrace(int enable);
     The DOS timer handler can be used to simulate vertical retrace
     interrupts. A retrace interrupt can be extremely useful for
     implementing smooth animation, but unfortunately the VGA hardware
     doesn't support it.  The EGA did, and some SVGA chipsets do, but
     not enough, and not in a sufficiently standardised way, for it to
     be useful. Allegro works around this by programming the timer to
     generate an interrupt when it thinks a retrace is next likely to
     occur, and polling the VGA inside the interrupt handler to make
     sure it stays in sync with the monitor refresh. This works quite
     well in some situations, but there are a lot of caveats:

        * You can't use the retrace simulator in SVGA modes. It will
          work with some chipsets, but not others, and it conflicts
          with most VESA implementations. Retrace simulation is only
          reliable in VGA mode 13h and mode-X.

        * Retrace simulation doesn't work under win95, because win95
          returns garbage when I try to read the elapsed time from the
          PIT. If anyone knows how I can make this work, please tell me!

        * Retrace simulation involves a lot of waiting around in the
          timer handler with interrupts disabled. This will
          significantly slow down your entire system, and may also
          cause static when playing samples on SB 1.0 cards (because
          they don't support auto-initialised DMA: SB 2.0 and above
          will be fine).

     Bearing all those problems in mind, I'd strongly advise against
     relying on the retrace simulator. If you are coding in mode-X, and
     don't care about your program working under win95, it is great,
     but it would be a good idea to give the user an option to disable
     it.

     Retrace simulation must be enabled before you use the triple
     buffering functions in a mode-X resolution. It can also be useful
     for simple retrace detection, because the polling vsync() function
     can occasionally miss retraces if a soundcard or timer interrupt
     occurs at exactly the same time as the retrace. When retrace
     interrupt simulation is enabled, vsync() will check the
     retrace_count variable rather than polling the VGA, so it won't
     miss retraces even if they are masked by other interrupts.

See also:
*Note install_timer::.
*Note retrace_count::.
*Note retrace_proc::.
*Note request_scroll::.
*Note vsync::.
*Note timer_can_simulate_retrace::.
*Note timer_is_using_retrace::.
*Note enable_triple_buffer::.
*Note ex3buf::.

File: allegro.info,  Node: timer_is_using_retrace,  Next: retrace_count,  Prev: timer_simulate_retrace,  Up: Timer

6.11 timer_is_using_retrace
===========================

int timer_is_using_retrace()
     Checks whether the timer module is currently synced with the
     monitor retrace or not. Returns non-zero if it is.

See also:
*Note timer_simulate_retrace::.
*Note timer_can_simulate_retrace::.

File: allegro.info,  Node: retrace_count,  Next: retrace_proc,  Prev: timer_is_using_retrace,  Up: Timer

6.12 retrace_count
==================

extern volatile int retrace_count;
     If the retrace simulator is installed, this count is incremented
     on each vertical retrace; otherwise, if the refresh rate is known,
     the count is incremented at the same rate (ignoring retraces);
     otherwise, it is incremented 70 times a second. This provides a
     useful way of controlling the speed of your program without the
     hassle of installing user timer functions.

     The speed of retraces varies depending on the graphics mode. In
     mode 13h and 200/400 line mode-X resolutions there are 70 retraces
     a second, and in 240/480 line modes there are 60. It can be as low
     as 50 (in 376x282 mode) or as high as 92 (in 400x300 mode).

See also:
*Note timer_simulate_retrace::.
*Note timer_is_using_retrace::.
*Note retrace_proc::.
*Note ex3d::.
*Note exblend::.
*Note exdbuf::.
*Note exflip::.
*Note exlights::.

File: allegro.info,  Node: retrace_proc,  Next: rest,  Prev: retrace_count,  Up: Timer

6.13 retrace_proc
=================

extern void (*retrace_proc)();
     If the retrace simulator is installed, this function is called
     during every vertical retrace; otherwise, if the refresh rate is
     known, the function is called at the same rate (ignoring
     retraces); otherwise it is called 70 times a second. Set it to
     NULL to disable the callback. The function must obey the same
     rules as regular timer handlers (ie. it must be locked, and
     mustn't call OS or libc functions) but even more so: it must
     execute very quickly, or it will mess up the timer synchronisation.
     The only use I can see for this function is for palette
     manipulations, because triple buffering can be done with the
     request_scroll() function, and the retrace_count variable can be
     used for timing your code. If you want to alter the palette in the
     retrace_proc you should use the inline _set_color() function
     rather than the regular set_color() or set_palette(), and you
     shouldn't try to alter more than two or three palette entries in a
     single retrace.

See also:
*Note timer_simulate_retrace::.
*Note timer_is_using_retrace::.
*Note retrace_count::.
*Note _set_color::.
*Note ex3buf::.

File: allegro.info,  Node: rest,  Next: rest_callback,  Prev: retrace_proc,  Up: Timer

6.14 rest
=========

void rest(long time);
     Once Allegro has taken over the timer the standard delay()
     function will no longer work, so you should use this routine
     instead. The time is given in milliseconds.

See also:
*Note install_timer::.
*Note rest_callback::.
*Note exsample::.
*Note extimer::.
*Note exunicod::.

File: allegro.info,  Node: rest_callback,  Next: install_keyboard,  Prev: rest,  Up: Timer

6.15 rest_callback
==================

void rest_callback(long time, void (*callback)())
     Like rest(), but continually calls the specified function while it
     is waiting for the required time to elapse.

See also:
*Note install_timer::.
*Note rest::.

File: allegro.info,  Node: Keyboard,  Next: Joystick,  Prev: Timer,  Up: Top

7 Keyboard routines
*******************

The Allegro keyboard handler provides both buffered input and a set of
flags storing the current state of each key. Note that it is not
possible to correctly detect every combination of keys, due to the
design of the PC keyboard. Up to two or three keys at a time will work
fine, but if you press more than that the extras are likely to be
ignored (exactly which combinations are possible seems to vary from one
keyboard to another).

* Menu:

* install_keyboard::
* remove_keyboard::
* install_keyboard_hooks::
* poll_keyboard::
* keyboard_needs_poll::
* key::
* key_shifts::
* keypressed::
* readkey::
* ureadkey::
* scancode_to_ascii::
* simulate_keypress::
* simulate_ukeypress::
* keyboard_callback::
* keyboard_ucallback::
* keyboard_lowlevel_callback::
* set_leds::
* set_keyboard_rate::
* clear_keybuf::
* three_finger_flag::
* key_led_flag::


File: allegro.info,  Node: install_keyboard,  Next: remove_keyboard,  Prev: rest_callback,  Up: Keyboard

7.1 install_keyboard
====================

int install_keyboard();
     Installs the Allegro keyboard interrupt handler. You must call this
     before using any of the keyboard input routines. Once you have set
     up the Allegro handler, you can no longer use operating system
     calls or C library functions to access the keyboard. Returns zero
     on success, or a negative number on failure (but you may decide
     not to check the return value as this function is very unlikely to
     fail). Note that on some platforms the keyboard won't work unless
     you have set a graphics mode, even if this function returns zero
     before calling set_gfx_mode.

See also:
*Note remove_keyboard::.
*Note poll_keyboard::.
*Note key::.
*Note keypressed::.
*Note readkey::.
*Note ureadkey::.
*Note keyboard_callback::.
*Note keyboard_ucallback::.
*Note keyboard_lowlevel_callback::.
*Note three_finger_flag::.
*Note key_led_flag::.
*Note set_leds::.
*Note set_keyboard_rate::.
*Note set_gfx_mode::.
*Note Standard config variables::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: remove_keyboard,  Next: install_keyboard_hooks,  Prev: install_keyboard,  Up: Keyboard

7.2 remove_keyboard
===================

void remove_keyboard();
     Removes the keyboard handler, returning control to the operating
     system.  You don't normally need to bother calling this, because
     allegro_exit() will do it for you.

See also:
*Note install_keyboard::.
*Note allegro_exit::.

File: allegro.info,  Node: install_keyboard_hooks,  Next: poll_keyboard,  Prev: remove_keyboard,  Up: Keyboard

7.3 install_keyboard_hooks
==========================

void install_keyboard_hooks(int (*keypressed)(), int (*readkey)());
     You should only use this function if you *aren't* using the rest
     of the keyboard handler. It should be called in the place of
     install_keyboard(), and lets you provide callback routines to
     detect and read keypresses, which will be used by the main
     keypressed() and readkey() functions. This can be useful if you
     want to use Allegro's GUI code with a custom keyboard handler, as
     it provides a way for the GUI to get keyboard input from your own
     code, bypassing the normal Allegro input system.

See also:
*Note install_keyboard::.
*Note keypressed::.
*Note readkey::.

File: allegro.info,  Node: poll_keyboard,  Next: keyboard_needs_poll,  Prev: install_keyboard_hooks,  Up: Keyboard

7.4 poll_keyboard
=================

int poll_keyboard();
     Wherever possible, Allegro will read the keyboard input
     asynchronously (ie. from inside an interrupt handler), but on some
     platforms that may not be possible, in which case you must call
     this routine at regular intervals to update the keyboard state
     variables. To help you test your keyboard polling code even if you
     are programming on a platform that doesn't require it, after the
     first time that you call this function Allegro will switch into
     polling mode, so from that point onwards you will have to call
     this routine in order to get any keyboard input at all, regardless
     of whether the current driver actually needs to be polled or not.
     The keypressed(), readkey(), and ureadkey() functions call
     poll_keyboard() automatically, so you only need to use this
     function when accessing the key[] array and key_shifts variable.
     Returns zero on success, or a negative number on failure (ie. no
     keyboard driver installed).

See also:
*Note keyboard_needs_poll::.
*Note install_keyboard::.
*Note key::.
*Note key_shifts::.
*Note excamera::.
*Note exsample::.
*Note exstars::.

File: allegro.info,  Node: keyboard_needs_poll,  Next: key,  Prev: poll_keyboard,  Up: Keyboard

7.5 keyboard_needs_poll
=======================

int keyboard_needs_poll();
     Returns TRUE if the current keyboard driver is operating in
     polling mode.

See also:
*Note poll_keyboard::.
*Note install_keyboard::.
*Note key::.

File: allegro.info,  Node: key,  Next: key_shifts,  Prev: keyboard_needs_poll,  Up: Keyboard

7.6 key
=======

extern volatile char key[KEY_MAX];
     Array of flags indicating the state of each key, ordered by
     scancode.  Wherever possible these values will be updated
     asynchronously, but if keyboard_needs_poll() returns TRUE, you
     must manually call poll_keyboard() to update them with the current
     input state. The scancodes are defined in allegro/keyboard.h as a
     series of KEY_* constants (and are also listed below). For
     example, you could write:

          if (key[KEY_SPACE])
             printf("Space is pressed\n");

     Note that the array is supposed to represent which keys are
     physically held down and which keys are not, so it is semantically
     read-only.

     These are the keyboard scancodes:

          KEY_A ... KEY_Z,
          KEY_0 ... KEY_9,
          KEY_0_PAD ... KEY_9_PAD,
          KEY_F1 ... KEY_F12,

          KEY_ESC, KEY_TILDE, KEY_MINUS, KEY_EQUALS,
          KEY_BACKSPACE, KEY_TAB, KEY_OPENBRACE, KEY_CLOSEBRACE,
          KEY_ENTER, KEY_COLON, KEY_QUOTE, KEY_BACKSLASH,
          KEY_BACKSLASH2, KEY_COMMA, KEY_STOP, KEY_SLASH,
          KEY_SPACE,

          KEY_INSERT, KEY_DEL, KEY_HOME, KEY_END, KEY_PGUP,
          KEY_PGDN, KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN,

          KEY_SLASH_PAD, KEY_ASTERISK, KEY_MINUS_PAD,
          KEY_PLUS_PAD, KEY_DEL_PAD, KEY_ENTER_PAD,

          KEY_PRTSCR, KEY_PAUSE,

          KEY_ABNT_C1, KEY_YEN, KEY_KANA, KEY_CONVERT, KEY_NOCONVERT,
          KEY_AT, KEY_CIRCUMFLEX, KEY_COLON2, KEY_KANJI,

          KEY_LSHIFT, KEY_RSHIFT,
          KEY_LCONTROL, KEY_RCONTROL,
          KEY_ALT, KEY_ALTGR,
          KEY_LWIN, KEY_RWIN, KEY_MENU,
          KEY_SCRLOCK, KEY_NUMLOCK, KEY_CAPSLOCK

          KEY_EQUALS_PAD, KEY_BACKQUOTE, KEY_SEMICOLON, KEY_COMMAND

See also:
*Note install_keyboard::.
*Note poll_keyboard::.
*Note key_shifts::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: key_shifts,  Next: keypressed,  Prev: key,  Up: Keyboard

7.7 key_shifts
==============

extern volatile int key_shifts;
     Bitmask containing the current state of shift/ctrl/alt, the special
     Windows keys, and the accent escape characters. Wherever possible
     this value will be updated asynchronously, but if
     keyboard_needs_poll() returns TRUE, you must manually call
     poll_keyboard() to update it with the current input state. This
     can contain any of the flags:

          KB_SHIFT_FLAG
          KB_CTRL_FLAG
          KB_ALT_FLAG
          KB_LWIN_FLAG
          KB_RWIN_FLAG
          KB_MENU_FLAG
          KB_COMMAND_FLAG
          KB_SCROLOCK_FLAG
          KB_NUMLOCK_FLAG
          KB_CAPSLOCK_FLAG
          KB_INALTSEQ_FLAG
          KB_ACCENT1_FLAG
          KB_ACCENT2_FLAG
          KB_ACCENT3_FLAG
          KB_ACCENT4_FLAG

See also:
*Note install_keyboard::.
*Note poll_keyboard::.
*Note key::.
*Note excamera::.
*Note exkeys::.

File: allegro.info,  Node: keypressed,  Next: readkey,  Prev: key_shifts,  Up: Keyboard

7.8 keypressed
==============

int keypressed();
     Returns TRUE if there are keypresses waiting in the input buffer.
     This is equivalent to the libc kbhit() function.

See also:
*Note install_keyboard::.
*Note readkey::.
*Note ureadkey::.
*Note clear_keybuf::.
*Note simulate_keypress::.
*Note simulate_ukeypress::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: readkey,  Next: ureadkey,  Prev: keypressed,  Up: Keyboard

7.9 readkey
===========

int readkey();
     Returns the next character from the keyboard buffer, in ASCII
     format. If the buffer is empty, it waits until a key is pressed.
     The low byte of the return value contains the ASCII code of the
     key, and the high byte the scancode. The scancode remains the same
     whatever the state of the shift, ctrl and alt keys, while the
     ASCII code is affected by shift and ctrl in the normal way (shift
     changes case, ctrl+letter gives the position of that letter in the
     alphabet, eg. ctrl+A = 1, ctrl+B = 2, etc). Pressing alt+key
     returns only the scancode, with a zero ASCII code in the low byte.
     For example:

          if ((readkey() & 0xff) == 'd')         // by ASCII code
             printf("You pressed 'd'\n");

          if ((readkey() >> 8) == KEY_SPACE)     // by scancode
             printf("You pressed Space\n");

          if ((readkey() & 0xff) == 3)           // ctrl+letter
             printf("You pressed Control+C\n");

          if (readkey() == (KEY_X << 8))         // alt+letter
             printf("You pressed Alt+X\n");

     This function cannot return character values greater than 255. If
     you need to read Unicode input, use ureadkey() instead.

See also:
*Note install_keyboard::.
*Note ureadkey::.
*Note keypressed::.
*Note clear_keybuf::.
*Note simulate_keypress::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: ureadkey,  Next: scancode_to_ascii,  Prev: readkey,  Up: Keyboard

7.10 ureadkey
=============

int ureadkey(int *scancode);
     Returns the next character from the keyboard buffer, in Unicode
     format.  If the buffer is empty, it waits until a key is pressed.
     The return value contains the Unicode value of the key, and if not
     NULL, the pointer argument will be set to the scancode. Unlike
     readkey(), this function is able to return character values
     greater than 255.

See also:
*Note install_keyboard::.
*Note readkey::.
*Note keypressed::.
*Note clear_keybuf::.
*Note simulate_ukeypress::.
*Note exkeys::.

File: allegro.info,  Node: scancode_to_ascii,  Next: simulate_keypress,  Prev: ureadkey,  Up: Keyboard

7.11 scancode_to_ascii
======================

int scancode_to_ascii(int scancode);
     Converts the given scancode to an ASCII character for that key,
     returning the unshifted uncapslocked result of pressing the key,
     or zero if the key isn't a character-generating key or the lookup
     can't be done.



File: allegro.info,  Node: simulate_keypress,  Next: simulate_ukeypress,  Prev: scancode_to_ascii,  Up: Keyboard

7.12 simulate_keypress
======================

void simulate_keypress(int key);
     Stuffs a key into the keyboard buffer, just as if the user had
     pressed it. The parameter is in the same format returned by
     readkey().

See also:
*Note install_keyboard::.
*Note simulate_ukeypress::.
*Note keypressed::.
*Note readkey::.

File: allegro.info,  Node: simulate_ukeypress,  Next: keyboard_callback,  Prev: simulate_keypress,  Up: Keyboard

7.13 simulate_ukeypress
=======================

void simulate_ukeypress(int key, int scancode);
     Stuffs a key into the keyboard buffer, just as if the user had
     pressed it. The parameter is in the same format returned by
     ureadkey().

See also:
*Note install_keyboard::.
*Note simulate_keypress::.
*Note keypressed::.
*Note ureadkey::.

File: allegro.info,  Node: keyboard_callback,  Next: keyboard_ucallback,  Prev: simulate_ukeypress,  Up: Keyboard

7.14 keyboard_callback
======================

extern int (*keyboard_callback)(int key);
     If set, this function is called by the keyboard handler in
     response to every keypress. It is passed a copy of the value that
     is about to be added into the input buffer, and can either return
     this value unchanged, return zero to cause the key to be ignored,
     or return a modified value to change what readkey() will later
     return. This routine executes in an interrupt context, so it must
     be in locked memory.

See also:
*Note install_keyboard::.
*Note readkey::.
*Note ureadkey::.
*Note keyboard_ucallback::.
*Note keyboard_lowlevel_callback::.

File: allegro.info,  Node: keyboard_ucallback,  Next: keyboard_lowlevel_callback,  Prev: keyboard_callback,  Up: Keyboard

7.15 keyboard_ucallback
=======================

extern int (*keyboard_ucallback)(int key, int *scancode);
     Unicode-aware version of keyboard_callback(). If set, this
     function is called by the keyboard handler in response to every
     keypress. It is passed the character value and scancode that are
     about to be added into the input buffer, can modify the scancode
     value, and returns a new or modified key code. If it both sets the
     scancode to zero and returns zero, the keypress will be ignored.
     This routine executes in an interrupt context, so it must be in
     locked memory.

See also:
*Note install_keyboard::.
*Note readkey::.
*Note ureadkey::.
*Note keyboard_callback::.
*Note keyboard_lowlevel_callback::.

File: allegro.info,  Node: keyboard_lowlevel_callback,  Next: set_leds,  Prev: keyboard_ucallback,  Up: Keyboard

7.16 keyboard_lowlevel_callback
===============================

extern void (*keyboard_lowlevel_callback)(int scancode);
     If set, this function is called by the keyboard handler in
     response to every keyboard event, both presses and releases. It
     will be passed a raw keyboard scancode byte, with the top bit
     clear if the key has been pressed or set if it was released. This
     routine executes in an interrupt context, so it must be in locked
     memory.

See also:
*Note install_keyboard::.
*Note keyboard_callback::.
*Note keyboard_ucallback::.

File: allegro.info,  Node: set_leds,  Next: set_keyboard_rate,  Prev: keyboard_lowlevel_callback,  Up: Keyboard

7.17 set_leds
=============

void set_leds(int leds);
     Overrides the state of the keyboard LED indicators. The parameter
     is a bitmask containing any of the values KB_SCROLOCK_FLAG,
     KB_NUMLOCK_FLAG, and KB_CAPSLOCK_FLAG, or -1 to restore the
     default behavior.

See also:
*Note install_keyboard::.
*Note key_led_flag::.

File: allegro.info,  Node: set_keyboard_rate,  Next: clear_keybuf,  Prev: set_leds,  Up: Keyboard

7.18 set_keyboard_rate
======================

void set_keyboard_rate(int delay, int repeat);
     Sets the keyboard repeat rate. Times are given in milliseconds.
     Passing zero times will disable the key repeat.

See also:
*Note install_keyboard::.
*Note readkey::.
*Note ureadkey::.

File: allegro.info,  Node: clear_keybuf,  Next: three_finger_flag,  Prev: set_keyboard_rate,  Up: Keyboard

7.19 clear_keybuf
=================

void clear_keybuf();
     Empties the keyboard buffer.

See also:
*Note install_keyboard::.
*Note keypressed::.
*Note readkey::.
*Note ureadkey::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: three_finger_flag,  Next: key_led_flag,  Prev: clear_keybuf,  Up: Keyboard

7.20 three_finger_flag
======================

extern int three_finger_flag;
     The djgpp keyboard handler provides an 'emergency exit' sequence
     which you can use to kill off your program. If you are running
     under DOS this is the three finger salute, ctrl+alt+del. Most
     multitasking OS's will trap this combination before it reaches the
     Allegro handler, in which case you can use the alternative
     ctrl+alt+end. If you want to disable this behaviour in release
     versions of your program, set this flag to FALSE.

See also:
*Note install_keyboard::.

File: allegro.info,  Node: key_led_flag,  Next: install_joystick,  Prev: three_finger_flag,  Up: Keyboard

7.21 key_led_flag
=================

extern int key_led_flag;
     By default, the capslock, numlock, and scroll-lock keys toggle the
     keyboard LED indicators when they are pressed. If you are using
     these keys for input in your game (eg. capslock to fire) this may
     not be desirable, so you can clear this flag to prevent the LED's
     being updated.

See also:
*Note install_keyboard::.
*Note set_leds::.

File: allegro.info,  Node: Joystick,  Next: Graphics,  Prev: Keyboard,  Up: Top

8 Joystick routines
*******************

* Menu:

* install_joystick::
* remove_joystick::
* poll_joystick::
* num_joysticks::
* joy::
* calibrate_joystick_name::
* calibrate_joystick::
* save_joystick_data::
* load_joystick_data::
* initialise_joystick::


File: allegro.info,  Node: install_joystick,  Next: remove_joystick,  Prev: key_led_flag,  Up: Joystick

8.1 install_joystick
====================

int install_joystick(int type);
     Initialises the joystick, and calibrates the centre position
     value. The type parameter should usually be JOY_TYPE_AUTODETECT,
     or see the platform specific documentation for a list of the
     available drivers. You must call this routine before using any
     other joystick functions, and you should make sure that the
     joystick is in the middle position at the time.  Returns zero on
     success. As soon as you have installed the joystick module, you
     will be able to read the button state and digital (on/off toggle)
     direction information, which may be enough for some games. If you
     want to get full analogue input, though, you need to use the
     calibrate_joystick() functions to measure the exact range of the
     inputs: see below.

See also:
*Note remove_joystick::.
*Note load_joystick_data::.
*Note calibrate_joystick::.
*Note calibrate_joystick_name::.
*Note poll_joystick::.
*Note Standard config variables::.
*Note JOY_TYPE_*/DOS::.
*Note exjoy::.

File: allegro.info,  Node: remove_joystick,  Next: poll_joystick,  Prev: install_joystick,  Up: Joystick

8.2 remove_joystick
===================

void remove_joystick();
     Removes the joystick handler. You don't normally need to bother
     calling this, because allegro_exit() will do it for you.

See also:
*Note install_joystick::.
*Note allegro_exit::.

File: allegro.info,  Node: poll_joystick,  Next: num_joysticks,  Prev: remove_joystick,  Up: Joystick

8.3 poll_joystick
=================

int poll_joystick();
     The joystick is not interrupt driven, so you need to call this
     function every now and again to update the global position values.
     Returns zero on success or a negative number on failure (usually
     because no joystick driver was installed).

See also:
*Note install_joystick::.
*Note joy::.
*Note num_joysticks::.
*Note exjoy::.

File: allegro.info,  Node: num_joysticks,  Next: joy,  Prev: poll_joystick,  Up: Joystick

8.4 num_joysticks
=================

extern int num_joysticks;
     Global variable containing the number of active joystick devices.
     The current drivers support a maximum of four controllers.

See also:
*Note install_joystick::.
*Note joy::.
*Note exjoy::.

File: allegro.info,  Node: joy,  Next: calibrate_joystick_name,  Prev: num_joysticks,  Up: Joystick

8.5 joy
=======

extern JOYSTICK_INFO joy[n];
     Global array of joystick state information, which is updated by the
     poll_joystick() function. Only the first num_joysticks elements
     will contain meaningful information. The JOYSTICK_INFO structure
     is defined as:

          typedef struct JOYSTICK_INFO
          {
             int flags;                       - status flags for this
                                                joystick
             int num_sticks;                  - how many stick inputs?
             int num_buttons;                 - how many buttons?
             JOYSTICK_STICK_INFO stick[n];    - stick state information
             JOYSTICK_BUTTON_INFO button[n];  - button state information
          } JOYSTICK_INFO;

     The button status is stored in the structure:

          typedef struct JOYSTICK_BUTTON_INFO
          {
             int b;                           - boolean on/off flag
             char *name;                      - description of this
                                                button
          } JOYSTICK_BUTTON_INFO;

     You may wish to display the button names as part of an input
     configuration screen to let the user choose what game function
     will be performed by each button, but in simpler situations you
     can safely assume that the first two elements in the button array
     will always be the main trigger controls.

     Each joystick will provide one or more stick inputs, of varying
     types.  These can be digital controls which snap to specific
     positions (eg. a gamepad controller, the coolie hat on a
     Flightstick Pro or Wingman Extreme, or a normal joystick which
     hasn't yet been calibrated), or they can be full analogue inputs
     with a smooth range of motion. Sticks may also have different
     numbers of axis, for example a normal directional control has two,
     but the Flightstick Pro throttle is only a single axis, and it is
     possible that the system could be extended in the future to
     support full 3d controllers. A stick input is described by the
     structure:

          typedef struct JOYSTICK_STICK_INFO
          {
             int flags;                       - status flags for this
                                                input
             int num_axis;                    - how many axis do we
                                                have?
             JOYSTICK_AXIS_INFO axis[n];      - axis state information
             char *name;                      - description of this
                                                input
          } JOYSTICK_STICK_INFO;

     A single joystick may provide several different stick inputs, but
     you can safely assume that the first element in the stick array
     will always be the main directional controller.

     Information about each of the stick axis is stored in the
     substructure:

          typedef struct JOYSTICK_AXIS_INFO
          {
             int pos;                         - analogue axis position
             int d1, d2;                      - digital axis position
             char *name;                      - description of this axis
          } JOYSTICK_AXIS_INFO;

     This provides both analogue input in the pos field (ranging from
     -128 to 128 or from 0 to 255, depending on the type of the
     control), and digital values in the d1 and d2 fields. For example,
     when describing the X-axis position, the pos field will hold the
     horizontal position of the joystick, d1 will be set if it is moved
     left, and d2 will be set if it is moved right. Allegro will fill
     in all these values regardless of whether it is using a digital or
     analogue joystick, emulating the pos field for digital inputs by
     snapping it to the min, middle, and maximum positions, and
     emulating the d1 and d2 values for an analogue stick by comparing
     the current position with the centre point.

     The joystick flags field may contain any combination of the bit
     flags:

     JOYFLAG_DIGITAL
     This control is currently providing digital input.

     JOYFLAG_ANALOGUE
     This control is currently providing analogue input.

     JOYFLAG_CALIB_DIGITAL
     This control will be capable of providing digital input once it has
     been calibrated, but is not doing this at the moment.

     JOYFLAG_CALIB_ANALOGUE
     This control will be capable of providing analogue input once it
     has been calibrated, but is not doing this at the moment.

     JOYFLAG_CALIBRATE
     Indicates that this control needs to be calibrated. Many devices
     require multiple calibration steps, so you should call the
     calibrate_joystick() function from a loop until this flag is
     cleared.

     JOYFLAG_SIGNED
     Indicates that the analogue axis position is in signed format,
     ranging from -128 to 128. This is the case for all 2d directional
     controls.

     JOYFLAG_UNSIGNED
     Indicates that the analogue axis position is in unsigned format,
     ranging from 0 to 255. This is the case for all 1d throttle
     controls.

     Note for people who spell funny: in case you don't like having to
     type "analogue", there are some #define aliases in
     allegro/joystick.h that will allow you to write "analog" instead.

See also:
*Note install_joystick::.
*Note poll_joystick::.
*Note num_joysticks::.
*Note calibrate_joystick::.
*Note calibrate_joystick_name::.
*Note exjoy::.
*Note JOYSTICK_INFO::.

File: allegro.info,  Node: calibrate_joystick_name,  Next: calibrate_joystick,  Prev: joy,  Up: Joystick

8.6 calibrate_joystick_name
===========================

const char *calibrate_joystick_name(int n);
     Returns a text description for the next type of calibration that
     will be done on the specified joystick, or NULL if no more
     calibration is required.

See also:
*Note install_joystick::.
*Note calibrate_joystick::.
*Note joy::.
*Note num_joysticks::.
*Note exjoy::.

File: allegro.info,  Node: calibrate_joystick,  Next: save_joystick_data,  Prev: calibrate_joystick_name,  Up: Joystick

8.7 calibrate_joystick
======================

int calibrate_joystick(int n);
     Most joysticks need to be calibrated before they can provide full
     analogue input. This function performs the next operation in the
     calibration series for the specified stick, assuming that the
     joystick has been positioned in the manner described by a previous
     call to calibrate_joystick_name(), returning zero on success. For
     example, a simple routine to fully calibrate all the joysticks
     might look like:

          int i;

          for (i=0; i<;num_joysticks; i++) {
             while (joy[i].flags & JOYFLAG_CALIBRATE) {
                char *msg = calibrate_joystick_name(i);
                printf("%s, and press a key\n", msg);
                readkey();
                if (calibrate_joystick(i) != 0) {
                   printf("oops!\n");
                   exit(1);
                }
             }
          }

See also:
*Note install_joystick::.
*Note calibrate_joystick_name::.
*Note joy::.
*Note num_joysticks::.
*Note exjoy::.

File: allegro.info,  Node: save_joystick_data,  Next: load_joystick_data,  Prev: calibrate_joystick,  Up: Joystick

8.8 save_joystick_data
======================

int save_joystick_data(const char *filename);
     After all the headache of calibrating the joystick, you may not
     want to make your poor users repeat the process every time they
     run your program.  Call this function to save the joystick
     calibration data into the specified configuration file, from which
     it can later be read by load_joystick_data(). Pass a NULL filename
     to write the data to the currently selected configuration file.
     Returns zero on success.

See also:
*Note load_joystick_data::.
*Note set_config_file::.

File: allegro.info,  Node: load_joystick_data,  Next: initialise_joystick,  Prev: save_joystick_data,  Up: Joystick

8.9 load_joystick_data
======================

int load_joystick_data(const char *filename);
     Restores calibration data previously stored by
     save_joystick_data() or the setup utility. This sets up all
     aspects of the joystick code: you don't even need to call
     install_joystick() if you are using this function. Pass a NULL
     filename to read the data from the currently selected
     configuration file. Returns zero on success: if it fails the
     joystick state is undefined and you must reinitialise it from
     scratch.

See also:
*Note install_joystick::.
*Note save_joystick_data::.
*Note set_config_file::.

File: allegro.info,  Node: initialise_joystick,  Next: set_color_depth,  Prev: load_joystick_data,  Up: Joystick

8.10 initialise_joystick
========================

int initialise_joystick();
     Deprecated. Use install_joystick() instead.

See also:
*Note install_joystick::.

File: allegro.info,  Node: Graphics,  Next: Bitmap,  Prev: Joystick,  Up: Top

9 Graphics modes
****************

* Menu:

* set_color_depth::
* get_color_depth::
* request_refresh_rate::
* get_refresh_rate::
* get_gfx_mode_list::
* destroy_gfx_mode_list::
* set_gfx_mode::
* set_display_switch_mode::
* set_display_switch_callback::
* remove_display_switch_callback::
* get_display_switch_mode::
* gfx_capabilities::
* enable_triple_buffer::
* scroll_screen::
* request_scroll::
* poll_scroll::
* show_video_bitmap::
* request_video_bitmap::
* vsync::


File: allegro.info,  Node: set_color_depth,  Next: get_color_depth,  Prev: initialise_joystick,  Up: Graphics

9.1 set_color_depth
===================

void set_color_depth(int depth);
     Sets the pixel format to be used by subsequent calls to
     set_gfx_mode() and create_bitmap(). Valid depths are 8 (the
     default), 15, 16, 24, and 32 bits.

See also:
*Note get_color_depth::.
*Note set_gfx_mode::.
*Note set_color_conversion::.
*Note makecol::.
*Note getr::.
*Note desktop_color_depth::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: get_color_depth,  Next: request_refresh_rate,  Prev: set_color_depth,  Up: Graphics

9.2 get_color_depth
===================

int get_color_depth(void);
     Returns the current pixel format.

See also:
*Note set_color_depth::.
*Note exrgbhsv::.

File: allegro.info,  Node: request_refresh_rate,  Next: get_refresh_rate,  Prev: get_color_depth,  Up: Graphics

9.3 request_refresh_rate
========================

void request_refresh_rate(int rate);
     Requests that the next call to set_gfx_mode() try to use the
     specified refresh rate, if possible. Not all drivers are able to
     control this at all, and even when they can, not all rates will be
     possible on all hardware, so the actual settings may differ from
     what you requested.  After you call set_gfx_mode(), you can use
     get_refresh_rate() to find out what was actually selected. At the
     moment only the DOS VESA 3.0, X DGA 2.0 and some Windows DirectX
     drivers support this function. The speed is specified in Hz, eg.
     60, 70. To return to the normal default selection, pass a rate
     value of zero.

See also:
*Note set_gfx_mode::.
*Note get_refresh_rate::.

File: allegro.info,  Node: get_refresh_rate,  Next: get_gfx_mode_list,  Prev: request_refresh_rate,  Up: Graphics

9.4 get_refresh_rate
====================

int get_refresh_rate(void);
     Returns the current refresh rate, if known (not all drivers are
     able to report this information). Returns zero if the actual rate
     is unknown.

See also:
*Note request_refresh_rate::.

File: allegro.info,  Node: get_gfx_mode_list,  Next: destroy_gfx_mode_list,  Prev: get_refresh_rate,  Up: Graphics

9.5 get_gfx_mode_list
=====================

GFX_MODE_LIST *get_gfx_mode_list(int card);
     Attempts to create a list of all the supported video modes for a
     certain graphics driver. This function returns a pointer to a list
     structure of the type GFX_MODE_LIST which has the following
     definition:

          typedef struct GFX_MODE_LIST {
             int num_modes;
             GFX_MODE *mode;
          } GFX_MODE_LIST;

     If this function returns NULL, it means the call failed. The mode
     entry points to the actual list of video modes.

          typedef struct GFX_MODE {
             int width, height, bpp;
          } GFX_MODE;

     This list is terminated with an { 0, 0, 0 } entry.

     Note that the card parameter must refer to a _real_ driver. This
     function fails if you pass GFX_SAFE, GFX_AUTODETECT, or any other
     "magic" driver.

See also:
*Note destroy_gfx_mode_list::.
*Note set_gfx_mode::.
*Note set_color_depth::.
*Note GFX_MODE_LIST::.

File: allegro.info,  Node: destroy_gfx_mode_list,  Next: set_gfx_mode,  Prev: get_gfx_mode_list,  Up: Graphics

9.6 destroy_gfx_mode_list
=========================

void destroy_gfx_mode_list(GFX_MODE_LIST *mode_list);
     Removes the mode list created by get_gfx_mode_list() from memory.

See also:
*Note get_gfx_mode_list::.
*Note set_gfx_mode::.
*Note set_color_depth::.
*Note GFX_MODE_LIST::.

File: allegro.info,  Node: set_gfx_mode,  Next: set_display_switch_mode,  Prev: destroy_gfx_mode_list,  Up: Graphics

9.7 set_gfx_mode
================

int set_gfx_mode(int card, int w, int h, int v_w, int v_h);
     Switches into graphics mode. The card parameter should usually be
     GFX_AUTODETECT, GFX_AUTODETECT_FULLSCREEN or
     GFX_AUTODETECT_WINDOWED, or see the platform specific
     documentation for a list of the available drivers. The w and h
     parameters specify what screen resolution you want.

     The v_w and v_h parameters specify the minimum virtual screen
     size, in case you need a large virtual screen for hardware
     scrolling or page flipping. You should set them to zero if you
     don't care about the virtual screen size. Virtual screens can
     cause a lot of confusion, but they are really quite simple.
     Warning: patronising explanation coming up, so you may wish to
     skip the rest of this paragraph :-) Think of video memory as a
     rectangular piece of paper which is being viewed through a small
     hole (your monitor) in a bit of cardboard. Since the paper is
     bigger than the hole you can only see part of it at any one time,
     but by sliding the cardboard around you can alter which portion of
     the image is visible. You could just leave the hole in one
     position and ignore the parts of video memory that aren't visible,
     but you can get all sorts of useful effects by sliding the screen
     window around, or by drawing images in a hidden part of video
     memory and then flipping across to display them.

     For example, you could select a 640x480 mode in which the monitor
     acts as a window onto a 1024x1024 virtual screen, and then move
     the visible screen around in this larger area. Initially, with the
     visible screen positioned at the top left corner of video memory,
     this setup would look like:

          (0,0)------------(640,0)----(1024,0)
            |                  |           |
            |  visible screen  |           |
            |                  |           |
          (0,480)----------(640,480)       |
            |                              |
            |   the rest of video memory   |
            |                              |
          (0,1024)--------------------(1024,1024)

     What's that? You are viewing this with a proportional font? Hehehe.

     When you call set_gfx_mode(), the v_w and v_h parameters represent
     the minimum size of virtual screen that is acceptable for your
     program. The range of possible sizes is usually very restricted,
     and Allegro is likely to end up creating a virtual screen much
     larger than the one you request.  On an SVGA card with one
     megabyte of vram you can count on getting a 1024x1024 virtual
     screen (256 colors) or 1024x512 (15 or 16 bpp), and with 512k vram
     you can get 1024x512 (256 colors). Other sizes may or may not be
     possible: don't assume that they will work. In mode-X the virtual
     width can be any multiple of eight greater than or equal to the
     physical screen width, and the virtual height will be set
     accordingly (the VGA has 256k of vram, so the virtual height will
     be 256*1024/virtual_width).

     Currently, using a big virtual screen for page flipping is
     considered bad practice.  There are platforms which don't support
     virtual screens bigger than the physical screen but can create
     different video pages to flip back and forth. This means that, if
     you want page flipping and aren't going to use hardware scrolling,
     you should call set_gfx_mode() with (0,0) as the virtual screen
     size and later create the different video pages with
     create_video_bitmap(). Otherwise your program will be limited to
     the platforms supporting hardware scrolling.

     After you select a graphics mode, the physical and virtual screen
     sizes can be checked with the macros SCREEN_W, SCREEN_H,
     VIRTUAL_W, and VIRTUAL_H.

     If Allegro is unable to select an appropriate mode, set_gfx_mode()
     returns a negative number and stores a description of the problem
     in allegro_error. Otherwise it returns zero.

     As a special case, if you use the magic driver code GFX_SAFE,
     Allegro will guarantee that the mode will always be set correctly.
     It will try to select the resolution that you request, and if that
     fails, it will fall back upon whatever mode is known to be
     reliable on the current platform (this is 320x200 VGA mode under
     DOS, a 640x480 resolution under Windows, the actual framebuffer's
     resolution under Linux if it's supported, etc).  If it absolutely
     cannot set any graphics mode at all, it will return negative as
     usual, meaning that there's no possible video output on the
     machine, and that you should abort your program immediately,
     possibly after notifying this to the user with allegro_message.
     This fake driver is useful for situations where you just want to
     get into some kind of workable display mode, and can't be bothered
     with trying multiple different resolutions and doing all the error
     checking yourself. Note however, that after a successful call to
     set_gfx_mode with this driver, you cannot make any assumptions
     about the width, height or color depth of the screen: your code
     will have to deal with this little detail.

     Finally, GFX_TEXT is another magic driver which usually closes any
     previously opened graphics mode, making you unable to use the
     global variable screen, and in those environments that have text
     modes, sets one previously used or the closest match to that
     (usually 80x25). With this driver the size parameters of
     set_gfx_mode don't mean anything, so you can leave them all to
     zero or any other number you prefer.

See also:
*Note set_color_depth::.
*Note request_refresh_rate::.
*Note screen::.
*Note gfx_capabilities::.
*Note allegro_error::.
*Note Standard config variables::.
*Note GFX_*/DOS::.
*Note GFX_*/Windows::.
*Note GFX_*/X::.
*Note GFX_*/Linux::.
*Note GFX_*/BeOS::.
*Note GFX_*/MacOSX::.
*Note create_video_bitmap::.
*Note get_desktop_resolution::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: set_display_switch_mode,  Next: set_display_switch_callback,  Prev: set_gfx_mode,  Up: Graphics

9.8 set_display_switch_mode
===========================

int set_display_switch_mode(int mode);
     Sets how the program should handle being switched into the
     background, if the user tabs away from it. Returns 0 and
     invalidates all callbacks registered with
     set_display_switch_callback() on success. Not all of the possible
     modes will be supported by every graphics driver on every
     platform: you must call this routine after initializing the
     graphics driver and if you request a mode that isn't currently
     possible, it will return -1. The available modes are:

        * SWITCH_NONE
          Disables switching. This is the default in single-tasking
          systems like DOS. It may be supported on other platforms, but
          you should use it with caution, because your users won't be
          impressed if they want to tab away from your program, but you
          don't let them!

        * SWITCH_PAUSE
          Pauses the program whenever it is in the background.
          Execution will be resumed as soon as the user switches back
          to it. This is the default in most fullscreen multitasking
          environments, for example the Linux console, but not under
          Windows.

        * SWITCH_AMNESIA
          Like SWITCH_PAUSE, but this mode doesn't bother to remember
          the contents of video memory, so the screen, and any video
          bitmaps that you have created, will be erased after the user
          switches away and then back to your program. This is not a
          terribly useful mode to have, but it is the default for the
          fullscreen drivers under Windows because DirectDraw is too
          dumb to implement anything better.

        * SWITCH_BACKGROUND
          The program will carry on running in the background, with the
          screen bitmap temporarily being pointed at a memory buffer
          for the fullscreen drivers. You must take special care when
          using this mode, because bad things will happen if the screen
          bitmap gets changed around when your program isn't expecting
          it (see below).

        * SWITCH_BACKAMNESIA
          Like SWITCH_BACKGROUND, but this mode doesn't bother to
          remember the contents of video memory (see SWITCH_AMNESIA).
          It is again the only mode supported by the fullscreen drivers
          under Windows that lets the program keep running in the
          background.

     Note that you should be very careful when you are using graphics
     routines in the switching context: you must always call
     acquire_screen() before the start of any drawing code onto the
     screen and not release it until you are completely finished,
     because the automatic locking mechanism may not be good enough to
     work when the program runs in the background or has just been
     raised in the foreground.

See also:
*Note set_display_switch_callback::.
*Note get_display_switch_mode::.
*Note exswitch::.

File: allegro.info,  Node: set_display_switch_callback,  Next: remove_display_switch_callback,  Prev: set_display_switch_mode,  Up: Graphics

9.9 set_display_switch_callback
===============================

int set_display_switch_callback(int dir, void (*cb)());
     Installs a notification callback for the switching mode that was
     previously selected by calling set_display_switch_mode(). The
     direction parameter can either be SWITCH_IN or SWITCH_OUT,
     depending whether you want to be notified about switches away from
     your program or back to your program. You can sometimes install
     callbacks for both directions at the same time, but not every
     platform supports this, so this function may return -1 if your
     request is impossible. You can install several switch callbacks at
     the same time.

See also:
*Note remove_display_switch_callback::.
*Note set_display_switch_mode::.
*Note exswitch::.

File: allegro.info,  Node: remove_display_switch_callback,  Next: get_display_switch_mode,  Prev: set_display_switch_callback,  Up: Graphics

9.10 remove_display_switch_callback
===================================

void remove_display_switch_callback(void (*cb)());
     Removes a notification callback that was previously installed by
     calling set_display_switch_callback(). All the callbacks will
     automatically be removed when you call set_display_switch_mode().

See also:
*Note set_display_switch_callback::.

File: allegro.info,  Node: get_display_switch_mode,  Next: gfx_capabilities,  Prev: remove_display_switch_callback,  Up: Graphics

9.11 get_display_switch_mode
============================

int get_display_switch_mode();
     Returns the current display switching mode, in the same format
     passed to set_display_switch_mode().

See also:
*Note set_display_switch_mode::.
*Note exswitch::.

File: allegro.info,  Node: gfx_capabilities,  Next: enable_triple_buffer,  Prev: get_display_switch_mode,  Up: Graphics

9.12 gfx_capabilities
=====================

extern int gfx_capabilities;
     Bitfield describing the capabilities of the current graphics
     driver and video hardware. This may contain combination any of the
     flags:

     GFX_CAN_SCROLL:
     Indicates that the scroll_screen() function may be used with this
     driver.

     GFX_CAN_TRIPLE_BUFFER:
     Indicates that the request_scroll() and poll_scroll() functions
     may be used with this driver. If this flag is not set, it is
     possible that the enable_triple_buffer() function may be able to
     activate it.

     GFX_HW_CURSOR:
     Indicates that a hardware mouse cursor is in use. When this flag is
     set, it is safe to draw onto the screen without hiding the mouse
     pointer first. Note that not every cursor graphic can be
     implemented in hardware: in particular VBE/AF only supports
     2-color images up to 32x32 in size, where the second color is an
     exact inverse of the first. This means that Allegro may need to
     switch between hardware and software cursors at any point during
     the execution of your program, so you should not assume that this
     flag will remain constant for long periods of time. It only tells
     you whether a hardware cursor is in use at the current time, and
     may change whenever you hide/redisplay the pointer.

     GFX_HW_HLINE:
     Indicates that the normal opaque version of the hline() function is
     implemented using a hardware accelerator. This will improve the
     performance not only of hline() itself, but also of many other
     functions that use it as a workhorse, for example circlefill(),
     triangle(), and floodfill().

     GFX_HW_HLINE_XOR:
     Indicates that the XOR version of the hline() function, and any
     other functions that use it as a workhorse, are implemented using
     a hardware accelerator.

     GFX_HW_HLINE_SOLID_PATTERN:
     Indicates that the solid and masked pattern modes of the hline()
     function, and any other functions that use it as a workhorse, are
     implemented using a hardware accelerator (see note below).

     GFX_HW_HLINE_COPY_PATTERN:
     Indicates that the copy pattern mode of the hline() function, and
     any other functions that use it as a workhorse, are implemented
     using a hardware accelerator (see note below).

     GFX_HW_FILL:
     Indicates that the opaque version of the rectfill() function, the
     clear_bitmap() routine, and clear_to_color(), are implemented
     using a hardware accelerator.

     GFX_HW_FILL_XOR:
     Indicates that the XOR version of the rectfill() function is
     implemented using a hardware accelerator.

     GFX_HW_FILL_SOLID_PATTERN:
     Indicates that the solid and masked pattern modes of the rectfill()
     function are implemented using a hardware accelerator (see note
     below).

     GFX_HW_FILL_COPY_PATTERN:
     Indicates that the copy pattern mode of the rectfill() function is
     implemented using a hardware accelerator (see note below).

     GFX_HW_LINE:
     Indicates that the opaque mode line() and vline() functions are
     implemented using a hardware accelerator.

     GFX_HW_LINE_XOR:
     Indicates that the XOR version of the line() and vline() functions
     are implemented using a hardware accelerator.

     GFX_HW_TRIANGLE:
     Indicates that the opaque mode triangle() function is implemented
     using a hardware accelerator.

     GFX_HW_TRIANGLE_XOR:
     Indicates that the XOR version of the triangle() function is
     implemented using a hardware accelerator.

     GFX_HW_GLYPH:
     Indicates that monochrome character expansion (for text drawing) is
     implemented using a hardware accelerator.

     GFX_HW_VRAM_BLIT:
     Indicates that blitting from one part of the screen to another is
     implemented using a hardware accelerator. If this flag is set,
     blitting within the video memory will almost certainly be the
     fastest possible way to display an image, so it may be worth
     storing some of your more frequently used graphics in an offscreen
     portion of the video memory.

     GFX_HW_VRAM_BLIT_MASKED:
     Indicates that the masked_blit() routine is capable of a hardware
     accelerated copy from one part of video memory to another, and that
     draw_sprite() will use a hardware copy when given a sub-bitmap of
     the screen or a video memory bitmap as the source image. If this
     flag is set, copying within the video memory will almost certainly
     be the fastest possible way to display an image, so it may be
     worth storing some of your more frequently used sprites in an
     offscreen portion of the video memory.

     Warning: if this flag is not set, masked_blit() and draw_sprite()
     will not work correctly when used with a video memory source
     image! You must only try to use these functions to copy within the
     video memory if they are supported in hardware.

     GFX_HW_MEM_BLIT:
     Indicates that blitting from a memory bitmap onto the screen is
     being accelerated in hardware.

     GFX_HW_MEM_BLIT_MASKED:
     Indicates that the masked_blit() and draw_sprite() functions are
     being accelerated in hardware when the source image is a memory
     bitmap and the destination is the physical screen.

     GFX_HW_SYS_TO_VRAM_BLIT:
     Indicates that blitting from a system bitmap onto the screen is
     being accelerated in hardware. Note that some acceleration may be
     present even if this flag is not set, because system bitmaps can
     benefit from normal memory to screen blitting as well. This flag
     will only be set if system bitmaps have further acceleration above
     and beyond what is provided by GFX_HW_MEM_BLIT.

     GFX_HW_SYS_TO_VRAM_BLIT_MASKED:
     Indicates that the masked_blit() and draw_sprite() functions are
     being accelerated in hardware when the source image is a system
     bitmap and the destination is the physical screen. Note that some
     acceleration may be present even if this flag is not set, because
     system bitmaps can benefit from normal memory to screen blitting
     as well. This flag will only be set if system bitmaps have further
     acceleration above and beyond what is provided by
     GFX_HW_MEM_BLIT_MASKED.

     Note: even if the capabilities information says that patterned
     drawing is supported by the hardware, it will not be possible for
     every size of pattern. VBE/AF only supports patterns up to 8x8 in
     size, so Allegro will fall back on the original non-accelerated
     drawing routines whenever you use a pattern larger than this.

     Note2: these hardware acceleration features will only take effect
     when you are drawing directly onto the screen bitmap, a video
     memory bitmap, or a sub-bitmap thereof. Accelerated hardware is
     most useful in a page flipping or triple buffering setup, and is
     unlikely to make any difference to the classic "draw onto a memory
     bitmap, then blit to the screen" system.

See also:
*Note screen::.
*Note create_video_bitmap::.
*Note scroll_screen::.
*Note request_scroll::.
*Note show_mouse::.
*Note enable_triple_buffer::.
*Note ex3buf::.
*Note exaccel::.
*Note exupdate::.

File: allegro.info,  Node: enable_triple_buffer,  Next: scroll_screen,  Prev: gfx_capabilities,  Up: Graphics

9.13 enable_triple_buffer
=========================

int enable_triple_buffer();
     If the GFX_CAN_TRIPLE_BUFFER bit of the gfx_capabilities field is
     not set, you can attempt to enable it by calling this function. In
     particular if you are running in mode-X in a clean DOS
     environment, this routine will enable the timer retrace simulator,
     which will activate the triple buffering functions. Returns zero
     if triple buffering is enabled.

See also:
*Note gfx_capabilities::.
*Note timer_simulate_retrace::.
*Note request_scroll::.
*Note request_video_bitmap::.
*Note ex3buf::.
*Note exupdate::.

File: allegro.info,  Node: scroll_screen,  Next: request_scroll,  Prev: enable_triple_buffer,  Up: Graphics

9.14 scroll_screen
==================

int scroll_screen(int x, int y);
     Attempts to scroll the hardware screen to display a different part
     of the virtual screen (initially it will be positioned at 0, 0,
     which is the top left corner). Returns zero on success: it may
     fail if the graphics driver can't handle hardware scrolling or the
     virtual screen isn't large enough.  You can use this to move the
     screen display around in a large virtual screen space, or to page
     flip back and forth between two non-overlapping areas of the
     virtual screen. Note that to draw outside the original position in
     the screen bitmap you will have to alter the clipping rectangle:
     see below.

     Mode-X scrolling is reliable and will work on any card.
     Unfortunately most VESA implementations can only handle horizontal
     scrolling in four pixel increments, so smooth horizontal panning
     is impossible in SVGA modes. This is a shame, but I can't see any
     way round it. A significant number of VESA implementations seem to
     be very buggy when it comes to scrolling in truecolor video modes,
     so I suggest you don't depend on this routine working correctly in
     the truecolor resolutions unless you can be sure that SciTech
     Display Doctor is installed.

     Allegro will handle any necessary vertical retrace synchronisation
     when scrolling the screen, so you don't need to call vsync()
     before it. This means that scroll_screen() has the same time delay
     effects as vsync().

See also:
*Note set_gfx_mode::.
*Note show_video_bitmap::.
*Note request_scroll::.
*Note request_video_bitmap::.
*Note exscroll::.

File: allegro.info,  Node: request_scroll,  Next: poll_scroll,  Prev: scroll_screen,  Up: Graphics

9.15 request_scroll
===================

int request_scroll(int x, int y);
     This function is used for triple buffering. It requests a hardware
     scroll to the specified position, but returns immediately rather
     than waiting for a retrace. The scroll will then take place during
     the next vertical retrace, but you can carry on running other code
     in the meantime and use the poll_scroll() routine to detect when
     the flip has actually taken place (see examples/ex3buf.c). Triple
     buffering is only possible on certain hardware: it will work in
     any mode-X resolution if the timer retrace simulator is active
     (but this doesn't work correctly under win95), plus it is
     supported by the VBE 3.0 and VBE/AF drivers for a limited number
     of high-end graphics cards. You can look at the
     GFX_CAN_TRIPLE_BUFFER bit in the gfx_capabilities flag to see if
     it will work with the current driver. This function returns zero
     on success.

See also:
*Note poll_scroll::.
*Note request_video_bitmap::.
*Note gfx_capabilities::.
*Note timer_simulate_retrace::.
*Note scroll_screen::.

File: allegro.info,  Node: poll_scroll,  Next: show_video_bitmap,  Prev: request_scroll,  Up: Graphics

9.16 poll_scroll
================

int poll_scroll();
     This function is used for triple buffering. It checks the status
     of a hardware scroll previously initiated by the request_scroll()
     routine, returning non-zero if it is still waiting to take place,
     and zero if it has already happened.

See also:
*Note request_scroll::.
*Note request_video_bitmap::.
*Note ex3buf::.
*Note exupdate::.

File: allegro.info,  Node: show_video_bitmap,  Next: request_video_bitmap,  Prev: poll_scroll,  Up: Graphics

9.17 show_video_bitmap
======================

int show_video_bitmap(BITMAP *bitmap);
     Attempts to page flip the hardware screen to display the specified
     video bitmap object, which must be the same size as the physical
     screen, and should have been obtained by calling the
     create_video_bitmap() function.  Returns zero on success and
     non-zero on failure.

     Allegro will handle any necessary vertical retrace synchronisation
     when page flipping, so you don't need to call vsync() before it.
     This means that show_video_bitmap() has the same time delay
     effects as vsync().

See also:
*Note scroll_screen::.
*Note create_video_bitmap::.
*Note exaccel::.
*Note exflip::.
*Note exupdate::.
*Note BITMAP::.

File: allegro.info,  Node: request_video_bitmap,  Next: vsync,  Prev: show_video_bitmap,  Up: Graphics

9.18 request_video_bitmap
=========================

int request_video_bitmap(BITMAP *bitmap);
     This function is used for triple buffering. It requests a page
     flip to display the specified video bitmap object, but returns
     immediately rather than waiting for a retrace. The flip will then
     take place during the next vertical retrace, but you can carry on
     running other code in the meantime and use the poll_scroll()
     routine to detect when the flip has actually taken place. Triple
     buffering is only possible on certain hardware: see the comments
     about request_scroll(). Returns zero on success.

See also:
*Note poll_scroll::.
*Note request_scroll::.
*Note gfx_capabilities::.
*Note timer_simulate_retrace::.
*Note create_video_bitmap::.
*Note scroll_screen::.
*Note ex3buf::.
*Note exupdate::.
*Note BITMAP::.

File: allegro.info,  Node: vsync,  Next: screen,  Prev: request_video_bitmap,  Up: Graphics

9.19 vsync
==========

void vsync();
     Waits for a vertical retrace to begin. The retrace happens when the
     electron beam in your monitor has reached the bottom of the screen
     and is moving back to the top ready for another scan. During this
     short period the graphics card isn't sending any data to the
     monitor, so you can do things to it that aren't possible at other
     times, such as altering the palette without causing flickering
     (snow). Allegro will automatically wait for a retrace before
     altering the palette or doing any hardware scrolling, though, so
     you don't normally need to bother with this function.

See also:
*Note set_palette::.
*Note scroll_screen::.
*Note timer_simulate_retrace::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: Bitmap,  Next: Loading,  Prev: Graphics,  Up: Top

10 Bitmap objects
*****************

Once you have selected a graphics mode, you can draw things onto the
display via the 'screen' bitmap. All the Allegro graphics routines draw
onto BITMAP structures, which are areas of memory containing
rectangular images, stored as packed byte arrays (in 8-bit modes one
byte per pixel, in 15- and 16-bit modes sizeof(short) bytes per pixel,
in 24-bit modes 3 bytes per pixel and in 32-bit modes sizeof(long)
bytes per pixel). You can create and manipulate bitmaps in system RAM,
or you can write to the special 'screen' bitmap which represents the
video memory in your graphics card.

For example, to draw a pixel onto the screen you would write:

     putpixel(screen, x, y, color);

Or to implement a double-buffered system:

     BITMAP *bmp = create_bitmap(320, 200);    // make a bitmap in RAM
     clear_bitmap(bmp);                        // zero the memory bitmap
     putpixel(bmp, x, y, color);               // draw onto the memory bitmap
     blit(bmp, screen, 0, 0, 0, 0, 320, 200);  // copy it to the screen

See below for information on how to get direct access to the image
memory in a bitmap.

Allegro supports several different types of bitmaps:

   * The screen bitmap, which represents the hardware video memory.
     Ultimately you have to draw onto this in order for your image to be
     visible. It is destroyed by any subsequent calls to set_gfx_mode().

   * Memory bitmaps, which are located in system RAM and can be used to
     store graphics or as temporary drawing spaces for double buffered
     systems. These can be obtained by calling create_bitmap(),
     load_pcx(), or by loading a grabber datafile.

   * Sub-bitmaps. These share image memory with a parent bitmap (which
     can be the screen, a memory bitmap, or another sub-bitmap), so
     drawing onto them will also change their parent. They can be of
     any size and located anywhere within the parent bitmap, and can
     have their own clipping rectangles, so they are a useful way of
     dividing a bitmap into several smaller units, eg. splitting a
     large virtual screen into multiple sections (see
     examples/exscroll.c).

   * Video memory bitmaps. These are created by the
     create_video_bitmap() function, and are usually implemented as
     sub-bitmaps of the screen object. They must be destroyed by
     destroy_bitmap() before any subsequent calls to set_gfx_mode().

   * System bitmaps. These are created by the create_system_bitmap()
     function, and are a sort of halfway house between memory and video
     bitmaps. They live in system memory, so you aren't limited by the
     amount of video ram in your card, but they are stored in a
     platform-specific format that may enable better hardware
     acceleration than is possible with a normal memory bitmap (see the
     GFX_HW_SYS_TO_VRAM_BLIT and GFX_HW_SYS_TO_VRAM_BLIT_MASKED flags in
     gfx_capabilities). System bitmaps must be accessed in the same way
     as video bitmaps, using the bank switch functions and bmp_write*()
     macros.  Not every platform implements this type of bitmap: if
     they aren't available, create_system_bitmap() will function
     identically to create_bitmap(). They must be destroyed by
     destroy_bitmap() before any subsequent calls to set_gfx_mode().

* Menu:

* screen::
* create_bitmap::
* create_bitmap_ex::
* create_sub_bitmap::
* create_video_bitmap::
* create_system_bitmap::
* destroy_bitmap::
* lock_bitmap::
* bitmap_color_depth::
* bitmap_mask_color::
* is_same_bitmap::
* is_planar_bitmap::
* is_linear_bitmap::
* is_memory_bitmap::
* is_screen_bitmap::
* is_video_bitmap::
* is_system_bitmap::
* is_sub_bitmap::
* acquire_bitmap::
* release_bitmap::
* acquire_screen::
* release_screen::
* set_clip::


File: allegro.info,  Node: screen,  Next: create_bitmap,  Prev: vsync,  Up: Bitmap

10.1 screen
===========

extern BITMAP *screen;
     Global pointer to a bitmap, sized VIRTUAL_W x VIRTUAL_H. This is
     created by set_gfx_mode(), and represents the hardware video
     memory. Only a part of this bitmap will actually be visible, sized
     SCREEN_W x SCREEN_H.  Normally this is the top left corner of the
     larger virtual screen, so you can ignore the extra invisible
     virtual size of the bitmap if you aren't interested in hardware
     scrolling or page flipping. To move the visible window to other
     parts of the screen bitmap, call scroll_screen().  Initially the
     clipping rectangle will be limited to the physical screen size, so
     if you want to draw onto a larger virtual screen space outside
     this rectangle, you will need to adjust the clipping.

     Warning: be very careful when using this pointer at the same time
     as any bitmaps created by the create_video_bitmap() function (see
     the description of this function for more detailed information).

See also:
*Note set_gfx_mode::.
*Note is_screen_bitmap::.
*Note create_video_bitmap::.
*Note scroll_screen::.
*Note Available Allegro examples: Available.
*Note BITMAP::.

File: allegro.info,  Node: create_bitmap,  Next: create_bitmap_ex,  Prev: screen,  Up: Bitmap

10.2 create_bitmap
==================

BITMAP *create_bitmap(int width, int height);
     Creates a memory bitmap sized width by height, and returns a
     pointer to it. The bitmap will have clipping turned on, and the
     clipping rectangle set to the full size of the bitmap. The image
     memory will not be cleared, so it will probably contain garbage:
     you should clear the bitmap before using it. This routine always
     uses the global pixel format, as specified by calling
     set_color_depth().

See also:
*Note create_bitmap_ex::.
*Note create_sub_bitmap::.
*Note create_video_bitmap::.
*Note create_system_bitmap::.
*Note destroy_bitmap::.
*Note set_color_depth::.
*Note is_memory_bitmap::.
*Note Available Allegro examples: Available.
*Note BITMAP::.

File: allegro.info,  Node: create_bitmap_ex,  Next: create_sub_bitmap,  Prev: create_bitmap,  Up: Bitmap

10.3 create_bitmap_ex
=====================

BITMAP *create_bitmap_ex(int color_depth, int width, int height);
     Creates a bitmap in a specific color depth (8, 15, 16, 24 or 32
     bits per pixel).

See also:
*Note create_bitmap::.
*Note create_sub_bitmap::.
*Note create_video_bitmap::.
*Note create_system_bitmap::.
*Note destroy_bitmap::.
*Note is_memory_bitmap::.
*Note ex12bit::.
*Note exlights::.
*Note exrgbhsv::.
*Note extrans::.
*Note BITMAP::.

File: allegro.info,  Node: create_sub_bitmap,  Next: create_video_bitmap,  Prev: create_bitmap_ex,  Up: Bitmap

10.4 create_sub_bitmap
======================

BITMAP *create_sub_bitmap(BITMAP *parent, int x, y, width, height);
     Creates a sub-bitmap, ie. a bitmap sharing drawing memory with a
     pre-existing bitmap, but possibly with a different size and
     clipping settings. When creating a sub-bitmap of the mode-X
     screen, the x position must be a multiple of four. The sub-bitmap
     width and height can extend beyond the right and bottom edges of
     the parent (they will be clipped), but the origin point must lie
     within the parent region.

See also:
*Note create_bitmap::.
*Note create_bitmap_ex::.
*Note destroy_bitmap::.
*Note is_sub_bitmap::.
*Note expat::.
*Note exscroll::.
*Note exswitch::.
*Note BITMAP::.

File: allegro.info,  Node: create_video_bitmap,  Next: create_system_bitmap,  Prev: create_sub_bitmap,  Up: Bitmap

10.5 create_video_bitmap
========================

BITMAP *create_video_bitmap(int width, int height);
     Allocates a video memory bitmap of the specified size, returning a
     pointer to it on success or NULL on failure (ie. if you have run
     out of vram). This can be used to allocate offscreen video memory
     for storing source graphics ready for a hardware accelerated
     blitting operation, or to create multiple video memory pages which
     can then be displayed by calling show_video_bitmap().

     Warning: video memory bitmaps are usually allocated from the same
     space as the screen bitmap, so they may overlap with it; it is
     therefore not a good idea to use the global screen at the same
     time as any surfaces returned by this function.

See also:
*Note create_bitmap::.
*Note create_bitmap_ex::.
*Note create_system_bitmap::.
*Note create_sub_bitmap::.
*Note destroy_bitmap::.
*Note screen::.
*Note show_video_bitmap::.
*Note gfx_capabilities::.
*Note is_video_bitmap::.
*Note ex3buf::.
*Note exaccel::.
*Note exflip::.
*Note exupdate::.
*Note BITMAP::.

File: allegro.info,  Node: create_system_bitmap,  Next: destroy_bitmap,  Prev: create_video_bitmap,  Up: Bitmap

10.6 create_system_bitmap
=========================

BITMAP *create_system_bitmap(int width, int height);
     Allocates a system memory bitmap of the specified size, returning a
     pointer to it on success or NULL on failure.

See also:
*Note create_bitmap::.
*Note create_bitmap_ex::.
*Note create_video_bitmap::.
*Note create_sub_bitmap::.
*Note destroy_bitmap::.
*Note is_system_bitmap::.
*Note exunicod::.
*Note exupdate::.
*Note BITMAP::.

File: allegro.info,  Node: destroy_bitmap,  Next: lock_bitmap,  Prev: create_system_bitmap,  Up: Bitmap

10.7 destroy_bitmap
===================

void destroy_bitmap(BITMAP *bitmap);
     Destroys a memory bitmap, sub-bitmap, video memory bitmap, or
     system bitmap when you are finished with it. See above for the
     restrictions as to when you are allowed to destroy the various
     types of bitmaps.

See also:
*Note create_bitmap::.
*Note load_bitmap::.
*Note Available Allegro examples: Available.
*Note BITMAP::.

File: allegro.info,  Node: lock_bitmap,  Next: bitmap_color_depth,  Prev: destroy_bitmap,  Up: Bitmap

10.8 lock_bitmap
================

void lock_bitmap(BITMAP *bitmap);
     Under DOS, locks all the memory used by a bitmap. You don't
     normally need to call this function unless you are doing very
     weird things in your program.

*Note BITMAP::.

File: allegro.info,  Node: bitmap_color_depth,  Next: bitmap_mask_color,  Prev: lock_bitmap,  Up: Bitmap

10.9 bitmap_color_depth
=======================

int bitmap_color_depth(BITMAP *bmp);
     Returns the color depth of the specified bitmap (8, 15, 16, 24, or
     32).

See also:
*Note set_color_depth::.
*Note bitmap_mask_color::.
*Note ex3d::.
*Note exlights::.
*Note exscn3d::.
*Note exswitch::.
*Note extrans::.
*Note exupdate::.
*Note exzbuf::.
*Note BITMAP::.

File: allegro.info,  Node: bitmap_mask_color,  Next: is_same_bitmap,  Prev: bitmap_color_depth,  Up: Bitmap

10.10 bitmap_mask_color
=======================

int bitmap_mask_color(BITMAP *bmp);
     Returns the mask color for the specified bitmap (the value which is
     skipped when drawing sprites). For 256-color bitmaps this is zero,
     and for truecolor bitmaps it is bright pink (maximum red and blue,
     zero green).

See also:
*Note MASK_COLOR_8::.
*Note set_color_depth::.
*Note bitmap_color_depth::.
*Note ex3d::.
*Note exmouse::.
*Note expat::.
*Note BITMAP::.

File: allegro.info,  Node: is_same_bitmap,  Next: is_planar_bitmap,  Prev: bitmap_mask_color,  Up: Bitmap

10.11 is_same_bitmap
====================

int is_same_bitmap(BITMAP *bmp1, BITMAP *bmp2);
     Returns TRUE if the two bitmaps describe the same drawing surface,
     ie.  the pointers are equal, one is a sub-bitmap of the other, or
     they are both sub-bitmaps of a common parent.

See also:
*Note create_sub_bitmap::.
*Note BITMAP::.

File: allegro.info,  Node: is_planar_bitmap,  Next: is_linear_bitmap,  Prev: is_same_bitmap,  Up: Bitmap

10.12 is_planar_bitmap
======================

int is_planar_bitmap(BITMAP *bmp);
     Returns TRUE if bmp is a planar (mode-X or Xtended mode) screen
     bitmap.

See also:
*Note is_linear_bitmap::.
*Note is_memory_bitmap::.
*Note BITMAP::.

File: allegro.info,  Node: is_linear_bitmap,  Next: is_memory_bitmap,  Prev: is_planar_bitmap,  Up: Bitmap

10.13 is_linear_bitmap
======================

int is_linear_bitmap(BITMAP *bmp);
     Returns TRUE if bmp is a linear bitmap, i.e. a bitmap that can be
     accessed linearly within each scanline (for example a memory
     bitmap, the DOS VGA or SVGA screen, Windows bitmaps, etc). Linear
     bitmaps can be used with the _putpixel(), _getpixel(),
     bmp_write_line(), and bmp_read_line() functions.

     Historically there were only linear and planar bitmaps for
     Allegro, so is_linear_bitmap is actually an alias for
     !is_planar_bitmap.

See also:
*Note is_planar_bitmap::.
*Note is_memory_bitmap::.
*Note BITMAP::.

File: allegro.info,  Node: is_memory_bitmap,  Next: is_screen_bitmap,  Prev: is_linear_bitmap,  Up: Bitmap

10.14 is_memory_bitmap
======================

int is_memory_bitmap(BITMAP *bmp);
     Returns TRUE if bmp is a memory bitmap, ie. it was created by
     calling create_bitmap() or loaded from a grabber datafile or image
     file. Memory bitmaps can be accessed directly via the line
     pointers in the bitmap structure, eg. bmp->line[y][x] = color.

See also:
*Note is_linear_bitmap::.
*Note is_planar_bitmap::.
*Note BITMAP::.

File: allegro.info,  Node: is_screen_bitmap,  Next: is_video_bitmap,  Prev: is_memory_bitmap,  Up: Bitmap

10.15 is_screen_bitmap
======================

int is_screen_bitmap(BITMAP *bmp);
     Returns TRUE if bmp is the screen bitmap, or a sub-bitmap of the
     screen.

See also:
*Note screen::.
*Note create_sub_bitmap::.
*Note BITMAP::.

File: allegro.info,  Node: is_video_bitmap,  Next: is_system_bitmap,  Prev: is_screen_bitmap,  Up: Bitmap

10.16 is_video_bitmap
=====================

int is_video_bitmap(BITMAP *bmp);
     Returns TRUE if bmp is the screen bitmap, a video memory bitmap,
     or a sub-bitmap of either.

See also:
*Note screen::.
*Note create_video_bitmap::.
*Note create_sub_bitmap::.
*Note BITMAP::.

File: allegro.info,  Node: is_system_bitmap,  Next: is_sub_bitmap,  Prev: is_video_bitmap,  Up: Bitmap

10.17 is_system_bitmap
======================

int is_system_bitmap(BITMAP *bmp);
     Returns TRUE if bmp is a system bitmap object, or a sub-bitmap of
     one.

See also:
*Note create_system_bitmap::.
*Note create_sub_bitmap::.
*Note BITMAP::.

File: allegro.info,  Node: is_sub_bitmap,  Next: acquire_bitmap,  Prev: is_system_bitmap,  Up: Bitmap

10.18 is_sub_bitmap
===================

int is_sub_bitmap(BITMAP *bmp);
     Returns TRUE if bmp is a sub-bitmap.

See also:
*Note create_sub_bitmap::.
*Note BITMAP::.

File: allegro.info,  Node: acquire_bitmap,  Next: release_bitmap,  Prev: is_sub_bitmap,  Up: Bitmap

10.19 acquire_bitmap
====================

void acquire_bitmap(BITMAP *bmp);
     Locks the specified video memory bitmap prior to drawing onto it.
     This does not apply to memory bitmaps, and only affects some
     platforms (Windows needs it, DOS does not). These calls are not
     strictly required, because the drawing routines will automatically
     acquire the bitmap before accessing it, but locking a DirectDraw
     surface is very slow, so you will get much better performance if
     you acquire the screen just once at the start of your main redraw
     function, and only release it when the drawing is completely
     finished. Multiple acquire calls may be nested, and the bitmap
     will only be truly released when the lock count returns to zero.
     Be warned that DirectX programs activate a mutex lock whenever a
     surface is locked, which prevents them from getting any input
     messages, so you must be sure to release all your bitmaps before
     using any timer, keyboard, or other non-graphics routines!

See also:
*Note release_bitmap::.
*Note acquire_screen::.
*Note release_screen::.
*Note ex3buf::.
*Note exaccel::.
*Note expat::.
*Note exquat::.
*Note exscroll::.
*Note exswitch::.
*Note exupdate::.
*Note BITMAP::.

File: allegro.info,  Node: release_bitmap,  Next: acquire_screen,  Prev: acquire_bitmap,  Up: Bitmap

10.20 release_bitmap
====================

void release_bitmap(BITMAP *bmp);
     Releases a bitmap that was previously locked by calling
     acquire_bitmap().  If the bitmap was locked multiple times, you
     must release it the same number of times before it will truly be
     unlocked.

See also:
*Note acquire_bitmap::.
*Note acquire_screen::.
*Note release_screen::.
*Note ex3buf::.
*Note exaccel::.
*Note expat::.
*Note exquat::.
*Note exscroll::.
*Note exswitch::.
*Note exupdate::.
*Note BITMAP::.

File: allegro.info,  Node: acquire_screen,  Next: release_screen,  Prev: release_bitmap,  Up: Bitmap

10.21 acquire_screen
====================

void acquire_screen();
     Shortcut version of acquire_bitmap(screen);

See also:
*Note acquire_bitmap::.
*Note release_bitmap::.
*Note release_screen::.
*Note exdbuf::.
*Note exflame::.
*Note exhello::.
*Note exkeys::.
*Note exmem::.
*Note exmouse::.
*Note expal::.
*Note exspline::.
*Note exswitch::.
*Note extruec::.

File: allegro.info,  Node: release_screen,  Next: set_clip,  Prev: acquire_screen,  Up: Bitmap

10.22 release_screen
====================

void release_screen();
     Shortcut version of release_bitmap(screen);

See also:
*Note acquire_bitmap::.
*Note release_bitmap::.
*Note acquire_screen::.
*Note exdbuf::.
*Note exflame::.
*Note exhello::.
*Note exkeys::.
*Note exmem::.
*Note exmouse::.
*Note expal::.
*Note exspline::.
*Note exswitch::.
*Note extruec::.

File: allegro.info,  Node: set_clip,  Next: load_bitmap,  Prev: release_screen,  Up: Bitmap

10.23 set_clip
==============

void set_clip(BITMAP *bitmap, int x1, int y1, int x2, int y2);
     Each bitmap has an associated clipping rectangle, which is the
     area of the image that it is ok to draw on. Nothing will be drawn
     to positions outside this space. Pass the two opposite corners of
     the clipping rectangle: these are inclusive, eg. set_clip(bitmap,
     16, 16, 32, 32) will allow drawing to (16, 16) and (32, 32), but
     not to (15, 15) and (33, 33).  If x1, y1, x2, and y2 are all zero,
     clipping will be turned off, which may slightly speed up some
     drawing operations (usually a negligible difference, although
     every little helps) but will result in your program dying a
     horrible death if you try to draw beyond the edges of the bitmap.

     There's no get_clip like function. To obtain the clipping
     rectangle of an existing bitmap, check the appropiate fields of
     the BITMAP structure holding it.

See also:
*Note ex12bit::.
*Note excamera::.
*Note BITMAP::.

File: allegro.info,  Node: Loading,  Next: Palette,  Prev: Bitmap,  Up: Top

11 Loading image files
**********************

Warning: when using truecolor images, you should always set the graphics
mode before loading any bitmap data! Otherwise the pixel format (RGB or
BGR) will not be known, so the file may be converted wrongly.

* Menu:

* load_bitmap::
* load_bmp::
* load_lbm::
* load_pcx::
* load_tga::
* save_bitmap::
* save_bmp::
* save_pcx::
* save_tga::
* register_bitmap_file_type::
* set_color_conversion::
* get_color_conversion::


File: allegro.info,  Node: load_bitmap,  Next: load_bmp,  Prev: set_clip,  Up: Loading

11.1 load_bitmap
================

BITMAP *load_bitmap(const char *filename, RGB *pal);
     Loads a bitmap from a file, returning a pointer to a bitmap and
     storing the palette data in the specified location, which should
     be an array of 256 RGB structures. You are responsible for
     destroying the bitmap when you are finished with it. Returns NULL
     on error. At present this function supports BMP, LBM, PCX, and TGA
     files, determining the type from the file extension.

     If the file contains a truecolor image, you must set the video
     mode or call set_color_conversion() before loading it. In this
     case, if the destination color depth is 8-bit, the palette will be
     generated by calling generate_optimized_palette() on the bitmap;
     otherwise, the returned palette will be generated by calling
     generate_332_palette().

     The pal argument may be NULL. In this case, the palette data are
     simply not returned. Additionally, if the file is a truecolor
     image and the destination color depth is 8-bit, the color
     conversion process will use the current palette instead of
     generating an optimized one.

See also:
*Note load_bmp::.
*Note load_lbm::.
*Note load_pcx::.
*Note load_tga::.
*Note destroy_bitmap::.
*Note save_bitmap::.
*Note register_bitmap_file_type::.
*Note set_color_depth::.
*Note set_color_conversion::.
*Note generate_optimized_palette::.
*Note generate_332_palette::.
*Note exaccel::.
*Note exalpha::.
*Note exbitmap::.
*Note exblend::.
*Note exconfig::.
*Note exlights::.
*Note exshade::.
*Note extrans::.
*Note exxfade::.
*Note BITMAP::.
*Note RGB::.

File: allegro.info,  Node: load_bmp,  Next: load_lbm,  Prev: load_bitmap,  Up: Loading

11.2 load_bmp
=============

BITMAP *load_bmp(const char *filename, RGB *pal);
     Loads a 256-color or 24-bit truecolor Windows or OS/2 BMP file.

See also:
*Note load_bitmap::.
*Note BITMAP::.
*Note RGB::.

File: allegro.info,  Node: load_lbm,  Next: load_pcx,  Prev: load_bmp,  Up: Loading

11.3 load_lbm
=============

BITMAP *load_lbm(const char *filename, RGB *pal);
     Loads a 256-color IFF ILBM/PBM file.

See also:
*Note load_bitmap::.
*Note BITMAP::.
*Note RGB::.

File: allegro.info,  Node: load_pcx,  Next: load_tga,  Prev: load_lbm,  Up: Loading

11.4 load_pcx
=============

BITMAP *load_pcx(const char *filename, RGB *pal);
     Loads a 256-color or 24-bit truecolor PCX file.

See also:
*Note load_bitmap::.
*Note exscale::.
*Note BITMAP::.
*Note RGB::.

File: allegro.info,  Node: load_tga,  Next: save_bitmap,  Prev: load_pcx,  Up: Loading

11.5 load_tga
=============

BITMAP *load_tga(const char *filename, RGB *pal);
     Loads a 256-color, 15-bit hicolor, 24-bit truecolor, or 32-bit
     truecolor+alpha TGA file.

See also:
*Note load_bitmap::.
*Note BITMAP::.
*Note RGB::.

File: allegro.info,  Node: save_bitmap,  Next: save_bmp,  Prev: load_tga,  Up: Loading

11.6 save_bitmap
================

int save_bitmap(const char *filename, BITMAP *bmp, const RGB *pal);
     Writes a bitmap into a file, using the specified palette, which
     should be an array of 256 RGB structures. Returns non-zero on
     error. The output format is determined from the filename
     extension: at present this function supports BMP, PCX and TGA
     formats.

     Two things to watch out for: on some video cards it may be faster
     to copy the screen to a memory bitmap and save the latter, and if
     you use this to dump the screen into a file you may end up with an
     image much larger than you were expecting, because Allegro often
     creates virtual screens larger than the visible screen. You can
     get around this by using a sub-bitmap to specify which part of the
     screen to save, eg:

          BITMAP *bmp;
          PALETTE pal;

          get_palette(pal);
          bmp = create_sub_bitmap(screen, 0, 0, SCREEN_W, SCREEN_H);
          save_bitmap("dump.pcx", bmp, pal);
          destroy_bitmap(bmp);

See also:
*Note save_bmp::.
*Note save_pcx::.
*Note save_tga::.
*Note load_bitmap::.
*Note register_bitmap_file_type::.
*Note BITMAP::.
*Note RGB::.

File: allegro.info,  Node: save_bmp,  Next: save_pcx,  Prev: save_bitmap,  Up: Loading

11.7 save_bmp
=============

int save_bmp(const char *filename, BITMAP *bmp, const RGB *pal);
     Writes a bitmap into a 256-color or 24-bit truecolor BMP file.

See also:
*Note save_bitmap::.
*Note BITMAP::.
*Note RGB::.

File: allegro.info,  Node: save_pcx,  Next: save_tga,  Prev: save_bmp,  Up: Loading

11.8 save_pcx
=============

int save_pcx(const char *filename, BITMAP *bmp, const RGB *pal);
     Writes a bitmap into a 256-color or 24-bit truecolor PCX file.

See also:
*Note save_bitmap::.
*Note BITMAP::.
*Note RGB::.

File: allegro.info,  Node: save_tga,  Next: register_bitmap_file_type,  Prev: save_pcx,  Up: Loading

11.9 save_tga
=============

int save_tga (const char *filename, BITMAP *bmp, const RGB *pal);
     Writes a bitmap into a 256-color, 15-bit hicolor, 24-bit
     truecolor, or 32-bit truecolor+alpha TGA file.

See also:
*Note save_bitmap::.
*Note BITMAP::.
*Note RGB::.

File: allegro.info,  Node: register_bitmap_file_type,  Next: set_color_conversion,  Prev: save_tga,  Up: Loading

11.10 register_bitmap_file_type
===============================

void register_bitmap_file_type(const char *ext, BITMAP *(*load)(const char *filename, RGB *pal), int (*save)(const char *filename, BITMAP *bmp, const RGB *pal));
     Informs the load_bitmap() and save_bitmap() functions of a new
     file type, providing routines to read and write images in this
     format (either function may be NULL).

See also:
*Note load_bitmap::.
*Note save_bitmap::.
*Note BITMAP::.
*Note RGB::.

File: allegro.info,  Node: set_color_conversion,  Next: get_color_conversion,  Prev: register_bitmap_file_type,  Up: Loading

11.11 set_color_conversion
==========================

void set_color_conversion(int mode);
     Specifies how to convert images between the various color depths
     when reading graphics from external bitmap files or datafiles. The
     mode is a bitmask specifying which types of conversion are
     allowed. If the appropriate bit is set, data will be converted
     into the current pixel format (selected by calling the
     set_color_depth() function), otherwise it will be left in the same
     format as the disk file, leaving you to convert it manually before
     the graphic can be displayed. The default mode is total
     conversion, so that all images will be loaded in the appropriate
     format for the current video mode. Valid bit flags are:

          COLORCONV_NONE                // disable all format
                                        // conversions
          COLORCONV_8_TO_15             // expand 8-bit to 15-bit
          COLORCONV_8_TO_16             // expand 8-bit to 16-bit
          COLORCONV_8_TO_24             // expand 8-bit to 24-bit
          COLORCONV_8_TO_32             // expand 8-bit to 32-bit
          COLORCONV_15_TO_8             // reduce 15-bit to 8-bit
          COLORCONV_15_TO_16            // expand 15-bit to 16-bit
          COLORCONV_15_TO_24            // expand 15-bit to 24-bit
          COLORCONV_15_TO_32            // expand 15-bit to 32-bit
          COLORCONV_16_TO_8             // reduce 16-bit to 8-bit
          COLORCONV_16_TO_15            // reduce 16-bit to 15-bit
          COLORCONV_16_TO_24            // expand 16-bit to 24-bit
          COLORCONV_16_TO_32            // expand 16-bit to 32-bit
          COLORCONV_24_TO_8             // reduce 24-bit to 8-bit
          COLORCONV_24_TO_15            // reduce 24-bit to 15-bit
          COLORCONV_24_TO_16            // reduce 24-bit to 16-bit
          COLORCONV_24_TO_32            // expand 24-bit to 32-bit
          COLORCONV_32_TO_8             // reduce 32-bit RGB to 8-bit
          COLORCONV_32_TO_15            // reduce 32-bit RGB to 15-bit
          COLORCONV_32_TO_16            // reduce 32-bit RGB to 16-bit
          COLORCONV_32_TO_24            // reduce 32-bit RGB to 24-bit
          COLORCONV_32A_TO_8            // reduce 32-bit RGBA to 8-bit
          COLORCONV_32A_TO_15           // reduce 32-bit RGBA to 15-bit
          COLORCONV_32A_TO_16           // reduce 32-bit RGBA to 16-bit
          COLORCONV_32A_TO_24           // reduce 32-bit RGBA to 24-bit
          COLORCONV_DITHER_PAL          // dither when reducing to 8-bit
          COLORCONV_DITHER_HI           // dither when reducing to
                                        // hicolor
          COLORCONV_KEEP_TRANS          // keep original transparency

     For convenience, the following macros can be used to select common
     combinations of these flags:

          COLORCONV_EXPAND_256          // expand 256-color to hi/truecolor
          COLORCONV_REDUCE_TO_256       // reduce hi/truecolor to 256-color
          COLORCONV_EXPAND_15_TO_16     // expand 15-bit hicolor to 16-bit
          COLORCONV_REDUCE_16_TO_15     // reduce 16-bit hicolor to 15-bit
          COLORCONV_EXPAND_HI_TO_TRUE   // expand 15/16-bit to 24/32-bit
          COLORCONV_REDUCE_TRUE_TO_HI   // reduce 24/32-bit to 15/16-bit
          COLORCONV_24_EQUALS_32        // convert between 24- and 32-bit
          COLORCONV_TOTAL               // everything to current format
          COLORCONV_PARTIAL             // convert 15 <-> 16-bit and
                                        // 24 <-> 32-bit
          COLORCONV_MOST                // all but hi/truecolor <-> 256
          COLORCONV_DITHER              // dither during all color reductions

     If you enable the COLORCONV_DITHER flag, dithering will be
     performed whenever truecolor graphics are converted into a hicolor
     or paletted format, including by the blit() function, and any
     automatic conversions that take place while reading graphics from
     disk. This can produce much better looking results, but is
     obviously slower than a direct conversion.

     If you intend using converted bitmaps with functions like
     masked_blit() or draw_sprite(), you should specify the
     COLORCONV_KEEP_TRANS flag. It will ensure that the masked areas in
     the bitmap before and after the conversion stay exactly the same,
     by mapping transparent colors to each other and adjusting colors
     which would be converted to the transparent color otherwise. It
     affects every blit() operation between distinct pixel formats and
     every automatic conversion.

See also:
*Note set_color_depth::.
*Note load_bitmap::.
*Note load_datafile::.
*Note fixup_datafile::.
*Note makecol15_dither::.
*Note get_color_conversion::.
*Note exalpha::.
*Note exblend::.
*Note exdata::.
*Note exexedat::.
*Note exlights::.
*Note exsprite::.
*Note exxfade::.

File: allegro.info,  Node: get_color_conversion,  Next: set_color,  Prev: set_color_conversion,  Up: Loading

11.12 get_color_conversion
==========================

int get_color_conversion();
     Returns the current color conversion mode.

See also:
*Note set_color_conversion::.

File: allegro.info,  Node: Palette,  Next: Truecolor,  Prev: Loading,  Up: Top

12 Palette routines
*******************

All the Allegro drawing functions use integer parameters to represent
colors. In truecolor resolutions these numbers encode the color
directly as a collection of red, green, and blue bits, but in a regular
256-color mode the values are treated as indexes into the current
palette, which is a table listing the red, green and blue intensities
for each of the 256 possible colors.

Palette entries are stored in an RGB structure, which contains red,
green and blue intensities in the VGA hardware format, ranging from
0-63, and is defined as:

     typedef struct RGB
     {
        unsigned char r, g, b;
     } RGB;

It contains an additional field for the purpose of padding but you
should not usually care about it. For example:

     RGB black = { 0,  0,  0  };
     RGB white = { 63, 63, 63 };
     RGB green = { 0,  63, 0  };
     RGB grey  = { 32, 32, 32 };

The type PALETTE is defined to be an array of PAL_SIZE RGB structures,
where PAL_SIZE is a preprocessor constant greater or equal to 256.

You may notice that a lot of the code in Allegro spells 'palette' as
'pallete'. This is because the headers from my old Mark Williams
compiler on the Atari spelt it with two l's, so that is what I'm used
to. Allegro will happily accept either spelling, due to some #defines
in allegro/alcompat.h (which can be turned off by defining the
ALLEGRO_NO_COMPATIBILITY symbol before including Allegro headers).

* Menu:

* set_color::
* _set_color::
* set_palette::
* set_palette_range::
* get_color::
* get_palette::
* get_palette_range::
* fade_interpolate::
* fade_from_range::
* fade_in_range::
* fade_out_range::
* fade_from::
* fade_in::
* fade_out::
* select_palette::
* unselect_palette::
* generate_332_palette::
* generate_optimized_palette::
* default_palette::
* black_palette::
* desktop_palette::


File: allegro.info,  Node: set_color,  Next: _set_color,  Prev: get_color_conversion,  Up: Palette

12.1 set_color
==============

void set_color(int index, const RGB *p);
     Sets the specified palette entry to the specified RGB triplet.
     Unlike the other palette functions this doesn't do any retrace
     synchronisation, so you should call vsync() before it to prevent
     snow problems.

See also:
*Note set_palette::.
*Note get_color::.
*Note _set_color::.
*Note ex12bit::.
*Note exrgbhsv::.
*Note exscroll::.
*Note RGB::.

File: allegro.info,  Node: _set_color,  Next: set_palette,  Prev: set_color,  Up: Palette

12.2 _set_color
===============

void _set_color(int index, const RGB *p);
     This is an inline version of set_color(), intended for use in the
     vertical retrace simulator callback function. It should only be
     used in VGA mode 13h and mode-X, because some of the more recent
     SVGA chipsets aren't VGA compatible (set_color() and set_palette()
     will use VESA calls on these cards, but _set_color() doesn't know
     about that).

See also:
*Note set_color::.
*Note set_gfx_mode::.
*Note timer_simulate_retrace::.
*Note ex3buf::.
*Note RGB::.

File: allegro.info,  Node: set_palette,  Next: set_palette_range,  Prev: _set_color,  Up: Palette

12.3 set_palette
================

void set_palette(const PALETTE p);
     Sets the entire palette of 256 colors. You should provide an array
     of 256 RGB structures. Unlike set_color(), there is no need to
     call vsync() before this function.

See also:
*Note set_gfx_mode::.
*Note set_palette_range::.
*Note set_color::.
*Note get_palette::.
*Note select_palette::.
*Note palette_color::.
*Note Available Allegro examples: Available.
*Note PALETTE::.

File: allegro.info,  Node: set_palette_range,  Next: get_color,  Prev: set_palette,  Up: Palette

12.4 set_palette_range
======================

void set_palette_range(const PALETTE p, int from, int to, int vsync);
     Sets the palette entries between from and to (inclusive: pass 0
     and 255 to set the entire palette). If vsync is set it waits for
     the vertical retrace, otherwise it sets the colors immediately.

See also:
*Note set_palette::.
*Note get_palette_range::.
*Note PALETTE::.

File: allegro.info,  Node: get_color,  Next: get_palette,  Prev: set_palette_range,  Up: Palette

12.5 get_color
==============

void get_color(int index, RGB *p);
     Retrieves the specified palette entry.

See also:
*Note get_palette::.
*Note set_color::.
*Note RGB::.

File: allegro.info,  Node: get_palette,  Next: get_palette_range,  Prev: get_color,  Up: Palette

12.6 get_palette
================

void get_palette(PALETTE p);
     Retrieves the entire palette of 256 colors. You should provide an
     array of 256 RGB structures to store it in.

See also:
*Note get_palette_range::.
*Note get_color::.
*Note set_palette::.
*Note PALETTE::.

File: allegro.info,  Node: get_palette_range,  Next: fade_interpolate,  Prev: get_palette,  Up: Palette

12.7 get_palette_range
======================

void get_palette_range(PALETTE p, int from, int to);
     Retrieves the palette entries between from and to (inclusive: pass
     0 and 255 to get the entire palette).

See also:
*Note get_palette::.
*Note set_palette_range::.
*Note PALETTE::.

File: allegro.info,  Node: fade_interpolate,  Next: fade_from_range,  Prev: get_palette_range,  Up: Palette

12.8 fade_interpolate
=====================

void fade_interpolate(const PALETTE source, const PALETTE dest, PALETTE output, int pos, int from, to);
     Calculates a temporary palette part way between source and dest,
     returning it in the output parameter. The position between the two
     extremes is specified by the pos value: 0 returns an exact copy of
     source, 64 returns dest, 32 returns a palette half way between the
     two, etc. This routine only affects colors between from and to
     (inclusive: pass 0 and 255 to interpolate the entire palette).

See also:
*Note fade_in::.
*Note fade_out::.
*Note fade_from::.
*Note PALETTE::.

File: allegro.info,  Node: fade_from_range,  Next: fade_in_range,  Prev: fade_interpolate,  Up: Palette

12.9 fade_from_range
====================

void fade_from_range(const PALETTE source, const PALETTE dest, int speed, int from, to);
     Gradually fades a part of the palette from the source palette to
     the dest palette. The speed is from 1 (the slowest) up to 64
     (instantaneous). This routine only affects colors between from and
     to (inclusive: pass 0 and 255 to fade the entire palette).

See also:
*Note fade_from::.
*Note PALETTE::.

File: allegro.info,  Node: fade_in_range,  Next: fade_out_range,  Prev: fade_from_range,  Up: Palette

12.10 fade_in_range
===================

void fade_in_range(const PALETTE p, int speed, int from, to);
     Gradually fades a part of the palette from a black screen to the
     specified palette. The speed is from 1 (the slowest) up to 64
     (instantaneous). This routine only affects colors between from and
     to (inclusive: pass 0 and 255 to fade the entire palette).

See also:
*Note fade_in::.
*Note PALETTE::.

File: allegro.info,  Node: fade_out_range,  Next: fade_from,  Prev: fade_in_range,  Up: Palette

12.11 fade_out_range
====================

void fade_out_range(int speed, int from, to);
     Gradually fades a part of the palette from the current palette to
     a black screen. The speed is from 1 (the slowest) up to 64
     (instantaneous). This routine only affects colors between from and
     to (inclusive: pass 0 and 255 to fade the entire palette).

See also:
*Note fade_out::.

File: allegro.info,  Node: fade_from,  Next: fade_in,  Prev: fade_out_range,  Up: Palette

12.12 fade_from
===============

void fade_from(const PALETTE source, const PALETTE dest, int speed);
     Fades gradually from the source palette to the dest palette. The
     speed is from 1 (the slowest) up to 64 (instantaneous).

See also:
*Note fade_in::.
*Note fade_out::.
*Note fade_interpolate::.
*Note fade_from_range::.
*Note PALETTE::.

File: allegro.info,  Node: fade_in,  Next: fade_out,  Prev: fade_from,  Up: Palette

12.13 fade_in
=============

void fade_in(const PALETTE p, int speed);
     Fades gradually from a black screen to the specified palette. The
     speed is from 1 (the slowest) up to 64 (instantaneous).

See also:
*Note fade_out::.
*Note fade_from::.
*Note fade_interpolate::.
*Note fade_in_range::.
*Note PALETTE::.

File: allegro.info,  Node: fade_out,  Next: select_palette,  Prev: fade_in,  Up: Palette

12.14 fade_out
==============

void fade_out(int speed);
     Fades gradually from the current palette to a black screen. The
     speed is from 1 (the slowest) up to 64 (instantaneous).

See also:
*Note fade_in::.
*Note fade_from::.
*Note fade_interpolate::.
*Note fade_in_range::.
*Note ex12bit::.

File: allegro.info,  Node: select_palette,  Next: unselect_palette,  Prev: fade_out,  Up: Palette

12.15 select_palette
====================

void select_palette(const PALETTE p);
     Ugly hack for use in various dodgy situations where you need to
     convert between paletted and truecolor image formats. Sets the
     internal palette table in the same way as the set_palette()
     function, so the conversion will use the specified palette, but
     without affecting the display hardware in any way. The previous
     palette settings are stored in an internal buffer, and can be
     restored by calling unselect_palette().

See also:
*Note set_palette::.
*Note unselect_palette::.
*Note exlights::.
*Note PALETTE::.

File: allegro.info,  Node: unselect_palette,  Next: generate_332_palette,  Prev: select_palette,  Up: Palette

12.16 unselect_palette
======================

void unselect_palette();
     Restores the palette tables that were in use before the last call
     to select_palette().

See also:
*Note select_palette::.

File: allegro.info,  Node: generate_332_palette,  Next: generate_optimized_palette,  Prev: unselect_palette,  Up: Palette

12.17 generate_332_palette
==========================

void generate_332_palette(PALETTE pal);
     Constructs a fake truecolor palette, using three bits for red and
     green and two for the blue. The load_bitmap() function returns
     this if the file does not contain a palette itself (ie. you are
     reading a truecolor bitmap).

See also:
*Note generate_optimized_palette::.
*Note set_color_depth::.
*Note excolmap::.
*Note exrgbhsv::.
*Note extruec::.
*Note exupdate::.
*Note PALETTE::.

File: allegro.info,  Node: generate_optimized_palette,  Next: default_palette,  Prev: generate_332_palette,  Up: Palette

12.18 generate_optimized_palette
================================

int generate_optimized_palette(BITMAP *bmp, PALETTE pal, const char rsvd[256]);
     Generates a 256-color palette suitable for making a reduced color
     version of the specified truecolor image. The rsvd parameter
     points to a table indicating which colors it is allowed to modify:
     zero for free colors which may be set to whatever the optimiser
     likes, negative values for reserved colors which cannot be used,
     and positive values for fixed palette entries that must not be
     changed, but can be used in the optimisation.

See also:
*Note generate_332_palette::.
*Note set_color_depth::.
*Note BITMAP::.
*Note PALETTE::.

File: allegro.info,  Node: default_palette,  Next: black_palette,  Prev: generate_optimized_palette,  Up: Palette

12.19 default_palette
=====================

extern PALETTE default_palette;
     The default IBM BIOS palette. This will be automatically selected
     whenever you set a new graphics mode.

See also:
*Note black_palette::.
*Note desktop_palette::.
*Note exjoy::.
*Note PALETTE::.

File: allegro.info,  Node: black_palette,  Next: desktop_palette,  Prev: default_palette,  Up: Palette

12.20 black_palette
===================

extern PALETTE black_palette;
     A palette containing solid black colors, used by the fade routines.

See also:
*Note default_palette::.
*Note desktop_palette::.
*Note expal::.
*Note PALETTE::.

File: allegro.info,  Node: desktop_palette,  Next: makecol8,  Prev: black_palette,  Up: Palette

12.21 desktop_palette
=====================

extern PALETTE desktop_palette;
     The palette used by the Atari ST low resolution desktop. I'm not
     quite sure why this is still here, except that the grabber and
     test programs use it. It is probably the only Atari legacy code
     left in Allegro, and it would be a shame to remove it :-)

See also:
*Note default_palette::.
*Note black_palette::.
*Note Available Allegro examples: Available.
*Note PALETTE::.

File: allegro.info,  Node: Truecolor,  Next: Drawing,  Prev: Palette,  Up: Top

13 Truecolor pixel formats
**************************

In a truecolor video mode the red, green, and blue components for each
pixel are packed directly into the color value, rather than using a
palette lookup table. In a 15-bit mode there are 5 bits for each color,
in 16-bit modes there are 5 bits each of red and blue and six bits of
green, and both 24 and 32-bit modes use 8 bits for each color (the
32-bit pixels simply have an extra padding byte to align the data
nicely). The layout of these components can vary depending on your
hardware, but will generally either be RGB or BGR. Since the layout is
not known until you select the video mode you will be using, you must
call set_gfx_mode() before using any of the following routines!

* Menu:

* makecol8::
* makeacol32::
* makecol::
* makecol_depth::
* makeacol::
* makecol15_dither::
* getr8::
* geta32::
* getr::
* getr_depth::
* palette_color::
* MASK_COLOR_8::


File: allegro.info,  Node: makecol8,  Next: makeacol32,  Prev: desktop_palette,  Up: Truecolor

13.1 makecol8
=============

int makecol8(int r, int g, int b);

int makecol15(int r, int g, int b);

int makecol16(int r, int g, int b);

int makecol24(int r, int g, int b);

int makecol32(int r, int g, int b);
     These functions convert colors from a hardware independent form
     (red, green, and blue values ranging 0-255) into various display
     dependent pixel formats. Converting to 15, 16, 24, or 32-bit
     formats only takes a few shifts, so it is fairly efficient.
     Converting to an 8-bit color involves searching the palette to
     find the closest match, which is quite slow unless you have set up
     an RGB mapping table (see below).

See also:
*Note makeacol32::.
*Note makecol::.
*Note makecol_depth::.
*Note makecol15_dither::.
*Note rgb_map::.
*Note bestfit_color::.
*Note set_color_depth::.
*Note exrgbhsv::.

File: allegro.info,  Node: makeacol32,  Next: makecol,  Prev: makecol8,  Up: Truecolor

13.2 makeacol32
===============

int makeacol32(int r, int g, int b, int a);
     Converts an RGBA color into a 32-bit display pixel format, which
     includes an alpha (transparency) value. There are no versions of
     this routine for other color depths, because only the 32-bit
     format has enough room to store a proper alpha channel. You should
     only use RGBA format colors as the input to draw_trans_sprite() or
     draw_trans_rle_sprite() after calling set_alpha_blender(), rather
     than drawing them directly to the screen.

See also:
*Note makeacol::.
*Note set_alpha_blender::.
*Note set_write_alpha_blender::.

File: allegro.info,  Node: makecol,  Next: makecol_depth,  Prev: makeacol32,  Up: Truecolor

13.3 makecol
============

int makecol(int r, int g, int b);
     Converts colors from a hardware independent format (red, green,
     and blue values ranging 0-255) to the pixel format required by the
     current video mode, calling the preceding 8, 15, 16, 24, or 32-bit
     makecol functions as appropriate.

See also:
*Note makeacol::.
*Note makecol8::.
*Note makecol_depth::.
*Note makecol15_dither::.
*Note rgb_map::.
*Note set_color_depth::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: makecol_depth,  Next: makeacol,  Prev: makecol,  Up: Truecolor

13.4 makecol_depth
==================

int makecol_depth(int color_depth, int r, int g, int b);
     Converts colors from a hardware independent format (red, green,
     and blue values ranging 0-255) to the pixel format required by the
     specified color depth.

See also:
*Note makeacol::.
*Note makecol::.
*Note makecol8::.
*Note makecol15_dither::.
*Note rgb_map::.
*Note set_color_depth::.

File: allegro.info,  Node: makeacol,  Next: makecol15_dither,  Prev: makecol_depth,  Up: Truecolor

13.5 makeacol
=============

int makeacol(int r, int g, int b, int a);

int makeacol_depth(int color_depth, int r, int g, int b, int a);
     Convert RGBA colors into display dependent pixel formats. In
     anything less than a 32-bit mode, these are the same as calling
     makecol() or makecol_depth(), but by using these routines it is
     possible to create 32-bit color values that contain a true 8 bit
     alpha channel along with the red, green, and blue components. You
     should only use RGBA format colors as the input to
     draw_trans_sprite() or draw_trans_rle_sprite() after calling
     set_alpha_blender(), rather than drawing them directly to the
     screen.

See also:
*Note makecol::.
*Note makecol_depth::.
*Note set_alpha_blender::.
*Note set_write_alpha_blender::.

File: allegro.info,  Node: makecol15_dither,  Next: getr8,  Prev: makeacol,  Up: Truecolor

13.6 makecol15_dither
=====================

int makecol15_dither(int r, int g, int b, int x, int y);

int makecol16_dither(int r, int g, int b, int x, int y);
     Given both a color value and a pixel coordinate, calculate a
     dithered 15 or 16-bit RGB value. This can produce better results
     when reducing images from truecolor to hicolor. In addition to
     calling these functions directly, hicolor dithering can be
     automatically enabled when loading graphics by calling the
     set_color_conversion() function, for example set_color_conversion
     (COLORCONV_REDUCE_TRUE_TO_HI | COLORCONV_DITHER).

See also:
*Note makecol::.
*Note makecol8::.
*Note set_color_conversion::.

File: allegro.info,  Node: getr8,  Next: geta32,  Prev: makecol15_dither,  Up: Truecolor

13.7 getr8
==========

int getr8(int c);

int getg8(int c);

int getb8(int c);

int getr15(int c);

int getg15(int c);

int getb15(int c);

int getr16(int c);

int getg16(int c);

int getb16(int c);

int getr24(int c);

int getg24(int c);

int getb24(int c);

int getr32(int c);

int getg32(int c);

int getb32(int c);
     Given a color in a display dependent format, these functions
     extract one of the red, green, or blue components (ranging 0-255).

See also:
*Note geta32::.
*Note getr::.
*Note getr_depth::.
*Note makecol::.
*Note set_color_depth::.

File: allegro.info,  Node: geta32,  Next: getr,  Prev: getr8,  Up: Truecolor

13.8 geta32
===========

int geta32(int c);
     Given a color in a 32-bit pixel format, this function extracts the
     alpha component (ranging 0-255).

See also:
*Note getr8::.

File: allegro.info,  Node: getr,  Next: getr_depth,  Prev: geta32,  Up: Truecolor

13.9 getr
=========

int getr(int c);

int getg(int c);

int getb(int c);

int geta(int c);
     Given a color in the format being used by the current video mode,
     these functions extract one of the red, green, blue, or alpha
     components (ranging 0-255), calling the preceding 8, 15, 16, 24,
     or 32-bit get functions as appropriate. The alpha part is only
     meaningful for 32-bit pixels.

See also:
*Note getr8::.
*Note getr_depth::.
*Note makecol::.
*Note set_color_depth::.
*Note exalpha::.

File: allegro.info,  Node: getr_depth,  Next: palette_color,  Prev: getr,  Up: Truecolor

13.10 getr_depth
================

int getr_depth(int color_depth, int c);

int getg_depth(int color_depth, int c);

int getb_depth(int color_depth, int c);

int geta_depth(int color_depth, int c);
     Given a color in the format being used by the specified color
     depth, these functions extract one of the red, green, blue, or
     alpha components (ranging 0-255). The alpha part is only
     meaningful for 32-bit pixels.

See also:
*Note getr::.
*Note getr8::.
*Note geta32::.
*Note makecol::.
*Note set_color_depth::.
*Note exlights::.

File: allegro.info,  Node: palette_color,  Next: MASK_COLOR_8,  Prev: getr_depth,  Up: Truecolor

13.11 palette_color
===================

extern int palette_color[256];
     Table mapping palette index colors (0-255) into whatever pixel
     format is being used by the current display mode. In a 256-color
     mode this just maps onto the array index. In truecolor modes it
     looks up the specified entry in the current palette, and converts
     that RGB value into the appropriate packed pixel format.

See also:
*Note set_palette::.
*Note makecol::.
*Note set_color_depth::.
*Note Available Allegro examples: Available.

File: allegro.info,  Node: MASK_COLOR_8,  Next: putpixel,  Prev: palette_color,  Up: Truecolor

13.12 MASK_COLOR_8
==================

#define MASK_COLOR_8 0

#define MASK_COLOR_15 (5.5.5 pink)

#define MASK_COLOR_16 (5.6.5 pink)

#define MASK_COLOR_24 (8.8.8 pink)

#define MASK_COLOR_32 (8.8.8 pink)
     Constants representing the colors used to mask transparent sprite
     pixels for each color depth. In 256-color resolutions this is
     zero, and in truecolor modes it is bright pink (maximum red and
     blue, zero green).

See also:
*Note bitmap_mask_color::.
*Note makecol::.
*Note draw_sprite::.
*Note masked_blit::.

File: allegro.info,  Node: Drawing,  Next: Blitting,  Prev: Truecolor,  Up: Top

14 Drawing primitives
*********************

Except for _putpixel(), all these routines are affected by the current
drawing mode and the clipping rectangle of the destination bitmap.

* Menu:

* putpixel::
* _putpixel::
* getpixel::
* _getpixel::
* vline::
* hline::
* do_line::
* line::
* triangle::
* polygon::
* rect::
* rectfill::
* do_circle::
* circle::
* circlefill::
* do_ellipse::
* ellipse::
* ellipsefill::
* do_arc::
* arc::
* calc_spline::
* spline::
* floodfill::


File: allegro.info,  Node: putpixel,  Next: _putpixel,  Prev: MASK_COLOR_8,  Up: Drawing

14.1 putpixel
=============

void putpixel(BITMAP *bmp, int x, int y, int color);
     Writes a pixel to the specified position in the bitmap, using the
     current drawing mode and the bitmap's clipping rectangle.

See also:
*Note getpixel::.
*Note _putpixel::.
*Note drawing_mode::.
*Note ex12bit::.
*Note exalpha::.
*Note exflame::.
*Note exjoy::.
*Note exstars::.
*Note exswitch::.
*Note BITMAP::.

File: allegro.info,  Node: _putpixel,  Next: getpixel,  Prev: putpixel,  Up: Drawing

14.2 _putpixel
==============

void _putpixel(BITMAP *bmp, int x, int y, int color);

void _putpixel15(BITMAP *bmp, int x, int y, int color);

void _putpixel16(BITMAP *bmp, int x, int y, int color);

void _putpixel24(BITMAP *bmp, int x, int y, int color);

void _putpixel32(BITMAP *bmp, int x, int y, int color);
     Like the regular putpixel(), but much faster because they are
     implemented as an inline assembler functions for specific color
     depths. These won't work in mode-X graphics modes, don't perform
     any clipping (they will crash if you try to draw outside the
     bitmap!), and ignore the drawing mode.

See also:
*Note putpixel::.
*Note BITMAP::.

File: allegro.info,  Node: getpixel,  Next: _getpixel,  Prev: _putpixel,  Up: Drawing

14.3 getpixel
=============

int getpixel(BITMAP *bmp, int x, int y);
     Reads a pixel from point x, y in the bitmap. Returns -1 if the
     point lies outside the bitmap.

See also:
*Note putpixel::.
*Note _getpixel::.
*Note ex12bit::.
*Note exalpha::.
*Note exflame::.
*Note exlights::.
*Note BITMAP::.

File: allegro.info,  Node: _getpixel,  Next: vline,  Prev: getpixel,  Up: Drawing

14.4 _getpixel
==============

int _getpixel(BITMAP *bmp, int x, int y);

int _getpixel15(BITMAP *bmp, int x, int y);

int _getpixel16(BITMAP *bmp, int x, int y);

int _getpixel24(BITMAP *bmp, int x, int y);

int _getpixel32(BITMAP *bmp, int x, int y);
     Faster inline versions of getpixel() for specific color depths.
     These won't work in mode-X, and don't do any clipping, so you must
     make sure the point lies inside the bitmap.

See also:
*Note getpixel::.
*Note BITMAP::.

File: allegro.info,  Node: vline,  Next: hline,  Prev: _getpixel,  Up: Drawing

14.5 vline
==========

void vline(BITMAP *bmp, int x, int y1, int y2, int color);
     Draws a vertical line onto the bitmap, from point (x, y1) to (x,
     y2).

See also:
*Note hline::.
*Note line::.
*Note drawing_mode::.
*Note exrgbhsv::.
*Note exscroll::.
*Note extruec::.
*Note BITMAP::.

File: allegro.info,  Node: hline,  Next: do_line,  Prev: vline,  Up: Drawing

14.6 hline
==========

void hline(BITMAP *bmp, int x1, int y, int x2, int color);
     Draws a horizontal line onto the bitmap, from point (x1, y) to
     (x2, y).

See also:
*Note vline::.
*Note line::.
*Note drawing_mode::.
*Note BITMAP::.

File: allegro.info,  Node: do_line,  Next: line,  Prev: hline,  Up: Drawing

14.7 do_line
============

void do_line(BITMAP *bmp, int x1, y1, x2, y2, int d,  void (*proc)(BITMAP *bmp, int x, int y, int d));
     Calculates all the points along a line from point (x1, y1) to (x2,
     y2), calling the supplied function for each one. This will be
     passed a copy of the bmp parameter, the x and y position, and a
     copy of the d parameter, so it is suitable for use with putpixel().

See also:
*Note do_circle::.
*Note do_ellipse::.
*Note do_arc::.
*Note line::.
*Note BITMAP::.

File: allegro.info,  Node: line,  Next: triangle,  Prev: do_line,  Up: Drawing

14.8 line
=========

void line(BITMAP *bmp, int x1, int y1, int x2, int y2, int color);
     Draws a line onto the bitmap, from point (x1, y1) to (x2, y2).

See also:
*Note hline::.
*Note vline::.
*Note do_line::.
*Note drawing_mode::.
*Note Available Allegro examples: Available.
*Note BITMAP::.

File: allegro.info,  Node: triangle,  Next: polygon,  Prev: line,  Up: Drawing

14.9 triangle
=============

void triangle(BITMAP *bmp, int x1, y1, x2, y2, x3, y3, int color);
     Draws a filled triangle between the three points.

See also:
*Note polygon::.
*Note triangle3d::.
*Note drawing_mode::.
*Note ex3buf::.
*Note exstars::.
*Note exupdate::.
*Note BITMAP::.

File: allegro.info,  Node: polygon,  Next: rect,  Prev: triangle,  Up: Drawing

14.10 polygon
=============

void polygon(BITMAP *bmp, int vertices, const int *points, int color);
     Draws a filled polygon with an arbitrary number of corners. Pass
     the number of vertices and an array containing a series of x, y
     points (a total of vertices*2 values).

See also:
*Note triangle::.
*Note polygon3d::.
*Note drawing_mode::.
*Note excamera::.
*Note BITMAP::.

File: allegro.info,  Node: rect,  Next: rectfill,  Prev: polygon,  Up: Drawing

14.11 rect
==========

void rect(BITMAP *bmp, int x1, int y1, int x2, int y2, int color);
     Draws an outline rectangle with the two points as its opposite
     corners.

See also:
*Note rectfill::.
*Note drawing_mode::.
*Note ex3d::.
*Note excamera::.
*Note BITMAP::.

File: allegro.info,  Node: rectfill,  Next: do_circle,  Prev: rect,  Up: Drawing

14.12 rectfill
==============

void rectfill(BITMAP *bmp, int x1, int y1, int x2, int y2, int color);
     Draws a solid, filled rectangle with the two points as its opposite
     corners.

See also:
*Note rect::.
*Note clear_bitmap::.
*Note drawing_mode::.
*Note exalpha::.
*Note excolmap::.
*Note exkeys::.
*Note expat::.
*Note exscroll::.
*Note exsprite::.
*Note exstars::.
*Note exswitch::.
*Note extrans::.
*Note BITMAP::.

File: allegro.info,  Node: do_circle,  Next: circle,  Prev: rectfill,  Up: Drawing

14.13 do_circle
===============

void do_circle(BITMAP *bmp, int x, int y, int radius, int d, void (*proc)(BITMAP *bmp, int x, int y, int d));
     Calculates all the points in a circle around point (x, y) with
     radius r, calling the supplied function for each one. This will be
     passed a copy of the bmp parameter, the x and y position, and a
     copy of the d parameter, so it is suitable for use with putpixel().

See also:
*Note do_ellipse::.
*Note do_arc::.
*Note do_line::.
*Note circle::.
*Note circlefill::.
*Note BITMAP::.

File: allegro.info,  Node: circle,  Next: circlefill,  Prev: do_circle,  Up: Drawing

14.14 circle
============

void circle(BITMAP *bmp, int x, int y, int radius, int color);
     Draws a circle with the specified centre and radius.

See also:
*Note ellipse::.
*Note arc::.
*Note circlefill::.
*Note do_circle::.
*Note drawing_mode::.
*Note ex12bit::.
*Note exblend::.
*Note excustom::.
*Note exjoy::.
*Note exmem::.
*Note exmouse::.
*Note exquat::.
*Note BITMAP::.

File: allegro.info,  Node: circlefill,  Next: do_ellipse,  Prev: circle,  Up: Drawing

14.15 circlefill
================

void circlefill(BITMAP *bmp, int x, int y, int radius, int color);
     Draws a filled circle with the specified centre and radius.

See also:
*Note ellipsefill::.
*Note circle::.
*Note do_circle::.
*Note drawing_mode::.
*Note excolmap::.
*Note excustom::.
*Note exdbuf::.
*Note exflip::.
*Note exlights::.
*Note expal::.
*Note exspline::.
*Note extrans::.
*Note BITMAP::.

File: allegro.info,  Node: do_ellipse,  Next: ellipse,  Prev: circlefill,  Up: Drawing

14.16 do_ellipse
================

void do_ellipse(BITMAP *bmp, int x, int y, int rx, ry, int d, void (*proc)(BITMAP *bmp, int x, int y, int d));
     Calculates all the points in an ellipse around point (x, y) with
     radius rx and ry, calling the supplied function for each one. This
     will be passed a copy of the bmp parameter, the x and y position,
     and a copy of the d parameter, so it is suitable for use with
     putpixel().

See also:
*Note do_circle::.
*Note do_arc::.
*Note do_line::.
*Note ellipse::.
*Note ellipsefill::.
*Note BITMAP::.

File: allegro.info,  Node: ellipse,  Next: ellipsefill,  Prev: do_ellipse,  Up: Drawing

14.17 ellipse
=============

void ellipse(BITMAP *bmp, int x, int y, int rx, int ry, int color);
     Draws an ellipse with the specified centre and radius.

See also:
*Note circle::.
*Note arc::.
*Note ellipsefill::.
*Note do_ellipse::.
*Note drawing_mode::.
*Note BITMAP::.

File: allegro.info,  Node: ellipsefill,  Next: do_arc,  Prev: ellipse,  Up: Drawing

14.18 ellipsefill
=================

void ellipsefill(BITMAP *bmp, int x, int y, int rx, int ry, int color);
     Draws a filled ellipse with the specified centre and radius.

See also:
*Note circlefill::.
*Note ellipse::.
*Note do_ellipse::.
*Note drawing_mode::.
*Note ex12bit::.
*Note BITMAP::.

File: allegro.info,  Node: do_arc,  Next: arc,  Prev: ellipsefill,  Up: Drawing

14.19 do_arc
============

void do_arc(BITMAP *bmp, int x, int y, fixed a1, fixed a2, int r, int d, void (*proc)(BITMAP *bmp, int x, int y, int d));
     Calculates all the points in a circular arc around point (x, y)
     with radius r, calling the supplied function for each one. This
     will be passed a copy of the bmp parameter, the x and y position,
     and a copy of the d parameter, so it is suitable for use with
     putpixel(). The arc will be plotted in an anticlockwise direction
     starting from the angle a1 and ending when it reaches a2. These
     values are specified in 16.16 fixed point format, with 256 equal
     to a full circle, 64 a right angle, etc.  Zero is to the right of
     the centre point, and larger values rotate anticlockwise from
     there.

See also:
*Note do_circle::.
*Note do_ellipse::.
*Note do_line::.
*Note arc::.
*Note fixed::.
*Note BITMAP::.

File: allegro.info,  Node: arc,  Next: calc_spline,  Prev: do_arc,  Up: Drawing

14.20 arc
=========

void arc(BITMAP *bmp, int x, y, fixed ang1, ang2, int r, int color);
     Draws a circular arc with centre x, y and radius r, in an
     anticlockwise direction starting from the angle a1 and ending when
     it reaches a2. These values are specified in 16.16 fixed point
     format, with 256 equal to a full circle, 64 a right angle, etc.
     Zero is to the right of the centre point, and larger values rotate
     anticlockwise from there.

See also:
*Note circle::.
*Note ellipse::.
*Note drawing_mode::.
*Note fixed::.
*Note BITMAP::.

File: allegro.info,  Node: calc_spline,  Next: spline,  Prev: arc,  Up: Drawing

14.21 calc_spline
=================

void calc_spline(const int points[8], int npts, int *x, int *y);
     Calculates a series of npts values along a bezier spline, storing
     them in the output x and y arrays. The bezier curve is specified
     by the four x/y control points in the points array: points[0] and
     points[1] contain the coordinates of the first control point,
     points[2] and points[3] are the second point, etc. Control points
     0 and 3 are the ends of the spline, and points 1 and 2 are guides.
     The curve probably won't pass through points 1 and 2, but they
     affect the shape of the curve between points 0 and 3 (the lines
     p0-p1 and p2-p3 are tangents to the spline). The easiest way to
     think of it is that the curve starts at p0, heading in the
     direction of p1, but curves round so that it arrives at p3 from
     the direction of p2.  In addition to their role as graphics
     primitives, spline curves can be useful for constructing smooth
     paths around a series of control points, as in exspline.c.

See also:
*Note spline::.
*Note exspline::.

File: allegro.info,  Node: spline,  Next: floodfill,  Prev: calc_spline,  Up: Drawing

14.22 spline
============

void spline(BITMAP *bmp, const int points[8], int color);
     Draws a bezier spline using the four control points specified in
     the points array.

See also:
*Note calc_spline::.
*Note drawing_mode::.
*Note exspline::.
*Note BITMAP::.

File: allegro.info,  Node: floodfill,  Next: clear_bitmap,  Prev: spline,  Up: Drawing

14.23 floodfill
===============

void floodfill(BITMAP *bmp, int x, int y, int color);
     Floodfills an enclosed area, starting at point (x, y), with the
     specified color.

See also:
*Note drawing_mode::.
*Note BITMAP::.

File: allegro.info,  Node: Blitting,  Next: RLE,  Prev: Drawing,  Up: Top

15 Blitting and sprites
***********************

All these routines are affected by the clipping rectangle of the
destination bitmap.

* Menu:

* clear_bitmap::
* clear_to_color::
* blit::
* stretch_blit::
* masked_blit::
* masked_stretch_blit::
* draw_sprite::
* stretch_sprite::
* draw_sprite_v_flip::
* draw_trans_sprite::
* draw_lit_sprite::
* draw_gouraud_sprite::
* draw_character_ex::
* rotate_sprite::
* rotate_sprite_v_flip::
* rotate_scaled_sprite::
* rotate_scaled_sprite_v_flip::
* pivot_sprite::
* pivot_sprite_v_flip::
* pivot_scaled_sprite::
* pivot_scaled_sprite_v_flip::


File: allegro.info,  Node: clear_bitmap,  Next: clear_to_color,  Prev: floodfill,  Up: Blitting

15.1 clear_bitmap
=================

void clear_bitmap(BITMAP *bitmap);
     Clears the bitmap to color 0.

See also:
*Note clear_to_color::.
*Note Available Allegro examples: Available.
*Note BITMAP::.

File: allegro.info,  Node: clear_to_color,  Next: blit,  Prev: clear_bitmap,  Up: Blitting

15.2 clear_to_color
===================

void clear_to_color(BITMAP *bitmap, int color);
     Clears the bitmap to the specified color.

See also:
*Note clear_bitmap::.
*Note Available Allegro examples: Available.
*Note BITMAP::.

File: allegro.info,  Node: blit,  Next: stretch_blit,  Prev: clear_to_color,  Up: Blitting

15.3 blit
=========

void blit(BITMAP *source, BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
     Copies a rectangular area of the source bitmap to the destination
     bitmap.  The source_x and source_y parameters are the top left
     corner of the area to copy from the source bitmap, and dest_x and
     dest_y are the corresponding position in the destination bitmap.
     This routine respects the destination clipping rectangle, and it
     will also clip if you try to blit from areas outside the source
     bitmap.

     You can blit between any parts of any two bitmaps, even if the two
     memory areas overlap (ie. source and dest are the same, or one is
     sub-bitmap of the other). You should be aware, however, that a lot
     of SVGA cards don't provide separate read and write banks, which
     means that blitting from one part of the screen to another
     requires the use of a temporary bitmap in memory, and is therefore
     extremely slow. As a general rule you should avoid blitting from
     the screen onto itself in SVGA modes.

     In mode-X, on the other hand, blitting from one part of the screen
     to another can be significantly faster than blitting from memory
     onto the screen, as long as the source and destination are
     correctly aligned with each other. Copying between overlapping
     screen rectangles is slow, but if the areas don't overlap, and if
     they have the same plane alignment (ie.  (source_x%4) ==
     (dest_x%4)), the VGA latch registers can be used for a very fast
     data transfer. To take advantage of this, in mode-X it is often
     worth storing tile graphics in a hidden area of video memory
     (using a large virtual screen), and blitting them from there onto
     the visible part of the screen.

     If the GFX_HW_VRAM_BLIT bit in the gfx_capabilities flag is set,
     the current driver supports hardware accelerated blits from one
     part of the screen onto another. This is extremely fast, so when
     this flag is set it may be worth storing some of your more
     frequently used graphics in an offscreen portion of the video
     memory.

     Unlike most of the graphics routines, blit() allows the source and
     destination bitmaps to be of different color depths, so it can be
     used to convert images from one pixel format to another.

See also:
*Note masked_blit::.
*Note stretch_blit::.
*Note draw_sprite::.
*Note gfx_capabilities::.
*Note BITMAP::.

File: allegro.info,  Node: stretch_blit,  Next: masked_blit,  Prev: blit,  Up: Blitting

15.4 stretch_blit
=================

void stretch_blit(BITMAP *source, BITMAP *dest, int source_x, source_y, source_width, source_height, int dest_x, dest_y, dest_width, dest_height);
     Like blit(), except it can scale images (so the source and
     destination rectangles don't need to be the same size) and
     requires the source and destination bitmaps to be of the same
     color depth. This routine doesn't do as much safety checking as
     the regular blit(): in particular you must take care not to copy
     from areas outside the source bitmap, and you cannot blit between
     overlapping regions, ie. you must use different bitmaps for the
     source and the destination. Moreover, the source must be a memory
     bitmap.

See also:
*Note blit::.
*Note masked_stretch_blit::.
*Note stretch_sprite::.
*Note BITMAP::.

File: allegro.info,  Node: masked_blit,  Next: masked_stretch_blit,  Prev: stretch_blit,  Up: Blitting

15.5 masked_blit
================

void masked_blit(BITMAP *source, BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
     Like blit(), but skips transparent pixels, which are marked by a
     zero in 256-color modes or bright pink for truecolor data (maximum
     red and blue, zero green), and requires the source and destination
     bitmaps to be of the same color depth. The source and destination
     regions must not overlap.

     If the GFX_HW_VRAM_BLIT_MASKED bit in the gfx_capabilities flag is
     set, the current driver supports hardware accelerated masked blits
     from one part of the screen onto another. This is extremely fast,
     so when this flag is set it may be worth storing some of your more
     frequently used sprites in an offscreen portion of the video
     memory.

     Warning: if the hardware acceleration flag is not set,
     masked_blit() will not work correctly when used with a source
     image in system or video memory so the latter must be a memory
     bitmap.

See also:
*Note blit::.
*Note masked_stretch_blit::.
*Note draw_sprite::.
*Note bitmap_mask_color::.
*Note BITMAP::.

File: allegro.info,  Node: masked_stretch_blit,  Next: draw_sprite,  Prev: masked_blit,  Up: Blitting

15.6 masked_stretch_blit
========================

void masked_stretch_blit(BITMAP *source, BITMAP *dest, int source_x, source_y, source_w, source_h, int dest_x, dest_y, dest_w, dest_h);
     Like masked_blit(), except it can scale images (so the source and
     destination rectangles don't need to be the same size). This
     routine doesn't do as much safety checking as the regular
     masked_blit(): in particular you must take care not to copy from
     areas outside the source bitmap. Moreover, the source must be a
     memory bitmap.

See also:
*Note blit::.
*Note masked_blit::.
*Note stretch_blit::.
*Note stretch_sprite::.
*Note BITMAP::.

File: allegro.info,  Node: draw_sprite,  Next: stretch_sprite,  Prev: masked_stretch_blit,  Up: Blitting

15.7 draw_sprite
================

void draw_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y);
     Draws a copy of the sprite bitmap onto the destination bitmap at
     the specified position. This is almost the same as blit(sprite,
     bmp, 0, 0, x, y, sprite->w, sprite->h), but it uses a masked
     drawing mode where transparent pixels are skipped, so the
     background image will show through the masked parts of the sprite.
     Transparent pixels are marked by a zero in 256-color modes or
     bright pink for truecolor data (maximum red and blue, zero green).

     If the GFX_HW_VRAM_BLIT_MASKED bit in the gfx_capabilities flag is
     set, the current driver supports hardware accelerated sprite
     drawing when the source image is a video memory bitmap or a
     sub-bitmap of the screen. This is extremely fast, so when this
     flag is set it may be worth storing some of your more frequently
     used sprites in an offscreen portion of the video memory.

     Warning: if the hardware acceleration flag is not set,
     draw_sprite() will not work correctly when used with a sprite
     image in system or video memory so the latter must be a memory
     bitmap.

     Although generally not supporting graphics of mixed color depths,
     as a special case this function can be used to draw 256-color
     source images onto truecolor destination bitmaps, so you can use
     palette effects on specific sprites within a truecolor program.

See also:
*Note draw_sprite_v_flip::.
*Note draw_trans_sprite::.
*Note draw_lit_sprite::.
*Note draw_gouraud_sprite::.
*Note stretch_sprite::.
*Note rotate_sprite::.
*Note draw_character_ex::.
*Note draw_rle_sprite::.
*Note draw_compiled_sprite::.
*Note masked_blit::.
*Note blit::.
*Note bitmap_mask_color::.
*Note exsprite::.
*Note BITMAP::.

File: allegro.info,  Node: stretch_sprite,  Next: draw_sprite_v_flip,  Prev: draw_sprite,  Up: Blitting

15.8 stretch_sprite
===================

void stretch_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y, int w, int h);
     Like draw_sprite(), except it can stretch the sprite image to the
     specified width and height and requires the sprite image and
     destination bitmap to be of the same color depth. Moreover, the
     sprite image must be a memory bitmap.

See also:
*Note draw_sprite::.
*Note stretch_blit::.
*Note bitmap_mask_color::.
*Note BITMAP::.

File: allegro.info,  Node: draw_sprite_v_flip,  Next: draw_trans_sprite,  Prev: stretch_sprite,  Up: Blitting

15.9 draw_sprite_v_flip
=======================

void draw_sprite_v_flip(BITMAP *bmp, BITMAP *sprite, int x, int y);

void draw_sprite_h_flip(BITMAP *bmp, BITMAP *sprite, int x, int y);

void draw_sprite_vh_flip(BITMAP *bmp, BITMAP *sprite, int x, int y);
     These are like draw_sprite(), but they flip the image about the
     vertical, horizontal, or both, axes. This produces exact mirror
     images, which is not the same as rotating the sprite (and it is a
     lot faster than the rotation routine). The sprite must be a memory
     bitmap.

See also:
*Note draw_sprite::.
*Note bitmap_mask_color::.
*Note exsprite::.
*Note BITMAP::.

File: allegro.info,  Node: draw_trans_sprite,  Next: draw_lit_sprite,  Prev: draw_sprite_v_flip,  Up: Blitting

15.10 draw_trans_sprite
=======================

void draw_trans_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y);
     Uses the global color_map table or truecolor blender functions to
     overlay the sprite on top of the existing image. This must only be
     used after you have set up the color mapping table (for 256-color
     modes) or blender functions (for truecolor modes). Because it
     involves reading as well as writing the bitmap memory, translucent
     drawing is very slow if you draw directly to video RAM, so
     wherever possible you should use a memory bitmap instead. The
     bitmap and sprite must normally be in the same color depth, but as
     a special case you can draw 32 bit RGBA format sprites onto any
     hicolor or truecolor bitmap, as long as you call
     set_alpha_blender() first, and you can draw 8-bit alpha images
     onto a 32-bit RGBA destination, as long as you call
     set_write_alpha_blender() first.  As draw_sprite() this function
     skips transparent pixels, except if the source sprite is an 8-bit
     image; if this is the case, you should pay attention to properly
     set up your color map table for index 0.

See also:
*Note draw_sprite::.
*Note draw_lit_sprite::.
*Note draw_trans_rle_sprite::.
*Note color_map::.
*Note set_trans_blender::.
*Note set_alpha_blender::.
*Note set_write_alpha_blender::.
*Note bitmap_mask_color::.
*Note exalpha::.
*Note exblend::.
*Note exlights::.
*Note extrans::.
*Note exxfade::.
*Note BITMAP::.

File: allegro.info,  Node: draw_lit_sprite,  Next: draw_gouraud_sprite,  Prev: draw_trans_sprite,  Up: Blitting

15.11 draw_lit_sprite
=====================

void draw_lit_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y, int color);
     In 256-color modes, uses the global color_map table to tint the
     sprite image to the specified color or to light it to the level
     specified by 'color', depending on the function which was used to
     build the table (create_trans_table or create_light_table), and
     draws the resulting image to the destination bitmap. In truecolor
     modes, uses the blender functions to light the sprite image using
     the alpha level specified by 'color' (the alpha level which was
     passed to the blender functions is ignored) and draws the
     resulting image to the destination bitmap. The 'color' parameter
     must be in the range [0-255] whatever its actual meaning is. This
     must only be used after you have set up the color mapping table
     (for 256-color modes) or blender functions (for truecolor modes).

See also:
*Note draw_sprite::.
*Note draw_trans_sprite::.
*Note draw_gouraud_sprite::.
*Note draw_lit_rle_sprite::.
*Note color_map::.
*Note set_trans_blender::.
*Note bitmap_mask_color::.
*Note exblend::.
*Note BITMAP::.

File: allegro.info,  Node: draw_gouraud_sprite,  Next: draw_character_ex,  Prev: draw_lit_sprite,  Up: Blitting

15.12 draw_gouraud_sprite
=========================

void draw_gouraud_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y, int c1, int c2, int c3, int c4);
     More sophisticated version of draw_lit_sprite(): the 'color'
     parameter is not constant across the sprite image anymore but
     interpolated between the four specified corner colors, which have
     the same actual meaning as it.

See also:
*Note draw_sprite::.
*Note draw_lit_sprite::.
*Note color_map::.
*Note set_trans_blender::.
*Note bitmap_mask_color::.
*Note BITMAP::.

File: allegro.info,  Node: draw_character_ex,  Next: rotate_sprite,  Prev: draw_gouraud_sprite,  Up: Blitting

15.13 draw_character_ex
=======================

void draw_character_ex(BITMAP *bmp, BITMAP *sprite, int x, int y, color, bg);
     Draws a copy of the sprite bitmap onto the destination bitmap at
     the specified position, drawing transparent pixels in the
     background color (or skipping them if the background color is -1)
     and setting all other pixels to the specified color. Transparent
     pixels are marked by a zero in 256-color modes or bright pink for
     truecolor data (maximum red and blue, zero green). The sprite must
     be an 8-bit image, even if the destination is a truecolor bitmap.

See also:
*Note draw_sprite::.
*Note bitmap_mask_color::.
*Note BITMAP::.

File: allegro.info,  Node: rotate_sprite,  Next: rotate_sprite_v_flip,  Prev: draw_character_ex,  Up: Blitting

15.14 rotate_sprite
===================

void rotate_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y, fixed angle);
     Draws the sprite image onto the bitmap. It is placed with its top
     left corner at the specified position, then rotated by the
     specified angle around its centre. The angle is a fixed point
     16.16 number in the same format used by the fixed point trig
     routines, with 256 equal to a full circle, 64 a right angle, etc.
     All rotation functions can draw between any two bitmaps, even
     screen bitmaps or bitmaps of different color depth.

See also:
*Note draw_sprite::.
*Note rotate_scaled_sprite::.
*Note rotate_sprite_v_flip::.
*Note rotate_scaled_sprite_v_flip::.
*Note pivot_sprite::.
*Note pivot_sprite_v_flip::.
*Note pivot_scaled_sprite::.
*Note pivot_scaled_sprite_v_flip::.
*Note itofix::.
*Note Fixed point trig::.
*Note exsprite::.
*Note fixed::.
*Note BITMAP::.

File: allegro.info,  Node: rotate_sprite_v_flip,  Next: rotate_scaled_sprite,  Prev: rotate_sprite,  Up: Blitting

15.15 rotate_sprite_v_flip
==========================

void rotate_sprite_v_flip(BITMAP *bmp, BITMAP *sprite, int x, int y, fixed angle);
     Like rotate_sprite, but also flips the image vertically.  To flip
     horizontally, use this routine but add itofix(128) to the angle.
     To flip in both directions, use rotate_sprite() and add
     itofix(128) to its angle.

See also:
*Note rotate_sprite::.
*Note rotate_scaled_sprite_v_flip::.
*Note pivot_sprite_v_flip::.
*Note pivot_scaled_sprite_v_flip::.
*Note exsprite::.
*Note fixed::.
*Note BITMAP::.

File: allegro.info,  Node: rotate_scaled_sprite,  Next: rotate_scaled_sprite_v_flip,  Prev: rotate_sprite_v_flip,  Up: Blitting

15.16 rotate_scaled_sprite
==========================

void rotate_scaled_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y, fixed angle, fixed scale);
     Like rotate_sprite(), but stretches or shrinks the image at the
     same time as rotating it.

See also:
*Note rotate_sprite::.
*Note rotate_scaled_sprite_v_flip::.
*Note pivot_scaled_sprite::.
*Note pivot_scaled_sprite_v_flip::.
*Note fixed::.
*Note BITMAP::.

File: allegro.info,  Node: rotate_scaled_sprite_v_flip,  Next: pivot_sprite,  Prev: rotate_scaled_sprite,  Up: Blitting

15.17 rotate_scaled_sprite_v_flip
=================================

void rotate_scaled_sprite_v_flip(BITMAP *bmp, BITMAP *sprite, int x, int y, fixed angle, fixed scale);
     Draws the sprite, similar to rotate_scaled_sprite() except that it
     flips the sprite vertically first.

See also:
*Note rotate_sprite::.
*Note rotate_scaled_sprite::.
*Note rotate_sprite_v_flip::.
*Note fixed::.
*Note BITMAP::.

File: allegro.info,  Node: pivot_sprite,  Next: pivot_sprite_v_flip,  Prev: rotate_scaled_sprite_v_flip,  Up: Blitting

15.18 pivot_sprite
==================

void pivot_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y, int cx, int cy, fixed angle);
     Like rotate_sprite(), but aligns the point in the sprite given by
     (cx, cy) to (x, y) in the bitmap, then rotates around this point.

See also:
*Note rotate_sprite::.
*Note pivot_scaled_sprite::.
*Note pivot_sprite_v_flip::.
*Note fixed::.
*Note BITMAP::.

File: allegro.info,  Node: pivot_sprite_v_flip,  Next: pivot_scaled_sprite,  Prev: pivot_sprite,  Up: Blitting

15.19 pivot_sprite_v_flip
=========================

void pivot_sprite_v_flip(BITMAP *bmp, BITMAP *sprite, int x, int y, int cx, int cy, fixed angle);
     Like rotate_sprite_v_flip(), but aligns the point in the sprite
     given by (cx, cy) to (x, y) in the bitmap, then rotates around
     this point.

See also:
*Note rotate_sprite::.
*Note rotate_sprite_v_flip::.
*Note pivot_sprite::.
*Note fixed::.
*Note BITMAP::.

File: allegro.info,  Node: pivot_scaled_sprite,  Next: pivot_scaled_sprite_v_flip,  Prev: pivot_sprite_v_flip,  Up: Blitting

15.20 pivot_scaled_sprite
=========================

void pivot_scaled_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y, int cx, int cy, fixed angle, fixed scale);
     Like rotate_scaled_sprite(), but aligns the point in the sprite
     given by (cx, cy) to (x, y) in the bitmap, then rotates and scales
     around this point.

See also:
*Note rotate_sprite::.
*Note rotate_scaled_sprite::.
*Note pivot_sprite::.
*Note pivot_scaled_sprite_v_flip::.
*Note fixed::.
*Note BITMAP::.

File: allegro.info,  Node: pivot_scaled_sprite_v_flip,  Next: get_rle_sprite,  Prev: pivot_scaled_sprite,  Up: Blitting

15.21 pivot_scaled_sprite_v_flip
================================

void pivot_scaled_sprite_v_flip(BITMAP *bmp, BITMAP *sprite, int x, int y, int cx, int cy, fixed angle, fixed scale);
     Like rotate_scaled_sprite_v_flip(), but aligns the point in the
     sprite given by (cx, cy) to (x, y) in the bitmap, then rotates and
     scales around this point.

See also:
*Note rotate_sprite::.
*Note rotate_scaled_sprite_v_flip::.
*Note rotate_sprite_v_flip::.
*Note pivot_sprite::.
*Note pivot_scaled_sprite::.
*Note fixed::.
*Note BITMAP::.

File: allegro.info,  Node: RLE,  Next: Compiled,  Prev: Blitting,  Up: Top

16 RLE sprites
**************

Because bitmaps can be used in so many different ways, the bitmap
structure is quite complicated, and it contains a lot of data. In many
situations, though, you will find yourself storing images that are only
ever copied to the screen, rather than being drawn onto or used as
filling patterns, etc.  If this is the case you may be better off
storing your images in RLE_SPRITE (read chapter "Structures and types
defined by Allegro" for an internal description of the RLE_SPRITE
structure) or COMPILED_SPRITE (see next chapter) structures rather than
regular bitmaps.

RLE sprites store the image in a simple run-length encoded format, where
repeated zero pixels are replaced by a single length count, and strings
of non-zero pixels are preceded by a counter giving the length of the
solid run. RLE sprites are usually much smaller than normal bitmaps,
both because of the run length compression, and because they avoid most
of the overhead of the bitmap structure. They are often also faster
than normal bitmaps, because rather than having to compare every single
pixel with zero to determine whether it should be drawn, it is possible
to skip over a whole run of zeros with a single add, or to copy a long
run of non-zero pixels with fast string instructions.

Every silver lining has a cloud, though, and in the case of RLE sprites
it is a lack of flexibility. You can't draw onto them, and you can't
flip them, rotate them, or stretch them. In fact the only thing you can
do with them is to blast them onto a bitmap with the draw_rle_sprite()
function, which is equivalent to using draw_sprite() with a regular
bitmap. You can convert bitmaps into RLE sprites at runtime, or you can
create RLE sprite structures in grabber datafiles by making a new
object of type 'RLE sprite'.

* Menu:

* get_rle_sprite::
* destroy_rle_sprite::
* draw_rle_sprite::
* draw_trans_rle_sprite::
* draw_lit_rle_sprite::


File: allegro.info,  Node: get_rle_sprite,  Next: destroy_rle_sprite,  Prev: pivot_scaled_sprite_v_flip,  Up: RLE

16.1 get_rle_sprite
===================

RLE_SPRITE *get_rle_sprite(BITMAP *bitmap);
     Creates an RLE sprite based on the specified bitmap (which must be
     a memory bitmap).

See also:
*Note draw_rle_sprite::.
*Note destroy_rle_sprite::.
*Note BITMAP::.
*Note RLE_SPRITE::.

File: allegro.info,  Node: destroy_rle_sprite,  Next: draw_rle_sprite,  Prev: get_rle_sprite,  Up: RLE

16.2 destroy_rle_sprite
=======================

void destroy_rle_sprite(RLE_SPRITE *sprite);
     Destroys an RLE sprite structure previously returned by
     get_rle_sprite().

See also:
*Note get_rle_sprite::.
*Note RLE_SPRITE::.

File: allegro.info,  Node: draw_rle_sprite,  Next: draw_trans_rle_sprite,  Prev: destroy_rle_sprite,  Up: RLE

16.3 draw_rle_sprite
====================

void draw_rle_sprite(BITMAP *bmp, const RLE_SPRITE *sprite, int x, int y);
     Draws an RLE sprite onto a bitmap at the specified position.

See also:
*Note get_rle_sprite::.
*Note draw_sprite::.
*Note draw_compiled_sprite::.
*Note draw_trans_rle_sprite::.
*Note draw_lit_rle_sprite::.
*Note bitmap_mask_color::.
*Note BITMAP::.
*Note RLE_SPRITE::.

File: allegro.info,  Node: draw_trans_rle_sprite,  Next: draw_lit_rle_sprite,  Prev: draw_rle_sprite,  Up: RLE

16.4 draw_trans_rle_sprite
==========================

void draw_trans_rle_sprite(BITMAP *bmp, const RLE_SPRITE *sprite, int x, int y);
     Translucent version of draw_rle_sprite(). See the description of
     draw_trans_sprite(). This must only be used after you have set up
     the color mapping table (for 256-color modes) or blender functions
     (for truecolor modes). The bitmap and sprite must normally be in
     the same color depth, but as a special case you can draw 32-bit
     RGBA format sprites onto any hicolor or truecolor bitmap, as long
     as you call set_alpha_blender() first.

See also:
*Note draw_rle_sprite::.
*Note draw_lit_rle_sprite::.
*Note draw_trans_sprite::.
*Note color_map::.
*Note set_trans_blender::.
*Note set_alpha_blender::.
*Note bitmap_mask_color::.
*Note BITMAP::.
*Note RLE_SPRITE::.

File: allegro.info,  Node: draw_lit_rle_sprite,  Next: get_compiled_sprite,  Prev: draw_trans_rle_sprite,  Up: RLE

16.5 draw_lit_rle_sprite
========================

void draw_lit_rle_sprite(BITMAP *bmp, const RLE_SPRITE *sprite, int x, y, color);
     Tinted version of draw_rle_sprite(). See the description of
     draw_lit_sprite(). This must only be used after you have set up
     the color mapping table (for 256-color modes) or blender functions
     (for truecolor modes).

See also:
*Note draw_rle_sprite::.
*Note draw_trans_rle_sprite::.
*Note draw_lit_sprite::.
*Note color_map::.
*Note set_trans_blender::.
*Note bitmap_mask_color::.
*Note BITMAP::.
*Note RLE_SPRITE::.

File: allegro.info,  Node: Compiled,  Next: Text,  Prev: RLE,  Up: Top

17 Compiled sprites
*******************

Compiled sprites are stored as actual machine code instructions that
draw a specific image onto a bitmap, using mov instructions with
immediate data values. This is the fastest way to draw a masked image:
on slow machines, up to and including a 486, drawing compiled sprites
can be about to five times as fast as using draw_sprite() with a
regular bitmap. On newer machines the difference is usually negligible.

Compiled sprites are big, so if memory is tight you should use RLE
sprites instead, and what you can do with them is even more restricted
than with RLE sprites, because they don't support clipping. If you try
to draw one off the edge of a bitmap, you will corrupt memory and
probably crash the system. You can convert bitmaps into compiled
sprites at runtime, or you can create compiled sprite structures in
grabber datafiles by making a new object of type 'Compiled sprite' or
'Compiled x-sprite'.

* Menu:

* get_compiled_sprite::
* destroy_compiled_sprite::
* draw_compiled_sprite::


File: allegro.info,  Node: get_compiled_sprite,  Next: destroy_compiled_sprite,  Prev: draw_lit_rle_sprite,  Up: Compiled

17.1 get_compiled_sprite
========================

COMPILED_SPRITE *get_compiled_sprite(BITMAP *bitmap, int planar);
     Creates a compiled sprite based on the specified bitmap (which
     must be a memory bitmap). Compiled sprites are device-dependent,
     so you have to specify whether to compile it into a linear or
     planar format. Pass FALSE as the second parameter if you are going
     to be drawing it onto memory bitmaps or mode 13h and SVGA screen
     bitmaps, and pass TRUE if you are going to draw it onto mode-X or
     Xtended mode screen bitmaps.

See also:
*Note draw_compiled_sprite::.
*Note destroy_compiled_sprite::.
*Note BITMAP::.
*Note COMPILED_SPRITE::.

File: allegro.info,  Node: destroy_compiled_sprite,  Next: draw_compiled_sprite,  Prev: get_compiled_sprite,  Up: Compiled

17.2 destroy_compiled_sprite
============================

void destroy_compiled_sprite(COMPILED_SPRITE *sprite);
     Destroys a compiled sprite structure previously returned by
     get_compiled_sprite().

See also:
*Note get_compiled_sprite::.
*Note COMPILED_SPRITE::.

File: allegro.info,  Node: draw_compiled_sprite,  Next: font,  Prev: destroy_compiled_sprite,  Up: Compiled

17.3 draw_compiled_sprite
=========================

void draw_compiled_sprite(BITMAP *bmp, const COMPILED_SPRITE *sprite, int x, int y);
     Draws a compiled sprite onto a bitmap at the specified position.
     The sprite must have been compiled for the correct type of bitmap
     (linear or planar). This function does not support clipping.

     Hint: if not being able to clip compiled sprites is a problem, a
     neat trick is to set up a work surface (memory bitmap, mode-X
     virtual screen, or whatever) a bit bigger than you really need,
     and use the middle of it as your screen. That way you can draw
     slightly off the edge without any trouble...

See also:
*Note get_compiled_sprite::.
*Note draw_sprite::.
*Note draw_rle_sprite::.
*Note bitmap_mask_color::.
*Note BITMAP::.
*Note COMPILED_SPRITE::.

File: allegro.info,  Node: Text,  Next: Polygon,  Prev: Compiled,  Up: Top

18 Text output
**************

Allegro provides text output routines that work with both monochrome and
color fonts, which can contain any number of Unicode character ranges.
The grabber program can create fonts from sets of characters drawn in a
bitmap file (see grabber.txt for more information), and can also import
GRX or BIOS format font files. The font structure contains a number of
hooks that can be used to extend it with your own custom drawing code:
see the definition in allegro/text.h for details.

* Menu:

* font::
* allegro_404_char::
* text_length::
* text_height::
* destroy_font::
* textout_ex::
* textout_centre_ex::
* textout_right_ex::
* textout_justify_ex::
* textprintf_ex::
* textprintf_centre_ex::
* textprintf_right_ex::
* textprintf_justify_ex::


File: allegro.info,  Node: font,  Next: allegro_404_char,  Prev: draw_compiled_sprite,  Up: Text

18.1 font
=========

extern FONT *font;
     A simple 8x8 fixed size font (the mode 13h BIOS default). If you
     want to alter the font used by the GUI routines, change this to
     point to one of your own fonts. This font contains the standard
     ASCII (U+20 to U+7F), Latin-1 (U+A1 to U+FF), and Latin Extended-A
     (U+0100 to U+017F) character ranges.

See also:
*Note textout_ex::.
*Note textprintf_ex::.
*Note Available Allegro examples: Available.
*Note FONT::.

File: allegro.info,  Node: allegro_404_char,  Next: text_length,  Prev: font,  Up: Text

18.2 allegro_404_char
=====================

extern int allegro_404_char;
     When Allegro cannot find a glyph it needs in a font, it will
     instead output the character given in allegro_404_char. By
     default, this is set to the caret symbol, '^'.

See also:
*Note font::.

File: allegro.info,  Node: text_length,  Next: text_height,  Prev: allegro_404_char,  Up: Text

18.3 text_length
================

int text_length(const FONT *f, const char *str);
     Returns the length (in pixels) of a string in the specified font.

See also:
*Note text_height::.
*Note ex12bit::.
*Note expat::.
*Note exunicod::.
*Note FONT::.

File: allegro.info,  Node: text_height,  Next: destroy_font,  Prev: text_length,  Up: Text

18.4 text_height
================

int text_height(const FONT *f)
     Returns the height (in pixels) of the specified font.

See also:
*Note text_length::.
*Note ex12bit::.
*Note expat::.
*Note exunicod::.
*Note FONT::.

File: allegro.info,  Node: destroy_font,  Next: textout_ex,  Prev: text_height,  Up: Text

18.5 destroy_font
=================

void destroy_font(FONT *f);
     Frees the memory being used by a font structure.

*Note FONT::.

File: allegro.info,  Node: textout_ex,  Next: textout_centre_ex,  Prev: destroy_font,  Up: Text

18.6 textout_ex
===============

void textout_ex(BITMAP *bmp, const FONT *f, const char *s, int x, y, color, bg);
     Writes the string s onto the bitmap at position x, y, using the
     specified font, foreground color and background color. If the
     background color is -1, then the text is written transparently. If
     the foreground color is -1 and a color font is in use, it will be
     drawn using the colors from the original font bitmap (the one you
     imported into the grabber program), which allows multicolored text
     output.

See also:
*Note font::.
*Note textout_centre_ex::.
*Note textout_right_ex::.
*Note textout_justify_ex::.
*Note textprintf_ex::.
*Note text_height::.
*Note text_length::.
*Note BITMAP::.
*Note FONT::.

File: allegro.info,  Node: textout_centre_ex,  Next: textout_right_ex,  Prev: textout_ex,  Up: Text

18.7 textout_centre_ex
======================

void textout_centre_ex(BITMAP *bmp, const FONT *f, const char *s, int x, y, color, bg);
     Like textout_ex(), but interprets the x coordinate as the centre
     rather than the left edge of the string.

See also:
*Note textout_ex::.
*Note textprintf_centre_ex::.
*Note BITMAP::.
*Note FONT::.

File: allegro.info,  Node: textout_right_ex,  Next: textout_justify_ex,  Prev: textout_centre_ex,  Up: Text

18.8 textout_right_ex
=====================

void textout_right_ex(BITMAP *bmp, const FONT *f, const char *s, int x, y, color, bg);
     Like textout_ex(), but interprets the x coordinate as the right
     rather than the left edge of the string.

See also:
*Note textout_ex::.
*Note textprintf_right_ex::.
*Note BITMAP::.
*Note FONT::.

File: allegro.info,  Node: textout_justify_ex,  Next: textprintf_ex,  Prev: textout_right_ex,  Up: Text

18.9 textout_justify_ex
=======================

void textout_justify_ex(BITMAP *bmp, const FONT *f, const char *s, int x1, x2, y, diff, color, bg);
     Draws justified text within the region x1-x2. If the amount of
     spare space is greater than the diff value, it will give up and
     draw regular left justified text instead.

See also:
*Note textout_ex::.
*Note textprintf_justify_ex::.
*Note BITMAP::.
*Note FONT::.

File: allegro.info,  Node: textprintf_ex,  Next: textprintf_centre_ex,  Prev: textout_justify_ex,  Up: Text

18.10 textprintf_ex
===================

void textprintf_ex(BITMAP *bmp, const FONT *f, int x, y, color, bg, const char *fmt, ...);
     Formatted text output, using a printf() style format string. Due
     to an intenal limitation, this function can't be used for
     extremely long texts.  If you happen to reach this limit, you can
     work around it by using uszprintf and textout_ex, which don't have
     any.

See also:
*Note font::.
*Note textout_ex::.
*Note textprintf_centre_ex::.
*Note textprintf_right_ex::.
*Note textprintf_justify_ex::.
*Note text_height::.
*Note text_length::.
*Note uszprintf::.
*Note BITMAP::.
*Note FONT::.

File: allegro.info,  Node: textprintf_centre_ex,  Next: textprintf_right_ex,  Prev: textprintf_ex,  Up: Text

18.11 textprintf_centre_ex
==========================

void textprintf_centre_ex(BITMAP *bmp, const FONT *f, int x, y, color, bg, const char *fmt, ...);
     Like textprintf_ex(), but interprets the x coordinate as the
     centre rather than the left edge of the string. This function
     shares the text length limitation of textprintf_ex.

See also:
*Note textprintf_ex::.
*Note textout_centre_ex::.
*Note BITMAP::.
*Note FONT::.

File: allegro.info,  Node: textprintf_right_ex,  Next: textprintf_justify_ex,  Prev: textprintf_centre_ex,  Up: Text

18.12 textprintf_right_ex
=========================

void textprintf_right_ex(BITMAP *bmp, const FONT *f, int x, y, color, bg, const char *fmt, ...);
     Like textprintf_ex(), but interprets the x coordinate as the right
     rather than the left edge of the string. This function shares the
     text length limitation of textprintf_ex.

See also:
*Note textprintf_ex::.
*Note textout_right_ex::.
*Note BITMAP::.
*Note FONT::.

File: allegro.info,  Node: textprintf_justify_ex,  Next: polygon3d,  Prev: textprintf_right_ex,  Up: Text

18.13 textprintf_justify_ex
===========================

void textprintf_justify_ex(BITMAP *bmp, const FONT *f, int x1, x2, y, diff, color, bg, const char *fmt, ...);
     Like textout_justify_ex(), but using a printf() style format
     string. This function shares the text length limitation of
     textprintf_ex.

See also:
*Note textprintf_ex::.
*Note textout_justify_ex::.
*Note BITMAP::.
*Note FONT::.

File: allegro.info,  Node: Polygon,  Next: Transparency,  Prev: Text,  Up: Top

19 Polygon rendering
********************

* Menu:

* polygon3d::
* triangle3d::
* quad3d::
* clip3d_f::
* clip3d::
* Zbuffered rendering::
* create_zbuffer::
* create_sub_zbuffer::
* set_zbuffer::
* clear_zbuffer::
* destroy_zbuffer::
* Scene rendering::
* create_scene::
* clear_scene::
* destroy_scene::
* scene_polygon3d::
* render_scene::
* scene_gap::


File: allegro.info,  Node: polygon3d,  Next: triangle3d,  Prev: textprintf_justify_ex,  Up: Polygon

19.1 polygon3d
==============

void polygon3d(BITMAP *bmp, int type, BITMAP *texture, int vc, V3D *vtx[]);

void polygon3d_f(BITMAP *bmp, int type, BITMAP *texture, int vc, V3D_f *vtx[]);
     Draw 3d polygons onto the specified bitmap, using the specified
     rendering mode. Unlike the regular polygon() function, these
     routines don't support concave or self-intersecting shapes, and
     they can't draw onto mode-X screen bitmaps (if you want to write
     3d code in mode-X, draw onto a memory bitmap and then blit to the
     screen). The width and height of the texture bitmap must be powers
     of two, but can be different, eg. a 64x16 texture is fine, but a
     17x3 one is not. The vertex count parameter (vc) should be
     followed by an array containing the appropriate number of pointers
     to vertex structures: polygon3d() uses the fixed point V3D
     structure, while polygon3d_f() uses the floating point V3D_f
     structure.  These are defined as:

          typedef struct V3D
          {
             fixed x, y, z;       - position
             fixed u, v;          - texture map coordinates
             int c;               - color
          } V3D;

          typedef struct V3D_f
          {
             float x, y, z;       - position
             float u, v;          - texture map coordinates
             int c;               - color
          } V3D_f;

     How the vertex data is used depends on the rendering mode:

     The x and y values specify the position of the vertex in 2d screen
     coordinates.

     The z value is only required when doing perspective correct texture
     mapping, and specifies the depth of the point in 3d world
     coordinates.

     The u and v coordinates are only required when doing texture
     mapping, and specify a point on the texture plane to be mapped on
     to this vertex. The texture plane is an infinite plane with the
     texture bitmap tiled across it. Each vertex in the polygon has a
     corresponding vertex on the texture plane, and the image of the
     resulting polygon in the texture plane will be mapped on to the
     polygon on the screen.

     We refer to pixels in the texture plane as texels. Each texel is a
     block, not just a point, and whole numbers for u and v refer to
     the top-left corner of a texel. This has a few implications. If
     you want to draw a rectangular polygon and map a texture sized
     32x32 on to it, you would use the texture coordinates (0,0),
     (0,32), (32,32) and (32,0), assuming the vertices are specified in
     anticlockwise order. The texture will then be mapped perfectly on
     to the polygon. However, note that when we set u=32, the last
     column of texels seen on the screen is the one at u=31, and the
     same goes for v. This is because the coordinates refer to the
     top-left corner of the texels. In effect, texture coordinates at
     the right and bottom on the texture plane are exclusive.

     There is another interesting point here. If you have two polygons
     side by side sharing two vertices (like the two parts of folded
     piece of cardboard), and you want to map a texture across them
     seamlessly, the values of u and v on the vertices at the join will
     be the same for both polygons. For example, if they are both
     rectangular, one polygon may use (0,0), (0,32), (32,32) and
     (32,0), and the other may use (32,0), (32,32), (64,32), (64,0).
     This would create a seamless join.

     Of course you can specify fractional numbers for u and v to
     indicate a point part-way across a texel. In addition, since the
     texture plane is infinite, you can specify larger values than the
     size of the texture.  This can be used to tile the texture several
     times across the polygon.

     The c value specifies the vertex color, and is interpreted
     differently by various rendering modes.

     The type parameter specifies the polygon rendering mode, and can
     be any of the values:

     POLYTYPE_FLAT:
     A simple flat shaded polygon, taking the color from the c value of
     the first vertex. This polygon type is affected by the
     drawing_mode() function, so it can be used to render XOR or
     translucent polygons.

     POLYTYPE_GCOL:
     A single-color gouraud shaded polygon. The colors for each vertex
     are taken from the c value, and interpolated across the polygon.
     This is very fast, but will only work in 256-color modes if your
     palette contains a smooth gradient between the colors. In
     truecolor modes it interprets the color as a packed,
     display-format value as produced by the makecol() function.

     POLYTYPE_GRGB:
     A gouraud shaded polygon which interpolates RGB triplets rather
     than a single color. In 256-color modes this uses the global
     rgb_map table to convert the result to an 8-bit paletted color, so
     it must only be used after you have set up the RGB mapping table!
     The colors for each vertex are taken from the c value, which is
     interpreted as a 24-bit RGB triplet (0xFF0000 is red, 0x00FF00 is
     green, and 0x0000FF is blue).

     POLYTYPE_ATEX:
     An affine texture mapped polygon. This stretches the texture across
     the polygon with a simple 2d linear interpolation, which is fast
     but not mathematically correct. It can look ok if the polygon is
     fairly small or flat-on to the camera, but because it doesn't deal
     with perspective foreshortening, it can produce strange warping
     artifacts.  To see what I mean, run test.exe and see what happens
     to the polygon3d() test when you zoom in very close to the cube.

     POLYTYPE_PTEX:
     A perspective-correct texture mapped polygon. This uses the z value
     from the vertex structure as well as the u/v coordinates, so
     textures are displayed correctly regardless of the angle they are
     viewed from.  Because it involves division calculations in the
     inner texture mapping loop, this mode is a lot slower than
     POLYTYPE_ATEX, and it uses floating point so it will be very slow
     on anything less than a Pentium (even with an FPU, a 486 can't
     overlap floating point division with other integer operations like
     the Pentium can).

     POLYTYPE_ATEX_MASK:
     POLYTYPE_PTEX_MASK:
     Like POLYTYPE_ATEX and POLYTYPE_PTEX, but zero texture map pixels
     are skipped, allowing parts of the texture map to be transparent.

     POLYTYPE_ATEX_LIT:
     POLYTYPE_PTEX_LIT:
     Like POLYTYPE_ATEX and POLYTYPE_PTEX, but the global color_map
     table (for 256-color modes) or blender function (for non-MMX
     truecolor modes) is used to blend the texture with a light level
     taken from the c value in the vertex structure. This must only be
     used after you have set up the color mapping table or blender
     functions!

     POLYTYPE_ATEX_MASK_LIT:
     POLYTYPE_PTEX_MASK_LIT:
     Like POLYTYPE_ATEX_LIT and POLYTYPE_PTEX_LIT, but zero texture map
     pixels are skipped, allowing parts of the texture map to be
     transparent.

     POLYTYPE_ATEX_TRANS:
     POLYTYPE_PTEX_TRANS:
     Render translucent textures. All the general rules for drawing
     translucent things apply. However, these modes have a major
     limitation: they only work with memory bitmaps or linear frame
     buffers (not with banked frame buffers). Don't even try, they do
     not check and your program will die horribly (or at least draw
     wrong things).

     POLYTYPE_ATEX_MASK_TRANS:
     POLYTYPE_PTEX_MASK_TRANS:
     Like POLYTYPE_ATEX_TRANS and POLYTYPE_PTEX_TRANS, but zero texture
     map pixels are skipped.

     If the CPU_MMX flag of the cpu_capabilities global variable is
     set, the GRGB and truecolor *LIT routines will be optimised using
     MMX instructions. If the CPU_3DNOW flag is set, the truecolor
     PTEX*LIT routines will take advantage of the 3DNow! CPU extensions.

     Using MMX for *LIT routines has a side effect: normally (without
     MMX), these routines use the blender functions used also for other
     lighting functions, set with set_trans_blender() or
     set_blender_mode(). The MMX versions only use the RGB value passed
     to set_trans_blender() and do the linear interpolation themselves.
     Therefore a new set of blender functions passed to
     set_blender_mode() is ignored.

See also:
*Note triangle3d::.
*Note quad3d::.
*Note polygon::.
*Note clip3d::.
*Note cpu_capabilities::.
*Note excamera::.
*Note BITMAP::.
*Note V3D::.
*Note V3D_f::.

File: allegro.info,  Node: triangle3d,  Next: quad3d,  Prev: polygon3d,  Up: Polygon

19.2 triangle3d
===============

void triangle3d(BITMAP *bmp, int type, BITMAP *tex, V3D *v1, *v2, *v3);

void triangle3d_f(BITMAP *bmp, int type, BITMAP *tex, V3D_f *v1, *v2, *v3);
     Draw 3d triangles, using either fixed or floating point vertex
     structures.  Unlike quad3d[_f], triangle3d[_f] functions are not
     wrappers of polygon3d[_f]. The triangle3d[_f] functions use their
     own routines taking into account the constantness of the gradients.
     Therefore triangle3d[_f](bmp, type, tex, v1, v2, v3) is faster than
     polygon3d[_f](bmp, type, tex, 3, v[]).

See also:
*Note polygon3d::.
*Note quad3d::.
*Note triangle::.
*Note BITMAP::.
*Note V3D::.
*Note V3D_f::.

File: allegro.info,  Node: quad3d,  Next: clip3d_f,  Prev: triangle3d,  Up: Polygon

19.3 quad3d
===========

void quad3d(BITMAP *bmp, int type, BITMAP *tex, V3D *v1, *v2, *v3, *v4);

void quad3d_f(BITMAP *bmp, int type, BITMAP *tex, V3D_f *v1, *v2, *v3, *v4);
     Draw 3d quads, using either fixed or floating point vertex
     structures.  These are equivalent to calling polygon3d(bmp, type,
     tex, 4, v[]); or polygon3d_f(bmp, type, tex, 4, v[]);

See also:
*Note polygon3d::.
*Note triangle3d::.
*Note ex3d::.
*Note BITMAP::.
*Note V3D::.
*Note V3D_f::.

File: allegro.info,  Node: clip3d_f,  Next: clip3d,  Prev: quad3d,  Up: Polygon

19.4 clip3d_f
=============

int clip3d_f(int type, float min_z, float max_z, int vc, const V3D_f *vtx[], V3D_f *vout[], V3D_f *vtmp[], int out[]);
     Clips the polygon given in vtx. The number of vertices is vc, the
     result goes in vout, and vtmp and out are needed for internal
     purposes. The pointers in vtx, vout and vtmp must point to valid
     V3D_f structures.  As additional vertices may appear in the
     process of clipping, so the size of vout, vtmp and out should be
     at least vc * (1.5 ^ n), where n is the number of clipping planes
     (5 or 6), and '^' denotes "to the power of".  The frustum (viewing
     volume) is defined by -z<x<z, -z<y<z, 0<min_z<z<max_z. If
     max_z<=min_z, the z<max_z clipping is not done. As you can see,
     clipping is done in the camera space, with perspective in mind, so
     this routine should be called after you apply the camera matrix,
     but before the perspective projection. The routine will correctly
     interpolate u, v, and c in the vertex structure. However, no
     provision is made for high/truecolor GCOL.

See also:
*Note polygon3d::.
*Note clip3d::.
*Note V3D_f::.

File: allegro.info,  Node: clip3d,  Next: Zbuffered rendering,  Prev: clip3d_f,  Up: Polygon

19.5 clip3d
===========

int clip3d(int type, fixed min_z, fixed max_z, int vc, const V3D *vtx[], V3D *vout[], V3D *vtmp[], int out[]);
     Fixed point version of clip3d_f(). This function should be used
     with caution, due to the limited precision of fixed point
     arithmetic and high chance of rounding errors: the floating point
     code is better for most situations.

See also:
*Note polygon3d::.
*Note clip3d_f::.
*Note fixed::.
*Note V3D::.

File: allegro.info,  Node: Zbuffered rendering,  Next: create_zbuffer,  Prev: clip3d,  Up: Polygon

19.6 Zbuffered rendering
========================

A Z-buffer stores the depth of each pixel that is drawn on a viewport.
When a 3D object is rendered, the depth of each of its pixels is
compared against the value stored into the Z-buffer: if the pixel is
closer it is drawn, otherwise it is skipped.

No polygon sorting is needed. However, backface culling should be done
because it prevents many invisible polygons being compared against the
Z-buffer. Z-buffered rendering is the only algorithm supported by
Allegro that directly solves penetrating shapes (see example exzbuf.c,
for instance).  The price to pay is more complex (and slower) routines.

Z-buffered polygons are designed as an extension of the normal
POLYTYPE_* rendering styles. Just OR the POLYTYPE with the value
POLYTYPE_ZBUF, and the normal polygon3d(), polygon3d_f(), quad3d(),
etc. functions will render z-buffered polygons.

Example:

     polygon3d(bmp, POLYTYPE_ATEX | POLYTYPE_ZBUF, tex, vc, vtx);

Of course, the z coordinates have to be valid regardless of rendering
style.

A Z-buffered rendering procedure looks like a double-buffered rendering
procedure. You should follow four steps: create a Z-buffer at the
beginning of the program and make the library use it by calling
set_zbuffer(). Then, for each frame, clear the Z-buffer and draw
polygons with POLYTYPE_* | POLYTYPE_ZBUF and finally destroy the
Z-buffer when leaving the program.

Notes on Z-buffered renderers:

   * Unlike the normal POLYTYPE_FLAT renderers, the Z-buffered ones
     don't use the hline() routine. Therefore DRAW_MODE has no effect.

   * The *LIT* routines work the traditional way - through the set of
     blender routines.

   * All the Z-buffered routines are much slower than their normal
     counterparts (they all use the FPU to interpolate and test 1/z
     values).


File: allegro.info,  Node: create_zbuffer,  Next: create_sub_zbuffer,  Prev: Zbuffered rendering,  Up: Polygon

19.7 create_zbuffer
===================

ZBUFFER *create_zbuffer(BITMAP *bmp);
     Creates a Z-buffer using the size of the BITMAP you are planning
     to draw on. Several Z-buffers can be defined but only one can be
     used at the same time, so you must call set_zbuffer() to make this
     Z-buffer active.

See also:
*Note create_sub_zbuffer::.
*Note set_zbuffer::.
*Note clear_zbuffer::.
*Note destroy_zbuffer::.
*Note exzbuf::.
*Note BITMAP::.
*Note ZBUFFER::.

File: allegro.info,  Node: create_sub_zbuffer,  Next: set_zbuffer,  Prev: create_zbuffer,  Up: Polygon

19.8 create_sub_zbuffer
=======================

ZBUFFER *create_sub_zbuffer(ZBUFFER *parent, int x, int y, int width, int height);
     Creates a sub-z-buffer, ie. a z-buffer sharing drawing memory with
     a pre-existing z-buffer, but possibly with a different size. The
     same rules as for sub-bitmaps apply: the sub-z-buffer width and
     height can extend beyond the right and bottom edges of the parent
     (they will be clipped), but the origin point must lie within the
     parent region.

     When drawing z-buffered to a bitmap, the top left corner of the
     bitmap is always mapped to the top left corner of the current
     z-buffer. So this function is primarily useful if you want to draw
     to a sub-bitmap and use the corresponding sub-area of the
     z-buffer. In other cases, eg. if you just want to draw to a
     sub-bitmap of screen (and not to other parts of screen), then you
     would usually want to create a normal z-buffer (not sub-z-buffer)
     the size of the visible screen. You don't need to first create a
     z-buffer the size of the virtual screen and then a sub-z-buffer of
     that.

See also:
*Note create_zbuffer::.
*Note create_sub_bitmap::.
*Note destroy_zbuffer::.
*Note ZBUFFER::.

File: allegro.info,  Node: set_zbuffer,  Next: clear_zbuffer,  Prev: create_sub_zbuffer,  Up: Polygon

19.9 set_zbuffer
================

void set_zbuffer(ZBUFFER *zbuf);
     Makes the given Z-buffer be the active one. This should have been
     previously created with create_zbuffer().

See also:
*Note create_zbuffer::.
*Note clear_zbuffer::.
*Note destroy_zbuffer::.
*Note exzbuf::.
*Note ZBUFFER::.

File: allegro.info,  Node: clear_zbuffer,  Next: destroy_zbuffer,  Prev: set_zbuffer,  Up: Polygon

19.10 clear_zbuffer
===================

void clear_zbuffer(ZBUFFER *zbuf, float z);
     Writes z into the given Z-buffer (0 means far away). This function
     should be used to initialize the Z-buffer before each frame.
     Actually, low-level routines compare depth of the current pixel
     with 1/z: for example, if you want to clip polygons farther than
     10, you must call clear_zbuffer(zbuf, 0.1);

See also:
*Note create_zbuffer::.
*Note set_zbuffer::.
*Note destroy_zbuffer::.
*Note exzbuf::.
*Note ZBUFFER::.

File: allegro.info,  Node: destroy_zbuffer,  Next: Scene rendering,  Prev: clear_zbuffer,  Up: Polygon

19.11 destroy_zbuffer
=====================

void destroy_zbuffer(ZBUFFER *zbuf);
     Destroys the Z-buffer when you are finished with it.

See also:
*Note create_zbuffer::.
*Note set_zbuffer::.
*Note clear_zbuffer::.
*Note exzbuf::.
*Note ZBUFFER::.

File: allegro.info,  Node: Scene rendering,  Next: create_scene,  Prev: destroy_zbuffer,  Up: Polygon

19.12 Scene rendering
=====================

Allegro provides two simple approaches to remove hidden surfaces:

   * Z-buffering - (see above)

   * Scan-line algorithms - along each scanline on your screen, you keep
     track of what polygons you are "in" and which is the nearest. This
     status changes only where the scanline crosses some polygon edge.
     So you have to juggle an edge list and a polygon list. And you
     have to sort the edges for each scanline (this can be countered by
     keeping the order of the previous scanline - it won't change
     much). The BIG advantage is that you write each pixel only once.
     If you have a lot of overlapping polygons you can get incredible
     speeds compared to any of the previous algorithms. This algorithm
     is covered by the *_scene routines.

The scene rendering has approximately the following steps:

   * Initialize the scene (set the clip area, clear the bitmap, blit a
     background, etc.)

   * Call clear_scene().

   * Transform all your points to camera space.

   * Clip polygons.

   * Project with persp_project() or persp_project_f().

   * "Draw" polygons with scene_polygon3d() and/or scene_polygon3d_f().
     This doesn't do any actual drawing, only initializes tables.

   * Render all the polygons defined previously to the bitmap with
     render_scene().

   * Overlay some non-3D graphics.

   * Show the bitmap (blit it to screen, flip the page, etc).

For each horizontal line in the viewport an x-sorted edge list is used
to keep track of what polygons are "in" and which is the nearest.
Vertical coherency is used - the edge list for a scanline is sorted
starting from the previous one - it won't change much. The scene
rendering routines use the same low-level asm routines as normal
polygon3d().

Notes on scene rendering:

   * Unlike polygon3d(), scene_polygon3d() requires valid z coordinates
     for all vertices, regardless of rendering style (unlike
     polygon3d(), which only uses z coordinate for *PTEX*).

   * All polygons passed to scene_polygon3d() have to be
     persp_project()'ed.

   * After render_scene() the mode is reset to SOLID.

Using a lot of *MASK* polygons drastically reduces performance, because
when a MASKed polygon is the first in line of sight, the polygons
underneath have to be drawn too. The same applies to FLAT polygons drawn
with DRAW_MODE_TRANS.

Z-buffered rendering works also within the scene renderer. It may be
helpful when you have a few intersecting polygons, but most of the
polygons may be safely rendered by the normal scanline sorting algo.
Same as before: just OR the POLYTYPE with POLYTYPE_ZBUF. Also, you have
to clear the z-buffer at the start of the frame. Example:

     clear_scene(buffer);
     if (some_polys_are_zbuf) clear_zbuffer(0.);
     while (polygons) {
        ...
        if (this_poly_is_zbuf) type |= POLYTYPE_ZBUF;
        scene_polygon3d(type, tex, vc, vtx);
     }
     render_scene();


File: allegro.info,  Node: create_scene,  Next: clear_scene,  Prev: Scene rendering,  Up: Polygon

19.13 create_scene
==================

int create_scene(int nedge, int npoly);
     Allocates memory for a scene, nedge and npoly are your estimates
     of how many edges and how many polygons you will render (you
     cannot get over the limit specified here). If you use same values
     in succesive calls, the space will be reused (no new malloc()).

     The memory allocated is a little less than 150 * (nedge + npoly)
     bytes.  Returns zero on success, or a negative number if
     allocations fail.

See also:
*Note scene_polygon3d::.
*Note render_scene::.
*Note clear_scene::.
*Note destroy_scene::.
*Note scene_gap::.
*Note create_zbuffer::.
*Note exscn3d::.

File: allegro.info,  Node: clear_scene,  Next: destroy_scene,  Prev: create_scene,  Up: Polygon

19.14 clear_scene
=================

void clear_scene(BITMAP *bmp);
     Initializes a scene. The bitmap is the bitmap you will eventually
     render on.

See also:
*Note create_scene::.
*Note scene_polygon3d::.
*Note render_scene::.
*Note destroy_scene::.
*Note scene_gap::.
*Note exscn3d::.
*Note BITMAP::.

File: allegro.info,  Node: destroy_scene,  Next: scene_polygon3d,  Prev: clear_scene,  Up: Polygon

19.15 destroy_scene
===================

void destroy_scene();
     Deallocate memory previously allocated by create_scene.

See also:
*Note create_scene::.
*Note scene_polygon3d::.
*Note clear_scene::.
*Note render_scene::.
*Note scene_gap::.
*Note exscn3d::.

File: allegro.info,  Node: scene_polygon3d,  Next: render_scene,  Prev: destroy_scene,  Up: Polygon

19.16 scene_polygon3d
=====================

int scene_polygon3d(int type, BITMAP *texture, int vc, V3D *vtx[]);

int scene_polygon3d_f(int type, BITMAP *texture, int vc, V3D_f *vtx[]);
     Puts a polygon in the rendering list. Nothing is really rendered
     at this moment. Should be called between clear_scene() and
     render_scene().

     Arguments are the same as for polygon3d(), except the bitmap is
     missing.  The one passed to clear_scene() will be used.

     Unlike polygon3d(), the polygon may be concave or
     self-intersecting.  Shapes that penetrate one another may look OK,
     but they are not really handled by this code.

     Note that the texture is stored as a pointer only, and you should
     keep the actual bitmap around until render_scene(), where it is
     used.

     Since the FLAT style is implemented with the low-level hline()
     funtion, the FLAT style is subject to DRAW_MODEs. All these modes
     are valid. Along with the polygon, this mode will be stored for
     the rendering moment, and also all the other related variables
     (color_map pointer, pattern pointer, anchor, blender values).

     The settings of the CPU_MMX and CPU_3DNOW flags of the
     cpu_capabilities global variable on entry in this routine affect
     the choice of low-level asm routine that will be used by
     render_scene() for this polygon.

     Returns zero on success, or a negative number if it won't be
     rendered for lack of a rendering routine.

See also:
*Note create_scene::.
*Note clear_scene::.
*Note render_scene::.
*Note destroy_scene::.
*Note polygon3d::.
*Note cpu_capabilities::.
*Note exscn3d::.
*Note BITMAP::.
*Note V3D::.
*Note V3D_f::.

File: allegro.info,  Node: render_scene,  Next: scene_gap,  Prev: scene_polygon3d,  Up: Polygon

19.17 render_scene
==================

void render_scene();
     Renders all the specified scene_polygon3d()'s on the bitmap passed
     to clear_scene(). Rendering is done one scanline at a time, with
     no pixel being processed more than once.

     Note that between clear_scene() and render_scene() you shouldn't
     change the clip rectangle of the destination bitmap. For speed
     reasons, you should set the clip rectangle to the minimum.

     Note also that all the textures passed to scene_polygon3d() are
     stored as pointers only and actually used in render_scene().

See also:
*Note create_scene::.
*Note clear_scene::.
*Note destroy_scene::.
*Note scene_gap::.
*Note scene_polygon3d::.
*Note exscn3d::.

File: allegro.info,  Node: scene_gap,  Next: drawing_mode,  Prev: render_scene,  Up: Polygon

19.18 scene_gap
===============

extern float scene_gap;
     This number (default value = 100.0) controls the behaviour of the
     z-sorting algorithm. When an edge is very close to another's
     polygon plane, there is an interval of uncertainty in which you
     cannot tell which object is visible (which z is smaller). This is
     due to cumulative numerical errors for edges that have undergone a
     lot of transformations and interpolations.

     The default value means that if the 1/z values (in projected space)
     differ by only 1/100 (one percent), they are considered to be
     equal and the x-slopes of the planes are used to find out which
     plane is getting closer when we move to the right.

     Larger values means narrower margins, and increasing the chance of
     missing true adjacent edges/planes. Smaller values means larger
     margins, and increasing the chance of mistaking close polygons for
     adjacent ones.  The value of 100 is close to the optimum. However,
     the optimum shifts slightly with resolution, and may be
     application-dependent. It is here for you to fine-tune.

See also:
*Note create_scene::.
*Note clear_scene::.
*Note destroy_scene::.
*Note render_scene::.
*Note scene_polygon3d::.

File: allegro.info,  Node: Transparency,  Next: Converting,  Prev: Polygon,  Up: Top

20 Transparency and patterned drawing
*************************************

* Menu:

* drawing_mode::
* xor_mode::
* solid_mode::
* 256-color transparency::
* color_map::
* create_trans_table::
* create_light_table::
* create_color_table::
* create_blender_table::
* Truecolor transparency::
* set_trans_blender::
* set_alpha_blender::
* set_write_alpha_blender::
* set_add_blender::
* set_burn_blender::
* set_color_blender::
* set_difference_blender::
* set_dissolve_blender::
* set_dodge_blender::
* set_hue_blender::
* set_invert_blender::
* set_luminance_blender::
* set_multiply_blender::
* set_saturation_blender::
* set_screen_blender::
* set_blender_mode::
* set_blender_mode_ex::


File: allegro.info,  Node: drawing_mode,  Next: xor_mode,  Prev: scene_gap,  Up: Transparency

20.1 drawing_mode
=================

void drawing_mode(int mode, BITMAP *pattern, int x_anchor, int y_anchor);
     Sets the graphics drawing mode. This only affects the geometric
     routines like putpixel, lines, rectangles, circles, polygons,
     floodfill, etc, not the text output, blitting, or sprite drawing
     functions. The mode should be one of the following constants:

          DRAW_MODE_SOLID               - the default, solid color
                                          drawing
          DRAW_MODE_XOR                 - exclusive-or drawing
          DRAW_MODE_COPY_PATTERN        - multicolored pattern fill
          DRAW_MODE_SOLID_PATTERN       - single color pattern fill
          DRAW_MODE_MASKED_PATTERN      - masked pattern fill
          DRAW_MODE_TRANS               - translucent color blending

     In DRAW_MODE_SOLID, pixels of the bitmap being drawn onto are
     simply replaced by those produced by the drawing function.

     In DRAW_MODE_XOR, pixels are written to the bitmap with an
     exclusive-or operation rather than a simple copy, so drawing the
     same shape twice will erase it. Because it involves reading as
     well as writing the bitmap memory, xor drawing is a lot slower
     than the normal replace mode.

     With the patterned modes, you provide a pattern bitmap which is
     tiled across the surface of the shape. Allegro stores a pointer to
     this bitmap rather than copying it, so you must not destroy the
     bitmap while it is still selected as the pattern. The width and
     height of the pattern must be powers of two, but they can be
     different, eg. a 64x16 pattern is fine, but a 17x3 one is not. The
     pattern is tiled in a grid starting at point (x_anchor, y_anchor).
     Normally you should just pass zero for these values, which lets
     you draw several adjacent shapes and have the patterns meet up
     exactly along the shared edges. Zero alignment may look peculiar
     if you are moving a patterned shape around the screen, however,
     because the shape will move but the pattern alignment will not, so
     in some situations you may wish to alter the anchor position.

     When you select DRAW_MODE_COPY_PATTERN, pixels are simply copied
     from the pattern bitmap onto the destination bitmap. This allows
     the use of multicolored patterns, and means that the color you
     pass to the drawing routine is ignored. This is the fastest of the
     patterned modes.

     In DRAW_MODE_SOLID_PATTERN, each pixel in the pattern bitmap is
     compared with the mask color, which is zero in 256-color modes or
     bright pink for truecolor data (maximum red and blue, zero green).
     If the pattern pixel is solid, a pixel of the color you passed to
     the drawing routine is written to the destination bitmap,
     otherwise a zero is written. The pattern is thus treated as a
     monochrome bitmask, which lets you use the same pattern to draw
     different shapes in different colors, but prevents the use of
     multicolored patterns.

     DRAW_MODE_MASKED_PATTERN is almost the same as
     DRAW_MODE_SOLID_PATTERN, but the masked pixels are skipped rather
     than being written as zeros, so the background shows through the
     gaps.

     In DRAW_MODE_TRANS, the global color_map table or truecolor blender
     functions are used to overlay pixels on top of the existing image.
     This must only be used after you have set up the color mapping
     table (for 256 color modes) or blender functions (for truecolor
     modes). Because it involves reading as well as writing the bitmap
     memory, translucent drawing is very slow if you draw directly to
     video RAM, so wherever possible you should use a memory bitmap
     instead.

See also:
*Note xor_mode::.
*Note solid_mode::.
*Note color_map::.
*Note set_trans_blender::.
*Note exalpha::.
*Note excolmap::.
*Note exjoy::.
*Note expat::.
*Note extrans::.
*Note BITMAP::.

File: allegro.info,  Node: xor_mode,  Next: solid_mode,  Prev: drawing_mode,  Up: Transparency

20.2 xor_mode
=============

void xor_mode(int on);
     This is a shortcut for toggling xor drawing mode on and off.
     Calling xor_mode(TRUE) is equivalent to drawing_mode
     (DRAW_MODE_XOR, NULL, 0, 0); Calling xor_mode(FALSE) is equivalent
     to drawing_mode(DRAW_MODE_SOLID, NULL, 0, 0);

See also:
*Note drawing_mode::.
*Note exspline::.
*Note exupdate::.

File: allegro.info,  Node: solid_mode,  Next: 256-color transparency,  Prev: xor_mode,  Up: Transparency

20.3 solid_mode
===============

void solid_mode();
     This is a shortcut for selecting solid drawing mode. It is
     equivalent to calling drawing_mode(DRAW_MODE_SOLID, NULL, 0, 0);

See also:
*Note drawing_mode::.
*Note exalpha::.
*Note expat::.

File: allegro.info,  Node: 256-color transparency,  Next: color_map,  Prev: solid_mode,  Up: Transparency

20.4 256-color transparency
===========================

In paletted video modes, translucency and lighting are implemented with
a 64k lookup table, which contains the result of combining any two
colors c1 and c2. You must set up this table before you use any of the
translucency or lighting routines. Depending on how you construct the
table, a range of different effects are possible. For example,
translucency can be implemented by using a color halfway between c1 and
c2 as the result of the combination.  Lighting is achieved by treating
one of the colors as a light level (0-255) rather than a color, and
setting up the table appropriately. A range of specialised effects are
possible, for instance replacing any color with any other color and
making individual source or destination colors completely solid or
invisible. Color mapping tables can be precalculated with the colormap
utility, or generated at runtime. Read chapter "Structures and types
defined by Allegro" for an internal description of the COLOR_MAP
structure.


File: allegro.info,  Node: color_map,  Next: create_trans_table,  Prev: 256-color transparency,  Up: Transparency

20.5 color_map
==============

extern COLOR_MAP *color_map;
     Global pointer to the color mapping table. This must be set before
     using any translucent or lit drawing functions in a 256-color
     video mode!

See also:
*Note create_color_table::.
*Note create_light_table::.
*Note create_trans_table::.
*Note create_blender_table::.
*Note set_trans_blender::.
*Note draw_trans_sprite::.
*Note draw_lit_sprite::.
*Note draw_gouraud_sprite::.
*Note drawing_mode::.
*Note ex3d::.
*Note excolmap::.
*Note exlights::.
*Note exshade::.
*Note extrans::.
*Note COLOR_MAP::.

File: allegro.info,  Node: create_trans_table,  Next: create_light_table,  Prev: color_map,  Up: Transparency

20.6 create_trans_table
=======================

void create_trans_table(COLOR_MAP *table, const PALETTE pal, int r, g, b, void (*callback)(int pos));
     Fills the specified color mapping table with lookup data for doing
     translucency effects with the specified palette. When combining the
     colors c1 and c2 with this table, the result will be a color
     somewhere between the two. The r, g, and b parameters specify the
     solidity of each color component, ranging from 0 (totally
     transparent) to 255 (totally solid). For 50% solidity, pass 128.
     This function treats source color #0 as a special case, leaving
     the destination unchanged whenever a zero source pixel is
     encountered, so that masked sprites will draw correctly.  If the
     callback function is not NULL, it will be called 256 times during
     the calculation, allowing you to display a progress indicator.

See also:
*Note color_map::.
*Note create_light_table::.
*Note create_color_table::.
*Note create_blender_table::.
*Note draw_trans_sprite::.
*Note draw_lit_sprite::.
*Note draw_gouraud_sprite::.
*Note PALETTE::.
*Note COLOR_MAP::.

File: allegro.info,  Node: create_light_table,  Next: create_color_table,  Prev: create_trans_table,  Up: Transparency

20.7 create_light_table
=======================

void create_light_table(COLOR_MAP *table, const PALETTE pal, int r, g, b, void (*callback)(int pos));
     Fills the specified color mapping table with lookup data for doing
     lighting effects with the specified palette. When combining the
     colors c1 and c2 with this table, c1 is treated as a light level
     from 0-255. At light level 255 the table will output color c2
     unchanged, at light level 0 it will output the r, g, b value you
     specify to this function, and at intermediate light levels it will
     output a color somewhere between the two extremes. The r, g, and b
     values are in the range 0-63. If the callback function is not
     NULL, it will be called 256 times during the calculation, allowing
     you to display a progress indicator.

See also:
*Note color_map::.
*Note create_trans_table::.
*Note create_color_table::.
*Note create_blender_table::.
*Note draw_trans_sprite::.
*Note draw_lit_sprite::.
*Note draw_gouraud_sprite::.
*Note PALETTE::.
*Note COLOR_MAP::.

File: allegro.info,  Node: create_color_table,  Next: create_blender_table,  Prev: create_light_table,  Up: Transparency

20.8 create_color_table
=======================

void create_color_table(COLOR_MAP *table, const PALETTE pal, void (*blend)(PALETTE pal, int x, int y, RGB *rgb), void (*callback)(int pos));
     Fills the specified color mapping table with lookup data for doing
     customised effects with the specified palette, calling the blend
     function to determine the results of each color combination. Your
     blend routine will be passed a pointer to the palette and the two
     colors which are to be combined, and should fill in the RGB
     structure with the desired result in 0-63 format. Allegro will
     then search the palette for the closest match to the RGB color
     that you requested, so it doesn't matter if the palette has no
     exact match for this color. If the callback function is not NULL,
     it will be called 256 times during the calculation, allowing you
     to display a progress indicator.

See also:
*Note color_map::.
*Note create_light_table::.
*Note create_trans_table::.
*Note create_blender_table::.
*Note draw_trans_sprite::.
*Note draw_lit_sprite::.
*Note draw_gouraud_sprite::.
*Note PALETTE::.
*Note RGB::.
*Note COLOR_MAP::.

File: allegro.info,  Node: create_blender_table,  Next: Truecolor transparency,  Prev: create_color_table,  Up: Transparency

20.9 create_blender_table
=========================

void create_blender_table(COLOR_MAP *table, const PALETTE pal, void (*callback)(int pos));
     Fills the specified color mapping table with lookup data for doing
     a paletted equivalent of whatever truecolor blender mode is
     currently selected. After calling set_trans_blender(),
     set_blender_mode(), or any of the other truecolor blender mode
     routines, you can use this function to create an 8-bit mapping
     table that will have the same results as whatever 24-bit blending
     mode you have enabled.

See also:
*Note color_map::.
*Note create_light_table::.
*Note create_trans_table::.
*Note create_color_table::.
*Note draw_trans_sprite::.
*Note draw_lit_sprite::.
*Note draw_gouraud_sprite::.
*Note set_trans_blender::.
*Note set_blender_mode::.
*Note PALETTE::.
*Note COLOR_MAP::.

File: allegro.info,  Node: Truecolor transparency,  Next: set_trans_blender,  Prev: create_blender_table,  Up: Transparency

20.10 Truecolor transparency
============================

In truecolor video modes, translucency and lighting are implemented by a
blender function of the form:

     unsigned long (*BLENDER_FUNC)(unsigned long x, y, n);

For each pixel to be drawn, this routine is passed two color parameters
x and y, decomposes them into their red, green and blue components,
combines them according to some mathematical transformation involving
the interpolation factor n, and then merges the result back into a
single return color value, which will be used to draw the pixel onto
the destination bitmap.

The parameter x represents the blending modifier color and the
parameter y represents the base color to be modified. The interpolation
factor n is in the range [0-255] and controls the solidity of the
blending.

When a translucent drawing function is used, x is the color of the
source, y is the color of the bitmap begin drawn onto and n is the
alpha level that was passed to the function that sets the blending mode
(the RGB triplet that was passed to this function is not taken into
account).

When a lit sprite drawing function is used, x is the color represented
by the RGB triplet that was passed to the function that sets the
blending mode (the alpha level that was passed to this function is not
taken into account), y is the color of the sprite and n is the alpha
level that was passed to the drawing function itself.

Since these routines may be used from various different color depths,
there are three such callbacks, one for use with 15-bit 5.5.5 pixels,
one for 16 bit 5.6.5 pixels, and one for 24-bit 8.8.8 pixels (this can
be shared between the 24 and 32-bit code since the bit packing is the
same).


File: allegro.info,  Node: set_trans_blender,  Next: set_alpha_blender,  Prev: Truecolor transparency,  Up: Transparency

20.11 set_trans_blender
=======================

void set_trans_blender(int r, int g, int b, int a);
     Enables a linear interpolator blender mode for combining
     translucent or lit truecolor pixels.

See also:
*Note set_blender_mode::.
*Note set_alpha_blender::.
*Note set_write_alpha_blender::.
*Note color_map::.
*Note draw_trans_sprite::.
*Note draw_lit_sprite::.
*Note drawing_mode::.
*Note set_add_blender::.
*Note set_burn_blender::.
*Note set_color_blender::.
*Note set_difference_blender::.
*Note set_dissolve_blender::.
*Note set_dodge_blender::.
*Note set_hue_blender::.
*Note set_invert_blender::.
*Note set_luminance_blender::.
*Note set_multiply_blender::.
*Note set_saturation_blender::.
*Note set_screen_blender::.
*Note ex3d::.
*Note exblend::.
*Note exshade::.
*Note extrans::.
*Note exxfade::.

File: allegro.info,  Node: set_alpha_blender,  Next: set_write_alpha_blender,  Prev: set_trans_blender,  Up: Transparency

20.12 set_alpha_blender
=======================

void set_alpha_blender();
     Enables the special alpha-channel blending mode, which is used for
     drawing 32-bit RGBA sprites. After calling this function, you can
     use draw_trans_sprite() or draw_trans_rle_sprite() to draw a
     32-bit source image onto any hicolor or truecolor destination. The
     alpha values will be taken directly from the source graphic, so
     you can vary the solidity of each part of the image. You can't use
     any of the normal translucency functions while this mode is
     active, though, so you should reset to one of the normal blender
     modes (eg. set_trans_blender()) before drawing anything other than
     32-bit RGBA sprites.

See also:
*Note set_trans_blender::.
*Note draw_trans_sprite::.
*Note draw_trans_rle_sprite::.
*Note set_write_alpha_blender::.
*Note exalpha::.
*Note extrans::.

File: allegro.info,  Node: set_write_alpha_blender,  Next: set_add_blender,  Prev: set_alpha_blender,  Up: Transparency

20.13 set_write_alpha_blender
=============================

void set_write_alpha_blender();
     Enables the special alpha-channel editing mode, which is used for
     drawing alpha channels over the top of an existing 32-bit RGB
     sprite, to turn it into an RGBA format image. After calling this
     function, you can set the drawing mode to DRAW_MODE_TRANS and then
     write draw color values (0-255) onto a 32-bit image. This will
     leave the color values unchanged, but alter the alpha to whatever
     values you are writing. After enabling this mode you can also use
     draw_trans_sprite() to superimpose an 8-bit alpha mask over the
     top of an existing 32-bit sprite.

See also:
*Note set_alpha_blender::.
*Note draw_trans_sprite::.
*Note drawing_mode::.
*Note exalpha::.
*Note extrans::.

File: allegro.info,  Node: set_add_blender,  Next: set_burn_blender,  Prev: set_write_alpha_blender,  Up: Transparency

20.14 set_add_blender
=====================

void set_add_blender(int r, int g, int b, int a);
     Enables an additive blender mode for combining translucent or lit
     truecolor pixels.

See also:
*Note set_trans_blender::.
*Note drawing_mode::.

File: allegro.info,  Node: set_burn_blender,  Next: set_color_blender,  Prev: set_add_blender,  Up: Transparency

20.15 set_burn_blender
======================

void set_burn_blender(int r, int g, int b, int a);
     Enables a burn blender mode for combining translucent or lit
     truecolor pixels. Here the lightness values of the colours of the
     source image reduce the lightness of the destination image,
     darkening the image.

See also:
*Note set_trans_blender::.
*Note drawing_mode::.

File: allegro.info,  Node: set_color_blender,  Next: set_difference_blender,  Prev: set_burn_blender,  Up: Transparency

20.16 set_color_blender
=======================

void set_color_blender(int r, int g, int b, int a);
     Enables a color blender mode for combining translucent or lit
     truecolor pixels. Applies only the hue and saturation of the
     source image to the destination image. The luminance of the
     destination image is not affected.

See also:
*Note set_trans_blender::.
*Note drawing_mode::.

File: allegro.info,  Node: set_difference_blender,  Next: set_dissolve_blender,  Prev: set_color_blender,  Up: Transparency

20.17 set_difference_blender
============================

void set_difference_blender(int r, int g, int b, int a);
     Enables a difference blender mode for combining translucent or lit
     truecolor pixels. This makes an image which has colours calculated
     by the difference between the source and destination colours.

See also:
*Note set_trans_blender::.
*Note drawing_mode::.

File: allegro.info,  Node: set_dissolve_blender,  Next: set_dodge_blender,  Prev: set_difference_blender,  Up: Transparency

20.18 set_dissolve_blender
==========================

void set_dissolve_blender(int r, int g, int b, int a);
     Enables a dissolve blender mode for combining translucent or lit
     truecolor pixels. Randomly replaces the colours of some pixels in
     the destination image with those of the source image. The number
     of pixels replaced depends on the alpha value (higher value, more
     pixels replaced; you get the idea :).

See also:
*Note set_trans_blender::.
*Note drawing_mode::.

File: allegro.info,  Node: set_dodge_blender,  Next: set_hue_blender,  Prev: set_dissolve_blender,  Up: Transparency

20.19 set_dodge_blender
=======================

void set_dodge_blender(int r, int g, int b, int a);
     Enables a dodge blender mode for combining translucent or lit
     truecolor pixels. The lightness of colours in the source lighten
     the colours of the destination. White has the most effect; black
     has none.

See also:
*Note set_trans_blender::.
*Note drawing_mode::.

File: allegro.info,  Node: set_hue_blender,  Next: set_invert_blender,  Prev: set_dodge_blender,  Up: Transparency

20.20 set_hue_blender
=====================

void set_hue_blender(int r, int g, int b, int a);
     Enables a hue blender mode for combining translucent or lit
     truecolor pixels. This applies the hue of the source to the
     destination.

See also:
*Note set_trans_blender::.
*Note drawing_mode::.

File: allegro.info,  Node: set_invert_blender,  Next: set_luminance_blender,  Prev: set_hue_blender,  Up: Transparency

20.21 set_invert_blender
========================

void set_invert_blender(int r, int g, int b, int a);
     Enables an invert blender mode for combining translucent or lit
     truecolor pixels. Blends the inverse (or negative) colour of the
     source with the destination.

See also:
*Note set_trans_blender::.
*Note drawing_mode::.

File: allegro.info,  Node: set_luminance_blender,  Next: set_multiply_blender,  Prev: set_invert_blender,  Up: Transparency

20.22 set_luminance_blender
===========================

void set_luminance_blender(int r, int g, int b, int a);
     Enables a luminance blender mode for combining translucent or lit
     truecolor pixels. Applies the luminance of the source to the
     destination.  The colour of the destination is not affected.

See also:
*Note set_trans_blender::.
*Note drawing_mode::.

File: allegro.info,  Node: set_multiply_blender,  Next: set_saturation_blender,  Prev: set_luminance_blender,  Up: Transparency

20.23 set_multiply_blender
==========================

void set_multiply_blender(int r, int g, int b, int a);
     Enables a multiply blender mode for combining translucent or lit
     truecolor pixels. Combines the source and destination images,
     multiplying the colours to produce a darker colour. If a colour is
     multiplied by white it remains unchanged; when multiplied by black
     it also becomes black.

See also:
*Note set_trans_blender::.
*Note drawing_mode::.
*Note exalpha::.

File: allegro.info,  Node: set_saturation_blender,  Next: set_screen_blender,  Prev: set_multiply_blender,  Up: Transparency

20.24 set_saturation_blender
============================

void set_saturation_blender(int r, int g, int b, int a);
     Enables a saturation blender mode for combining translucent or lit
     truecolor pixels. Applies the saturation of the source to the
     destination image.

See also:
*Note set_trans_blender::.
*Note drawing_mode::.

File: allegro.info,  Node: set_screen_blender,  Next: set_blender_mode,  Prev: set_saturation_blender,  Up: Transparency

20.25 set_screen_blender
========================

void set_screen_blender(int r, int g, int b, int a);
     Enables a screen blender mode for combining translucent or lit
     truecolor pixels. This blender mode lightens the colour of the
     destination image by multiplying the inverse of the source and
     destination colours. Sort of like the opposite of the multiply
     blender mode.

See also:
*Note set_trans_blender::.
*Note drawing_mode::.

File: allegro.info,  Node: set_blender_mode,  Next: set_blender_mode_ex,  Prev: set_screen_blender,  Up: Transparency

20.26 set_blender_mode
======================

void set_blender_mode(BLENDER_FUNC b15, b16, b24, int r, g, b, a);
     Specifies a custom set of truecolor blender routines, which can be
     used to implement whatever special interpolation modes you need.
     This function shares a single blender between the 24 and 32-bit
     modes.

See also:
*Note set_blender_mode_ex::.
*Note set_trans_blender::.
*Note color_map::.
*Note draw_trans_sprite::.
*Note draw_lit_sprite::.
*Note drawing_mode::.

File: allegro.info,  Node: set_blender_mode_ex,  Next: bestfit_color,  Prev: set_blender_mode,  Up: Transparency

20.27 set_blender_mode_ex
=========================

void set_blender_mode_ex(BLENDER_FUNC b15, b16, b24, b32, b15x, b16x, b24x, int r, g, b, a);
     Like set_blender_mode(), but allows you to specify a more complete
     set of blender routines. The b15, b16, b24, and b32 routines are
     used when drawing pixels onto destinations of the same format,
     while b15x, b16x, and b24x are used by draw_trans_sprite() and
     draw_trans_rle_sprite() when drawing RGBA images onto destination
     bitmaps of another format. These blenders will be passed a 32-bit
     x parameter, along with a y value of a different color depth, and
     must try to do something sensible in response.

See also:
*Note set_blender_mode::.
*Note set_alpha_blender::.

File: allegro.info,  Node: Converting,  Next: Direct,  Prev: Transparency,  Up: Top

21 Converting between color formats
***********************************

In general, Allegro is designed to be used in only one color depth at a
time, so you will call set_color_depth() once and then store all your
bitmaps in the same format. If you want to mix several different pixel
formats, you can use create_bitmap_ex() in place of create_bitmap(), and
call bitmap_color_depth() to query the format of a specific image. Most
of the graphics routines require all their input parameters to be in
the same format (eg. you cannot stretch a 15-bit source bitmap onto a
24-bit destination), but there are some exceptions: blit() and the
rotation routines can copy between bitmaps of any format, converting
the data as required, draw_sprite() can draw 256-color source images
onto destinations of any format, draw_character_ex() _always_ uses a
256-color source bitmap, whatever the format of the destination, the
draw_trans_sprite() and draw_trans_rle_sprite() functions are able to
draw 32-bit RGBA images onto any hicolor or truecolor destination, as
long as you call set_alpha_blender() first, and the draw_trans_sprite()
function is able to draw an 8-bit alpha channel image over the top of
an existing 32-bit image, as long as you call set_write_alpha_blender()
first.

Expanding a 256-color source onto a truecolor destination is fairly fast
(obviously you must set the correct palette before doing this
conversion!).  Converting between different truecolor formats is
slightly slower, and reducing truecolor images to a 256-color
destination is very slow (it can be sped up significantly if you set up
the global rgb_map table before doing the conversion).

* Menu:

* bestfit_color::
* rgb_map::
* create_rgb_table::
* hsv_to_rgb::


File: allegro.info,  Node: bestfit_color,  Next: rgb_map,  Prev: set_blender_mode_ex,  Up: Converting

21.1 bestfit_color
==================

int bestfit_color(const PALETTE pal, int r, int g, int b);
     Searches the specified palette for the closest match to the
     requested color, which are specified in the VGA hardware 0-63
     format. Normally you should call makecol8() instead, but this
     lower level function may be useful if you need to use a palette
     other than the currently selected one, or specifically don't want
     to use the rgb_map lookup table.

See also:
*Note makecol8::.
*Note PALETTE::.

File: allegro.info,  Node: rgb_map,  Next: create_rgb_table,  Prev: bestfit_color,  Up: Converting

21.2 rgb_map
============

extern RGB_MAP *rgb_map;
     To speed up reducing RGB values to 8-bit paletted colors, Allegro
     uses a 32k lookup table (5 bits for each color component). You
     must set up this table before using the gouraud shading routines,
     and if present the table will also vastly accelerate the
     makecol8() function. RGB tables can be precalculated with the
     rgbmap utility, or generated at runtime. The RGB_MAP structure is
     defined as:

          typedef struct {
             unsigned char data[32][32][32];
          } RGB_MAP;

See also:
*Note create_rgb_table::.
*Note makecol8::.
*Note ex3d::.
*Note excolmap::.
*Note exrgbhsv::.
*Note exshade::.
*Note extrans::.
*Note RGB_MAP::.

File: allegro.info,  Node: create_rgb_table,  Next: hsv_to_rgb,  Prev: rgb_map,  Up: Converting

21.3 create_rgb_table
=====================

void create_rgb_table(RGB_MAP *table, const PALETTE pal, void (*callback)(int pos));
     Fills the specified RGB mapping table with lookup data for the
     specified palette. If the callback function is not NULL, it will
     be called 256 times during the calculation, allowing you to
     display a progress indicator.

See also:
*Note rgb_map::.
*Note PALETTE::.
*Note RGB_MAP::.

File: allegro.info,  Node: hsv_to_rgb,  Next: play_fli,  Prev: create_rgb_table,  Up: Converting

21.4 hsv_to_rgb
===============

void hsv_to_rgb(float h, float s, float v, int *r, int *g, int *b);

void rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v);
     Convert color values between the HSV and RGB colorspaces. The RGB
     values range from 0 to 255, hue is from 0 to 360, and saturation
     and value are from 0 to 1.

See also:
*Note exlights::.
*Note exrgbhsv::.

File: allegro.info,  Node: Direct,  Next: FLIC,  Prev: Converting,  Up: Top

22 Direct access to video memory
********************************

Read chapter "Structures and types defined by Allegro" for an internal
description of the BITMAP structure. There are several ways to get
direct access to the image memory of a bitmap, varying in complexity
depending on what sort of bitmap you are using.

The simplest approach will only work with memory bitmaps (obtained from
create_bitmap(), grabber datafiles, and image files) and sub-bitmaps of
memory bitmaps. This uses a table of char pointers, called 'line',
which is a part of the bitmap structure and contains pointers to the
start of each line of the image. For example, a simple memory bitmap
putpixel function is:

     void memory_putpixel(BITMAP *bmp, int x, int y, int color)
     {
        bmp->line[y][x] = color;
     }

For truecolor modes you need to cast the line pointer to the appropriate
type, for example:

     void memory_putpixel_15_or_16_bpp(BITMAP *bmp, int x, int y, int color)
     {
        ((short *)bmp->line[y])[x] = color;
     }

     void memory_putpixel_32(BITMAP *bmp, int x, int y, int color)
     {
        ((long *)bmp->line[y])[x] = color;
     }

If you want to write to the screen as well as to memory bitmaps, you
need to use some helper macros, because the video memory may not be
part of your normal address space. This simple routine will work for
any linear screen, eg. a VESA linear framebuffers:

     void linear_screen_putpixel(BITMAP *bmp, int x, int y, int color)
     {
        bmp_select(bmp);
        bmp_write8((unsigned long)bmp->line[y]+x, color);
     }

For truecolor modes you should replace the bmp_write8() with
bmp_write16(), bmp_write24(), or bmp_write32(), and multiply the x
offset by the number of bytes per pixel. There are of course similar
functions to read a pixel value from a bitmap, namely bmp_read8(),
bmp_read16(), bmp_read24() and bmp_read32().

This still won't work in banked SVGA modes, however, or on platforms
like Windows that do special processing inside the bank switching
functions. For more flexible access to bitmap memory, you need to call
the routines:

unsigned long bmp_write_line(BITMAP *bmp, int line);
Selects the line of a bitmap that you are going to draw onto.

unsigned long bmp_read_line(BITMAP *bmp, int line);
Selects the line of a bitmap that you are going to read from.

unsigned long bmp_unwrite_line(BITMAP *bmp);
Releases the bitmap memory after you are finished with it. You only need
to call this once at the end of a drawing operation, even if you have
called bmp_write_line() or bmp_read_line() several times before it.

These are implemented as inline assembler routines, so they are not as
inefficient as they might seem. If the bitmap doesn't require bank
switching (ie. it is a memory bitmap, mode 13h screen, etc), these
functions just return bmp->line[line].

Although SVGA bitmaps are banked, Allegro provides linear access to the
memory within each scanline, so you only need to pass a y coordinate to
these functions. Various x positions can be obtained by simply adding
the x coordinate to the returned address. The return value is an
unsigned long rather than a char pointer because the bitmap memory may
not be in your data segment, and you need to access it with far
pointers. For example, a putpixel using the bank switching functions is:

     void banked_putpixel(BITMAP *bmp, int x, int y, int color)
     {
        unsigned long address = bmp_write_line(bmp, y);
        bmp_select(bmp);
        bmp_write8(address+x, color);
        bmp_unwrite_line(bmp);
     }

You will notice that Allegro provides separate functions for setting the
read and write banks. It is important that you distinguish between
these, because on some graphics cards the banks can be set
individually, and on others the video memory is read and written at
different addresses. Life is never quite as simple as we might wish it
to be, though (this is true even when we _aren't_ talking about
graphics coding :-) and so of course some cards only provide a single
bank. On these the read and write bank functions will behave
identically, so you shouldn't assume that you can read from one part of
video memory and write to another at the same time. You can call
bmp_read_line(), and read whatever you like from that line, and then
call bmp_write_line() with the same or a different line number, and
write whatever you like to this second line, but you mustn't call
bmp_read_line() and bmp_write_line() together and expect to be able to
read one line and write the other simultaneously. It would be nice if
this was possible, but if you do it, your code won't work on single
banked SVGA cards.

And then there's mode-X. If you've never done any mode-X graphics
coding, you probably won't understand this, but for those of you who
want to know how Allegro sets up the mode-X screen bitmaps, here goes...

The line pointers are still present, and they contain planar addresses,
ie.  the actual location at which you access the first pixel in the
line. These addresses are guaranteed to be quad aligned, so you can
just set the write plane, divide your x coordinate by four, and add it
to the line pointer. For example, a mode-X putpixel is:

     void modex_putpixel(BITMAP *b, int x, int y, int color)
     {
        outportw(0x3C4, (0x100<<(x&3))|2);
        bmp_select(bmp);
        bmp_write8((unsigned long)bmp->line[y]+(x>>2), color);
     }

Oh yeah: the djgpp nearptr hack. Personally I don't like this very much
because it disables memory protection and isn't portable to other
platforms, but a lot of people swear by it because it can give you
direct access to the screen memory via a normal C pointer. Warning:
this method will only work with the djgpp library, when using VGA 13h
or a linear framebuffer modes!

In your setup code:

     #include <sys/nearptr.h>

     unsigned char *screenmemory;
     unsigned long screen_base_addr;

     __djgpp_nearptr_enable();

     __dpmi_get_segment_base_address(screen->seg, &screen_base_addr);

     screenmemory = (unsigned char *)(screen_base_addr +
                                      screen->line[0] -
                                      __djgpp_base_address);

Then:

     void nearptr_putpixel(int x, int y, int color)
     {
        screenmemory[x + y*VIRTUAL_W] = color;
     }


File: allegro.info,  Node: FLIC,  Next: Sound,  Prev: Direct,  Up: Top

23 FLIC routines
****************

There are two high level functions for playing FLI/FLC animations:
play_fli(), which reads the data directly from disk, and
play_memory_fli(), which uses data that has already been loaded into
RAM. Apart from the different sources of the data, these two functions
behave identically. They draw the animation onto the specified bitmap,
which should normally be the screen. Frames will be aligned with the
top left corner of the bitmap: if you want to position them somewhere
else you will need to create a sub-bitmap for the FLI player to draw
onto. If loop is set the player will cycle when it reaches the end of
the file, otherwise it will play through the animation once and then
return. If the callback function is not NULL it will be called once for
each frame, allowing you to perform background tasks of your own. This
callback should normally return zero: if it returns non-zero the player
will terminate (this is the only way to stop an animation that is
playing in looped mode). The FLI player returns FLI_OK if it reached
the end of the file, FLI_ERROR if something went wrong, and the value
returned by the callback function if that was what stopped it. If you
need to distinguish between different return values, your callback
should return positive integers, since FLI_OK is zero and FLI_ERROR is
negative.  Note that the FLI player will only work when the timer
module is installed, and that it will alter the palette according to
whatever palette data is present in the animation file.

Occasionally you may need more detailed control over how an FLI is
played, for example if you want to superimpose a text scroller on top
of the animation, or to play it back at a different speed. You could do
both of these with the lower level functions described below.

* Menu:

* play_fli::
* play_memory_fli::
* open_fli::
* close_fli::
* next_fli_frame::
* fli_bitmap::
* fli_palette::
* fli_bmp_dirty_from::
* fli_pal_dirty_from::
* reset_fli_variables::
* fli_frame::
* fli_timer::


File: allegro.info,  Node: play_fli,  Next: play_memory_fli,  Prev: hsv_to_rgb,  Up: FLIC

23.1 play_fli
=============

int play_fli(const char *filename, BITMAP *bmp, int loop, int (*callback)());
     Plays an Autodesk Animator FLI or FLC animation file, reading the
     data from disk as it is required.

See also:
*Note play_memory_fli::.
*Note install_timer::.
*Note fli_frame::.
*Note BITMAP::.

File: allegro.info,  Node: play_memory_fli,  Next: open_fli,  Prev: play_fli,  Up: FLIC

23.2 play_memory_fli
====================

int play_memory_fli(const void *fli_data, BITMAP *bmp, int loop, int (*callback)());
     Plays an Autodesk Animator FLI or FLC animation, reading the data
     from a copy of the file which is held in memory. You can obtain
     the fli_data pointer by mallocing a block of memory and reading an
     FLI file into it, or by importing an FLI into a grabber datafile.
     Playing animations from memory is obviously faster than cueing
     them directly from disk, and is particularly useful with short,
     looped FLI's. Animations can easily get very large, though, so in
     most cases you will probably be better just using play_fli().

See also:
*Note play_fli::.
*Note install_timer::.
*Note fli_frame::.
*Note BITMAP::.

File: allegro.info,  Node: open_fli,  Next: close_fli,  Prev: play_memory_fli,  Up: FLIC

23.3 open_fli
=============

int open_fli(const char *filename);

int open_memory_fli(const void *fli_data);
     Open FLI files ready for playing, reading the data from disk or
     memory respectively. Return FLI_OK on success. Information about
     the current FLI is held in global variables, so you can only have
     one animation open at a time.

See also:
*Note close_fli::.
*Note next_fli_frame::.

File: allegro.info,  Node: close_fli,  Next: next_fli_frame,  Prev: open_fli,  Up: FLIC

23.4 close_fli
==============

void close_fli();
     Closes an FLI file when you have finished reading from it.

See also:
*Note open_fli::.

File: allegro.info,  Node: next_fli_frame,  Next: fli_bitmap,  Prev: close_fli,  Up: FLIC

23.5 next_fli_frame
===================

int next_fli_frame(int loop);
     Reads the next frame of the current animation file. If loop is set
     the player will cycle when it reaches the end of the file,
     otherwise it will return FLI_EOF. Returns FLI_OK on success,
     FLI_ERROR or FLI_NOT_OPEN on error, and FLI_EOF on reaching the
     end of the file. The frame is read into the global variables
     fli_bitmap and fli_palette.

See also:
*Note open_fli::.
*Note fli_bitmap::.
*Note fli_palette::.
*Note fli_timer::.
*Note fli_frame::.

File: allegro.info,  Node: fli_bitmap,  Next: fli_palette,  Prev: next_fli_frame,  Up: FLIC

23.6 fli_bitmap
===============

extern BITMAP *fli_bitmap;
     Contains the current frame of the FLI/FLC animation.

See also:
*Note next_fli_frame::.
*Note fli_bmp_dirty_from::.
*Note fli_palette::.
*Note BITMAP::.

File: allegro.info,  Node: fli_palette,  Next: fli_bmp_dirty_from,  Prev: fli_bitmap,  Up: FLIC

23.7 fli_palette
================

extern PALETTE fli_palette;
     Contains the current FLI palette.

See also:
*Note next_fli_frame::.
*Note fli_pal_dirty_from::.
*Note fli_bitmap::.
*Note PALETTE::.

File: allegro.info,  Node: fli_bmp_dirty_from,  Next: fli_pal_dirty_from,  Prev: fli_palette,  Up: FLIC

23.8 fli_bmp_dirty_from
=======================

extern int fli_bmp_dirty_from;

extern int fli_bmp_dirty_to;
     These variables are set by next_fli_frame() to indicate which part
     of the fli_bitmap has changed since the last call to
     reset_fli_variables(). If fli_bmp_dirty_from is greater than
     fli_bmp_dirty_to, the bitmap has not changed, otherwise lines
     fli_bmp_dirty_from to fli_bmp_dirty_to (inclusive) have altered.
     You can use these when copying the fli_bitmap onto the screen, to
     avoid moving data unnecessarily.

See also:
*Note fli_bitmap::.
*Note reset_fli_variables::.

File: allegro.info,  Node: fli_pal_dirty_from,  Next: reset_fli_variables,  Prev: fli_bmp_dirty_from,  Up: FLIC

23.9 fli_pal_dirty_from
=======================

extern int fli_pal_dirty_from;

extern int fli_pal_dirty_to;
     These variables are set by next_fli_frame() to indicate which part
     of the fli_palette has changed since the last call to
     reset_fli_variables(). If fli_pal_dirty_from is greater than
     fli_pal_dirty_to, the palette has not changed, otherwise colors
     fli_pal_dirty_from to fli_pal_dirty_to (inclusive) have altered.
     You can use these when updating the hardware palette, to avoid
     unnecessary calls to set_palette().

See also:
*Note fli_palette::.
*Note reset_fli_variables::.

File: allegro.info,  Node: reset_fli_variables,  Next: fli_frame,  Prev: fli_pal_dirty_from,  Up: FLIC

23.10 reset_fli_variables
=========================

void reset_fli_variables();
     Once you have done whatever you are going to do with the
     fli_bitmap and fli_palette, call this function to reset the
     fli_bmp_dirty_* and fli_pal_dirty_* variables.

See also:
*Note fli_bmp_dirty_from::.
*Note fli_pal_dirty_from::.

File: allegro.info,  Node: fli_frame,  Next: fli_timer,  Prev: reset_fli_variables,  Up: FLIC

23.11 fli_frame
===============

extern int fli_frame;
     Global variable containing the current frame number in the FLI
     file. This is useful for synchronising other events with the
     animation, for instance you could check it in a play_fli()
     callback function and use it to trigger a sample at a particular
     point.

See also:
*Note play_fli::.
*Note play_memory_fli::.
*Note next_fli_frame::.

File: allegro.info,  Node: fli_timer,  Next: detect_digi_driver,  Prev: fli_frame,  Up: FLIC

23.12 fli_timer
===============

extern volatile int fli_timer;
     Global variable for timing FLI playback. When you open an FLI
     file, a timer interrupt is installed which increments this
     variable every time a new frame should be displayed. Calling
     next_fli_frame() decrements it, so you can test it and know that
     it is time to display a new frame if it is greater than zero.

See also:
*Note install_timer::.
*Note next_fli_frame::.

File: allegro.info,  Node: Sound,  Next: Digital,  Prev: FLIC,  Up: Top

24 Sound init routines
**********************

* Menu:

* detect_digi_driver::
* detect_midi_driver::
* reserve_voices::
* set_volume_per_voice::
* install_sound::
* remove_sound::
* set_volume::


File: allegro.info,  Node: detect_digi_driver,  Next: detect_midi_driver,  Prev: fli_timer,  Up: Sound

24.1 detect_digi_driver
=======================

int detect_digi_driver(int driver_id);
     Detects whether the specified digital sound device is available.
     Returns the maximum number of voices that the driver can provide,
     or zero if the hardware is not present. This function must be
     called _before_ install_sound().

See also:
*Note install_sound::.
*Note reserve_voices::.
*Note DIGI_*/DOS::.
*Note DIGI_*/Windows::.
*Note DIGI_*/Unix::.
*Note DIGI_*/BeOS::.
*Note DIGI_*/QNX::.
*Note DIGI_*/MacOSX::.

File: allegro.info,  Node: detect_midi_driver,  Next: reserve_voices,  Prev: detect_digi_driver,  Up: Sound

24.2 detect_midi_driver
=======================

int detect_midi_driver(int driver_id);
     Detects whether the specified MIDI sound device is available.
     Returns the maximum number of voices that the driver can provide,
     or zero if the hardware is not present. There are two special-case
     return values that you should watch out for: if this function
     returns -1 it is a note-stealing driver (eg. DIGMID) that shares
     voices with the current digital sound driver, and if it returns
     0xFFFF it is an external device like an MPU-401 where there is no
     way to determine how many voices are available. This function must
     be called _before_ install_sound().

See also:
*Note install_sound::.
*Note reserve_voices::.
*Note MIDI_*/DOS::.
*Note MIDI_*/Windows::.
*Note MIDI_*/Unix::.
*Note MIDI_*/BeOS::.
*Note MIDI_*/QNX::.
*Note MIDI_*/MacOSX::.

File: allegro.info,  Node: reserve_voices,  Next: set_volume_per_voice,  Prev: detect_midi_driver,  Up: Sound

24.3 reserve_voices
===================

void reserve_voices(int digi_voices, int midi_voices);
     Call this function to specify the number of voices that are to be
     used by the digital and MIDI sound drivers respectively. This must
     be done _before_ calling install_sound(). If you reserve too many
     voices, subsequent calls to install_sound() will fail. How many
     voices are available depends on the driver, and in some cases you
     will actually get more than you reserve (eg. the FM synth drivers
     will always provide 9 voices on an OPL2 and 18 on an OPL3, and the
     SB digital driver will round the number of voices up to the
     nearest power of two). Pass negative values to restore the default
     settings. You should be aware that the sound quality is usually
     inversely related to how many voices you use, so don't reserve any
     more than you really need.

See also:
*Note set_volume_per_voice::.
*Note install_sound::.
*Note detect_digi_driver::.
*Note detect_midi_driver::.

File: allegro.info,  Node: set_volume_per_voice,  Next: install_sound,  Prev: reserve_voices,  Up: Sound

24.4 set_volume_per_voice
=========================

void set_volume_per_voice(int scale);
     By default, when you reserve more voices for the digital sound
     driver, Allegro will reduce the volume of each voice to
     compensate. This is done to avoid too much distortion. The default
     volume per voice is such that, if you reserve n voices, you can
     play up to n/2 normalised samples with centre panning without
     risking distortion. The exception is when you have fewer than 8
     voices, where the volume remains the same as for 8 voices.

     If the resultant output is either too loud or too quiet, this
     function can be used to adjust the volume of each voice. You
     should first check that your speakers are at a reasonable volume,
     Allegro's global volume is at maximum (see set_volume() below),
     and any other mixers such as the Windows Volume Control are set
     reasonably.

     Once you are sure that Allegro's output level is unsuitable for
     your application, use this function to adjust it. This must be
     done _before_ calling install_sound(). Note that this function is
     currently only relevant for drivers that use the Allegro mixer
     (which is most of them).

     If you pass 0 to this function, each centred sample will play at
     the maximum volume possible without distortion, as will all
     samples played through a mono driver. Samples at the extreme left
     and right will distort if played at full volume. If you wish to
     play panned samples at full volume without distortion, you should
     pass 1 to this function.  Note: this is different from the
     function's behaviour in WIPs 3.9.34, 3.9.35 and 3.9.36. If you
     used this function under one of these WIPs, you will have to
     increase your parameter by one to get the same volume.

     Each time you increase the parameter by one, the volume of each
     voice will halve. For example, if you pass 4, you can play up to
     16 centred samples at maximum volume without distortion.

     Here are the default values, dependent on the number of voices:

          1-8 voices - set_volume_per_voice(2)
           16 voices - set_volume_per_voice(3)
           32 voices - set_volume_per_voice(4)
           64 voices - set_volume_per_voice(5)

     Of course this function does not override the volume you specify
     with play_sample() or voice_set_volume(). It simply alters the
     overall output of the program. If you play samples at lower
     volumes, or if they are not normalised, then you can play more of
     them without distortion.

     Warning: Allegro uses a clipping table to clip the waveform. The
     table is big enough to accommodate a total output of up to 4 times
     the maximum possible without distortion. If your output goes above
     this limit, the wave will 'wrap around' (peaks become troughs and
     vice versa), thus distorting much more. You should be careful that
     this does not happen.

     It is recommended that you hard-code the parameter into your
     program, rather than offering it to the user. The user can alter
     the volume with the configuration file instead, or you can provide
     for this with set_volume().

     To restore volume per voice to its default behaviour, pass -1.

See also:
*Note reserve_voices::.
*Note set_volume::.
*Note install_sound::.
*Note detect_digi_driver::.
*Note detect_midi_driver::.

File: allegro.info,  Node: install_sound,  Next: remove_sound,  Prev: set_volume_per_voice,  Up: Sound

24.5 install_sound
==================

int install_sound(int digi, int midi, const char *cfg_path);
     Initialises the sound module. You should normally pass
     DIGI_AUTODETECT and MIDI_AUTODETECT as the driver parameters to
     this function, in which case Allegro will read hardware settings
     from the current configuration file. This allows the user to
     select different values with the setup utility: see the config
     section for details. Alternatively, see the platform specific
     documentation for a list of the available drivers. The cfg_path
     parameter is only present for compatibility with previous versions
     of Allegro, and has no effect on anything. Returns zero if the
     sound is successfully installed, and -1 on failure. If it fails it
     will store a description of the problem in allegro_error.

See also:
*Note remove_sound::.
*Note reserve_voices::.
*Note detect_digi_driver::.
*Note detect_midi_driver::.
*Note set_volume::.
*Note play_sample::.
*Note Voice control::.
*Note play_midi::.
*Note play_audio_stream::.
*Note install_sound_input::.
*Note allegro_error::.
*Note Standard config variables::.
*Note DIGI_*/DOS::.
*Note DIGI_*/Windows::.
*Note DIGI_*/Unix::.
*Note DIGI_*/BeOS::.
*Note DIGI_*/QNX::.
*Note DIGI_*/MacOSX::.
*Note MIDI_*/DOS::.
*Note MIDI_*/Windows::.
*Note MIDI_*/Unix::.
*Note MIDI_*/BeOS::.
*Note MIDI_*/QNX::.
*Note MIDI_*/MacOSX::.
*Note exdodgy::.
*Note exmidi::.
*Note exsample::.
*Note exstream::.

File: allegro.info,  Node: remove_sound,  Next: set_volume,  Prev: install_sound,  Up: Sound

24.6 remove_sound
=================

void remove_sound();
     Cleans up after you are finished with the sound routines. You don't
     normally need to call this, because allegro_exit() will do it for
     you.

See also:
*Note install_sound::.
*Note allegro_exit::.
*Note exdodgy::.

File: allegro.info,  Node: set_volume,  Next: load_sample,  Prev: remove_sound,  Up: Sound

24.7 set_volume
===============

void set_volume(int digi_volume, int midi_volume);
     Alters the global sound output volume. Specify volumes for both
     digital samples and MIDI playback, as integers from 0 to 255, or
     pass a negative value to leave one of the settings unchanged. If
     possible this routine will use a hardware mixer to control the
     volume, otherwise it will tell the sample and MIDI players to
     simulate a mixer in software.

See also:
*Note install_sound::.

File: allegro.info,  Node: Digital,  Next: Music,  Prev: Sound,  Up: Top

25 Digital sample routines
**************************

* Menu:

* load_sample::
* load_wav::
* load_voc::
* save_sample::
* create_sample::
* destroy_sample::
* lock_sample::
* register_sample_file_type::
* play_sample::
* adjust_sample::
* stop_sample::
* Voice control::
* allocate_voice::
* deallocate_voice::
* reallocate_voice::
* release_voice::
* voice_start::
* voice_stop::
* voice_set_priority::
* voice_check::
* voice_get_position::
* voice_set_position::
* voice_set_playmode::
* voice_get_volume::
* voice_set_volume::
* voice_ramp_volume::
* voice_stop_volumeramp::
* voice_get_frequency::
* voice_set_frequency::
* voice_sweep_frequency::
* voice_stop_frequency_sweep::
* voice_get_pan::
* voice_set_pan::
* voice_sweep_pan::
* voice_stop_pan_sweep::
* voice_set_echo::
* voice_set_tremolo::
* voice_set_vibrato::


File: allegro.info,  Node: load_sample,  Next: load_wav,  Prev: set_volume,  Up: Digital

25.1 load_sample
================

SAMPLE *load_sample(const char *filename);
     Loads a sample from a file, returning a pointer to it, or NULL on
     error.  At present this function supports both mono and stereo WAV
     and mono VOC files, in 8 or 16-bit formats, as well as formats
     handled by functions registered using register_sample_file_type.

See also:
*Note destroy_sample::.
*Note load_voc::.
*Note load_wav::.
*Note play_sample::.
*Note save_sample::.
*Note register_sample_file_type::.
*Note Voice control::.
*Note exsample::.
*Note SAMPLE::.

File: allegro.info,  Node: load_wav,  Next: load_voc,  Prev: load_sample,  Up: Digital

25.2 load_wav
=============

SAMPLE *load_wav(const char *filename);
     Loads a sample from a RIFF WAV file.

See also:
*Note load_sample::.
*Note register_sample_file_type::.
*Note SAMPLE::.

File: allegro.info,  Node: load_voc,  Next: save_sample,  Prev: load_wav,  Up: Digital

25.3 load_voc
=============

SAMPLE *load_voc(const char *filename);
     Loads a sample from a Creative Labs VOC file.

See also:
*Note load_sample::.
*Note register_sample_file_type::.
*Note SAMPLE::.

File: allegro.info,  Node: save_sample,  Next: create_sample,  Prev: load_voc,  Up: Digital

25.4 save_sample
================

int save_sample(const char *filename, SAMPLE *spl);
     Writes a sample into a file, returning non-zero on error. The
     output format is determined from the filename extension. At
     present Allegro does not natively support the writing of any
     sample formats, so you must register a custom saver routine with
     register_sample_file_type().

See also:
*Note load_sample::.
*Note register_sample_file_type::.
*Note SAMPLE::.

File: allegro.info,  Node: create_sample,  Next: destroy_sample,  Prev: save_sample,  Up: Digital

25.5 create_sample
==================

SAMPLE *create_sample(int bits, int stereo, int freq, int len);
     Constructs a new sample structure of the specified type. The data
     field points to a block of waveform data: see the structure
     definition in allegro/digi.h for details.

See also:
*Note load_sample::.
*Note destroy_sample::.
*Note SAMPLE::.

File: allegro.info,  Node: destroy_sample,  Next: lock_sample,  Prev: create_sample,  Up: Digital

25.6 destroy_sample
===================

void destroy_sample(SAMPLE *spl);
     Destroys a sample structure when you are done with it. It is safe
     to call this even when the sample might be playing, because it
     checks and will kill it off if it is active.

See also:
*Note load_sample::.
*Note exsample::.
*Note SAMPLE::.

File: allegro.info,  Node: lock_sample,  Next: register_sample_file_type,  Prev: destroy_sample,  Up: Digital

25.7 lock_sample
================

void lock_sample(SAMPLE *spl);
     Under DOS, locks all the memory used by a sample. You don't
     normally need to call this function because load_sample() and
     create_sample() do it for you.

See also:
*Note load_sample::.
*Note create_sample::.
*Note SAMPLE::.

File: allegro.info,  Node: register_sample_file_type,  Next: play_sample,  Prev: lock_sample,  Up: Digital

25.8 register_sample_file_type
==============================

void register_sample_file_type(const char *ext, SAMPLE *(*load)(const char *filename), int (*save)(const char *filename, SAMPLE *spl));
     Informs the load_sample() function of a new sample file type,
     providing routines to read and write samples in this format (either
     function may be NULL).

See also:
*Note load_sample::.
*Note save_sample::.
*Note SAMPLE::.

File: allegro.info,  Node: play_sample,  Next: adjust_sample,  Prev: register_sample_file_type,  Up: Digital

25.9 play_sample
================

int play_sample(const SAMPLE *spl, int vol, int pan, int freq, int loop);
     Triggers a sample at the specified volume, pan position, and
     frequency.  The volume and pan range from 0 (min/left) to 255
     (max/right). Frequency is relative rather than absolute: 1000
     represents the frequency that the sample was recorded at, 2000 is
     twice this, etc. If the loop flag is set, the sample will repeat
     until you call stop_sample(), and can be manipulated while it is
     playing by calling adjust_sample(). Returns the voice number that
     was allocated for the sample (a non-negative number if successful).

See also:
*Note install_sound::.
*Note load_sample::.
*Note adjust_sample::.
*Note stop_sample::.
*Note Voice control::.
*Note exsample::.
*Note SAMPLE::.

File: allegro.info,  Node: adjust_sample,  Next: stop_sample,  Prev: play_sample,  Up: Digital

25.10 adjust_sample
===================

void adjust_sample(const SAMPLE *spl, int vol, int pan, int freq, int loop);
     Alters the parameters of a sample while it is playing (useful for
     manipulating looped sounds). You can alter the volume, pan, and
     frequency, and can also clear the loop flag, which will stop the
     sample when it next reaches the end of its loop. If there are
     several copies of the same sample playing, this will adjust the
     first one it comes across.  If the sample is not playing it has no
     effect.

See also:
*Note play_sample::.
*Note exsample::.
*Note SAMPLE::.

File: allegro.info,  Node: stop_sample,  Next: Voice control,  Prev: adjust_sample,  Up: Digital

25.11 stop_sample
=================

void stop_sample(const SAMPLE *spl);
     Kills off a sample, which is required if you have set a sample
     going in looped mode. If there are several copies of the sample
     playing, it will stop them all.

See also:
*Note play_sample::.
*Note SAMPLE::.

File: allegro.info,  Node: Voice control,  Next: allocate_voice,  Prev: stop_sample,  Up: Digital

25.12 Voice control
===================

If you need more detailed control over how samples are played, you can
use the lower level voice functions rather than just calling
play_sample(). This is rather more work, because you have to explicitly
allocate and free the voices rather than them being automatically
released when they finish playing, but allows far more precise
specification of exactly how you want everything to sound. You may also
want to modify a couple of fields from the sample structure:

     int priority;
        Ranging 0-255 (default 128), this controls how voices are
        allocated if you attempt to play more than the driver can handle.
        This may be used to ensure that the less important sounds are
        cut off while the important ones are preserved.

     unsigned long loop_start;
     unsigned long loop_end;
        Loop position in sample units, by default set to the start and end of
        the sample.

See also:
*Note install_sound::.
*Note allocate_voice::.
*Note deallocate_voice::.
*Note reallocate_voice::.
*Note release_voice::.
*Note voice_start::.
*Note voice_set_priority::.
*Note voice_check::.
*Note voice_set_position::.
*Note voice_set_playmode::.
*Note voice_set_volume::.
*Note voice_set_frequency::.
*Note voice_set_pan::.

File: allegro.info,  Node: allocate_voice,  Next: deallocate_voice,  Prev: Voice control,  Up: Digital

25.13 allocate_voice
====================

int allocate_voice(const SAMPLE *spl);
     Allocates a soundcard voice and prepares it for playing the
     specified sample, setting up sensible default parameters (maximum
     volume, centre pan, no change of pitch, no looping). When you are
     finished with the voice you must free it by calling
     deallocate_voice() or release_voice().  Returns the voice number,
     or -1 if no voices are available.

See also:
*Note Voice control::.
*Note deallocate_voice::.
*Note reallocate_voice::.
*Note release_voice::.
*Note load_sample::.
*Note SAMPLE::.

File: allegro.info,  Node: deallocate_voice,  Next: reallocate_voice,  Prev: allocate_voice,  Up: Digital

25.14 deallocate_voice
======================

void deallocate_voice(int voice);
     Frees a soundcard voice, stopping it from playing and releasing
     whatever resources it is using.

See also:
*Note allocate_voice::.
*Note voice_stop::.

File: allegro.info,  Node: reallocate_voice,  Next: release_voice,  Prev: deallocate_voice,  Up: Digital

25.15 reallocate_voice
======================

void reallocate_voice(int voice, const SAMPLE *spl);
     Switches an already-allocated voice to use a different sample.
     Calling reallocate_voice(voice, sample) is equivalent to:

          deallocate_voice(voice);
          voice = allocate_voice(sample);

See also:
*Note allocate_voice::.
*Note deallocate_voice::.
*Note load_sample::.
*Note SAMPLE::.

File: allegro.info,  Node: release_voice,  Next: voice_start,  Prev: reallocate_voice,  Up: Digital

25.16 release_voice
===================

void release_voice(int voice);
     Releases a soundcard voice, indicating that you are no longer
     interested in manipulating it. The sound will continue to play,
     and any resources that it is using will automatically be freed
     when it finishes. This is essentially the same as
     deallocate_voice(), but it waits for the sound to stop playing
     before taking effect.

See also:
*Note allocate_voice::.
*Note deallocate_voice::.

File: allegro.info,  Node: voice_start,  Next: voice_stop,  Prev: release_voice,  Up: Digital

25.17 voice_start
=================

void voice_start(int voice);
     Activates a voice, using whatever parameters have been set for it.

See also:
*Note Voice control::.
*Note allocate_voice::.
*Note voice_stop::.
*Note release_voice::.
*Note exstream::.

File: allegro.info,  Node: voice_stop,  Next: voice_set_priority,  Prev: voice_start,  Up: Digital

25.18 voice_stop
================

void voice_stop(int voice);
     Stops a voice, storing the current position and state so that it
     may later be resumed by calling voice_start().

See also:
*Note voice_start::.
*Note deallocate_voice::.
*Note release_voice::.
*Note exstream::.

File: allegro.info,  Node: voice_set_priority,  Next: voice_check,  Prev: voice_stop,  Up: Digital

25.19 voice_set_priority
========================

void voice_set_priority(int voice, int priority);
     Sets the priority of a voice (range 0-255). This is used to decide
     which voices should be chopped off, if you attempt to play more
     than the soundcard driver can handle.

See also:
*Note Voice control::.

File: allegro.info,  Node: voice_check,  Next: voice_get_position,  Prev: voice_set_priority,  Up: Digital

25.20 voice_check
=================

SAMPLE *voice_check(int voice);
     Checks whether a voice is currently allocated. It returns a copy
     of the sample that the voice is using, or NULL if the voice is
     inactive (ie. it has been deallocated, or the release_voice()
     function has been called and the sample has then finished playing).

See also:
*Note allocate_voice::.
*Note voice_start::.
*Note voice_get_position::.
*Note SAMPLE::.

File: allegro.info,  Node: voice_get_position,  Next: voice_set_position,  Prev: voice_check,  Up: Digital

25.21 voice_get_position
========================

int voice_get_position(int voice);
     Returns the current position of a voice, in sample units, or -1 if
     it has finished playing.

See also:
*Note Voice control::.
*Note voice_set_position::.

File: allegro.info,  Node: voice_set_position,  Next: voice_set_playmode,  Prev: voice_get_position,  Up: Digital

25.22 voice_set_position
========================

void voice_set_position(int voice, int position);
     Sets the position of a voice, in sample units.

See also:
*Note Voice control::.
*Note voice_get_position::.
*Note voice_set_playmode::.

File: allegro.info,  Node: voice_set_playmode,  Next: voice_get_volume,  Prev: voice_set_position,  Up: Digital

25.23 voice_set_playmode
========================

void voice_set_playmode(int voice, int playmode);
     Adjusts the loop status of the specified voice. This can be done
     while the voice is playing, so you can start a sample in looped
     mode (having set the loop start and end positions to the
     appropriate values), and then clear the loop flag when you want to
     end the sound, which will cause it to continue past the loop end,
     play the subsequent part of the sample, and finish in the normal
     way. The mode parameter is a bitfield containing the following
     values:

        * PLAYMODE_PLAY
          Plays the sample a single time. This is the default if you
          don't set the loop flag.

        * PLAYMODE_LOOP
          Loops repeatedly through the sample, jumping back to the loop
          start position upon reaching the loop end.

        * PLAYMODE_FORWARD
          Plays the sample from beginning to end. This is the default
          if you don't set the backward flag.

        * PLAYMODE_BACKWARD
          Reverses the direction of the sample. If you combine this
          with the loop flag, the sample jumps to the loop end position
          upon reaching the loop start (ie. you do not need to reverse
          the loop start and end values when you play the sample in
          reverse).

        * PLAYMODE_BIDIR
          When used in combination with the loop flag, causes the
          sample to change direction each time it reaches one of the
          loop points, so it alternates between playing forwards and in
          reverse.

See also:
*Note Voice control::.

File: allegro.info,  Node: voice_get_volume,  Next: voice_set_volume,  Prev: voice_set_playmode,  Up: Digital

25.24 voice_get_volume
======================

int voice_get_volume(int voice);
     Returns the current volume of the voice, range 0-255.

See also:
*Note Voice control::.
*Note voice_set_volume::.

File: allegro.info,  Node: voice_set_volume,  Next: voice_ramp_volume,  Prev: voice_get_volume,  Up: Digital

25.25 voice_set_volume
======================

void voice_set_volume(int voice, int volume);
     Sets the volume of the voice, range 0-255.

See also:
*Note Voice control::.
*Note voice_get_volume::.
*Note voice_ramp_volume::.

File: allegro.info,  Node: voice_ramp_volume,  Next: voice_stop_volumeramp,  Prev: voice_set_volume,  Up: Digital

25.26 voice_ramp_volume
=======================

void voice_ramp_volume(int voice, int time, int endvol);
     Starts a volume ramp (crescendo or diminuendo) from the current
     volume to the specified ending volume, lasting for time
     milliseconds.

See also:
*Note Voice control::.
*Note voice_set_volume::.

File: allegro.info,  Node: voice_stop_volumeramp,  Next: voice_get_frequency,  Prev: voice_ramp_volume,  Up: Digital

25.27 voice_stop_volumeramp
===========================

void voice_stop_volumeramp(int voice);
     Interrupts a volume ramp operation.

See also:
*Note voice_ramp_volume::.

File: allegro.info,  Node: voice_get_frequency,  Next: voice_set_frequency,  Prev: voice_stop_volumeramp,  Up: Digital

25.28 voice_get_frequency
=========================

int voice_get_frequency(int voice);
     Returns the current pitch of the voice, in Hz.

See also:
*Note Voice control::.
*Note voice_set_frequency::.

File: allegro.info,  Node: voice_set_frequency,  Next: voice_sweep_frequency,  Prev: voice_get_frequency,  Up: Digital

25.29 voice_set_frequency
=========================

void voice_set_frequency(int voice, int frequency);
     Sets the pitch of the voice, in Hz.

See also:
*Note Voice control::.
*Note voice_get_frequency::.
*Note voice_sweep_frequency::.

File: allegro.info,  Node: voice_sweep_frequency,  Next: voice_stop_frequency_sweep,  Prev: voice_set_frequency,  Up: Digital

25.30 voice_sweep_frequency
===========================

void voice_sweep_frequency(int voice, int time, int endfreq);
     Starts a frequency sweep (glissando) from the current pitch to the
     specified ending pitch, lasting for time milliseconds.

See also:
*Note Voice control::.
*Note voice_set_frequency::.

File: allegro.info,  Node: voice_stop_frequency_sweep,  Next: voice_get_pan,  Prev: voice_sweep_frequency,  Up: Digital

25.31 voice_stop_frequency_sweep
================================

void voice_stop_frequency_sweep(int voice);
     Interrupts a frequency sweep operation.

See also:
*Note voice_sweep_frequency::.

File: allegro.info,  Node: voice_get_pan,  Next: voice_set_pan,  Prev: voice_stop_frequency_sweep,  Up: Digital

25.32 voice_get_pan
===================

int voice_get_pan(int voice);
     Returns the current pan position, from 0 (left) to 255 (right).

See also:
*Note Voice control::.
*Note voice_set_pan::.

File: allegro.info,  Node: voice_set_pan,  Next: voice_sweep_pan,  Prev: voice_get_pan,  Up: Digital

25.33 voice_set_pan
===================

void voice_set_pan(int voice, int pan);
     Sets the pan position, ranging from 0 (left) to 255 (right).

See also:
*Note Voice control::.
*Note voice_get_pan::.
*Note voice_sweep_pan::.

File: allegro.info,  Node: voice_sweep_pan,  Next: voice_stop_pan_sweep,  Prev: voice_set_pan,  Up: Digital

25.34 voice_sweep_pan
=====================

void voice_sweep_pan(int voice, int time, int endpan);
     Starts a pan sweep (left <-> right movement) from the current
     position to the specified ending position, lasting for time
     milliseconds.

See also:
*Note Voice control::.
*Note voice_set_pan::.

File: allegro.info,  Node: voice_stop_pan_sweep,  Next: voice_set_echo,  Prev: voice_sweep_pan,  Up: Digital

25.35 voice_stop_pan_sweep
==========================

void voice_stop_pan_sweep(int voice);
     Interrupts a pan sweep operation.

See also:
*Note voice_sweep_pan::.

File: allegro.info,  Node: voice_set_echo,  Next: voice_set_tremolo,  Prev: voice_stop_pan_sweep,  Up: Digital

25.36 voice_set_echo
====================

void voice_set_echo(int voice, int strength, int delay);
     Sets the echo parameters for a voice (not currently implemented).

See also:
*Note Voice control::.

File: allegro.info,  Node: voice_set_tremolo,  Next: voice_set_vibrato,  Prev: voice_set_echo,  Up: Digital

25.37 voice_set_tremolo
=======================

void voice_set_tremolo(int voice, int rate, int depth);
     Sets the tremolo parameters for a voice (not currently
     implemented).

See also:
*Note Voice control::.

File: allegro.info,  Node: voice_set_vibrato,  Next: load_midi,  Prev: voice_set_tremolo,  Up: Digital

25.38 voice_set_vibrato
=======================

void voice_set_vibrato(int voice, int rate, int depth);
     Sets the vibrato parameters for a voice (not currently
     implemented).

See also:
*Note Voice control::.

File: allegro.info,  Node: Music,  Next: Audio,  Prev: Digital,  Up: Top

26 Music routines (MIDI)
************************

* Menu:

* load_midi::
* destroy_midi::
* lock_midi::
* play_midi::
* play_looped_midi::
* stop_midi::
* midi_pause::
* midi_resume::
* midi_seek::
* midi_out::
* load_midi_patches::
* midi_pos::
* midi_loop_start::
* midi_msg_callback::
* load_ibk::


File: allegro.info,  Node: load_midi,  Next: destroy_midi,  Prev: voice_set_vibrato,  Up: Music

26.1 load_midi
==============

MIDI *load_midi(const char *filename);
     Loads a MIDI file (handles both format 0 and format 1), returning a
     pointer to a MIDI structure, or NULL on error.

See also:
*Note destroy_midi::.
*Note play_midi::.
*Note exdodgy::.
*Note exmidi::.
*Note MIDI::.

File: allegro.info,  Node: destroy_midi,  Next: lock_midi,  Prev: load_midi,  Up: Music

26.2 destroy_midi
=================

void destroy_midi(MIDI *midi);
     Destroys a MIDI structure when you are done with it. It is safe to
     call this even when the MIDI file might be playing, because it
     checks and will kill it off if it is active.

See also:
*Note load_midi::.
*Note exdodgy::.
*Note exmidi::.
*Note MIDI::.

File: allegro.info,  Node: lock_midi,  Next: play_midi,  Prev: destroy_midi,  Up: Music

26.3 lock_midi
==============

void lock_midi(MIDI *midi);
     Under DOS, locks all the memory used by a MIDI file. You don't
     normally need to call this function because load_midi() does it
     for you.

See also:
*Note load_midi::.
*Note MIDI::.

File: allegro.info,  Node: play_midi,  Next: play_looped_midi,  Prev: lock_midi,  Up: Music

26.4 play_midi
==============

int play_midi(MIDI *midi, int loop);
     Starts playing the specified MIDI file, first stopping whatever
     music was previously playing. If the loop flag is set, the data
     will be repeated until replaced with something else, otherwise it
     will stop at the end of the file. Passing a NULL pointer will stop
     whatever music is currently playing. Returns non-zero if an error
     occurs (this may happen if a patch-caching wavetable driver is
     unable to load the required samples, or at least it might in the
     future when somebody writes some patch-caching wavetable drivers
     :-)

See also:
*Note install_sound::.
*Note load_midi::.
*Note play_looped_midi::.
*Note stop_midi::.
*Note midi_pause::.
*Note midi_seek::.
*Note midi_pos::.
*Note midi_msg_callback::.
*Note exdodgy::.
*Note exmidi::.
*Note MIDI::.

File: allegro.info,  Node: play_looped_midi,  Next: stop_midi,  Prev: play_midi,  Up: Music

26.5 play_looped_midi
=====================

int play_looped_midi(MIDI *midi, int loop_start, int loop_end);
     Starts playing a MIDI file with a user-defined loop position. When
     the player reaches the loop end position or the end of the file
     (loop_end may be -1 to only loop at EOF), it will wind back to the
     loop start point.  Both positions are specified in the same beat
     number format as the midi_pos variable.

See also:
*Note play_midi::.
*Note midi_loop_start::.
*Note MIDI::.

File: allegro.info,  Node: stop_midi,  Next: midi_pause,  Prev: play_looped_midi,  Up: Music

26.6 stop_midi
==============

void stop_midi();
     Stops whatever music is currently playing. This is the same thing
     as calling play_midi(NULL, FALSE).

See also:
*Note play_midi::.
*Note midi_pause::.

File: allegro.info,  Node: midi_pause,  Next: midi_resume,  Prev: stop_midi,  Up: Music

26.7 midi_pause
===============

void midi_pause();
     Pauses the MIDI player.

See also:
*Note play_midi::.
*Note stop_midi::.
*Note midi_resume::.
*Note midi_seek::.

File: allegro.info,  Node: midi_resume,  Next: midi_seek,  Prev: midi_pause,  Up: Music

26.8 midi_resume
================

void midi_resume();
     Resumes playback of a paused MIDI file.

See also:
*Note midi_pause::.

File: allegro.info,  Node: midi_seek,  Next: midi_out,  Prev: midi_resume,  Up: Music

26.9 midi_seek
==============

int midi_seek(int target);
     Seeks to the given midi_pos in the current MIDI file. If the
     target is earlier in the file than the current midi_pos it seeks
     from the beginning; otherwise it seeks from the current position.
     Returns zero if it could successfully seek to the requested
     position. Otherwise, a return value of 1 means it stopped playing,
     and midi_pos is set to the negative length of the MIDI file (so
     you can use this function to determine the length of a MIDI file).
     A return value of 2 means the MIDI file looped back to the start.

See also:
*Note play_midi::.
*Note midi_pos::.

File: allegro.info,  Node: midi_out,  Next: load_midi_patches,  Prev: midi_seek,  Up: Music

26.10 midi_out
==============

void midi_out(unsigned char *data, int length);
     Streams a block of MIDI commands into the player in realtime,
     allowing you to trigger notes, jingles, etc, over the top of
     whatever MIDI file is currently playing.

See also:
*Note install_sound::.
*Note load_midi_patches::.
*Note midi_recorder::.

File: allegro.info,  Node: load_midi_patches,  Next: midi_pos,  Prev: midi_out,  Up: Music

26.11 load_midi_patches
=======================

int load_midi_patches();
     Forces the MIDI driver to load the entire set of patches ready for
     use.  You will not normally need to call this, because Allegro
     automatically loads whatever data is required for the current MIDI
     file, but you must call it before sending any program change
     messages via the midi_out() command. Returns non-zero if an error
     occurred.

See also:
*Note install_sound::.
*Note midi_out::.

File: allegro.info,  Node: midi_pos,  Next: midi_loop_start,  Prev: load_midi_patches,  Up: Music

26.12 midi_pos
==============

extern volatile long midi_pos;
     Stores the current position (beat number) in the MIDI file, or
     contains a negative number if no music is currently playing.
     Useful for synchronising animations with the music, and for
     checking whether a MIDI file has finished playing.

See also:
*Note play_midi::.
*Note midi_msg_callback::.

File: allegro.info,  Node: midi_loop_start,  Next: midi_msg_callback,  Prev: midi_pos,  Up: Music

26.13 midi_loop_start
=====================

extern long midi_loop_start;

extern long midi_loop_end;
     The loop start and end points, set by the play_looped_midi()
     function.  These may safely be altered while the music is playing,
     but you should be sure they are always set to sensible values
     (start < end). If you are changing them both at the same time,
     make sure to alter them in the right order in case a MIDI
     interrupt happens to occur in between your two writes! Setting
     these values to -1 represents the start and end of the file
     respectively.

See also:
*Note play_looped_midi::.

File: allegro.info,  Node: midi_msg_callback,  Next: load_ibk,  Prev: midi_loop_start,  Up: Music

26.14 midi_msg_callback
=======================

extern void (*midi_msg_callback)(int msg, int byte1, int byte2);

extern void (*midi_meta_callback)(int type, const unsigned char *data, int length);

extern void (*midi_sysex_callback)(const unsigned char *data, int length);
     Hook functions allowing you to intercept MIDI player events. If
     set to anything other than NULL, these routines will be called for
     each MIDI message, meta-event, and system exclusive data block
     respectively. They will execute in an interrupt handler context,
     so all the code and data they use should be locked, and they must
     not call any operating system functions. In general you just use
     these routines to set some flags and respond to them later in your
     mainline code.

See also:
*Note play_midi::.

File: allegro.info,  Node: load_ibk,  Next: play_audio_stream,  Prev: midi_msg_callback,  Up: Music

26.15 load_ibk
==============

int load_ibk(char *filename, int drums);
     Reads in a .IBK patch definition file for use by the Adlib driver.
     If drums is set, it will load it as a percussion patch set,
     otherwise it will use it as a replacement set of General MIDI
     instruments. You may call this before or after initialising the
     sound code, or can simply set the ibk_file and ibk_drum_file
     variables in the configuration file to have the data loaded
     automatically. Note that this function has no effect on any
     drivers other than the Adlib one! Returns non-zero on error.

See also:
*Note install_sound::.

File: allegro.info,  Node: Audio,  Next: Recording,  Prev: Music,  Up: Top

27 Audio stream routines
************************

The audio stream functions are for playing digital sounds that are too
big to fit in a regular SAMPLE structure, either because they are huge
files that you want to load in pieces as the data is required, or
because you are doing something clever like generating the waveform on
the fly.

* Menu:

* play_audio_stream::
* stop_audio_stream::
* get_audio_stream_buffer::
* free_audio_stream_buffer::


File: allegro.info,  Node: play_audio_stream,  Next: stop_audio_stream,  Prev: load_ibk,  Up: Audio

27.1 play_audio_stream
======================

AUDIOSTREAM *play_audio_stream(int len, bits, stereo, freq, vol, pan);
     This function creates a new audio stream and starts it playing. The
     length is the size of each transfer buffer (in samples), which
     should normally (but doesn't have to) be a power of two somewhere
     around 1k in size. Larger buffers are more efficient and require
     fewer updates, but result in more latency between you providing
     the data and it actually being played. The bits parameter must be
     8 or 16, freq is the sample rate of the data in Hertz. The vol and
     pan values use the same 0-255 ranges as the regular sample playing
     functions. The stereo parameter should be set to 1 for stereo
     streams, or 0 otherwise. If you want to adjust the pitch, volume,
     or panning of a stream once it is playing, you can use the regular
     voice_*() functions with stream->voice as a parameter. The sample
     data is always in unsigned format, with stereo waveforms
     consisting of alternating left/right samples, left sample first.

See also:
*Note install_sound::.
*Note get_audio_stream_buffer::.
*Note stop_audio_stream::.
*Note exstream::.
*Note AUDIOSTREAM::.

File: allegro.info,  Node: stop_audio_stream,  Next: get_audio_stream_buffer,  Prev: play_audio_stream,  Up: Audio

27.2 stop_audio_stream
======================

void stop_audio_stream(AUDIOSTREAM *stream);
     Destroys an audio stream when it is no longer required.

See also:
*Note play_audio_stream::.
*Note exstream::.
*Note AUDIOSTREAM::.

File: allegro.info,  Node: get_audio_stream_buffer,  Next: free_audio_stream_buffer,  Prev: stop_audio_stream,  Up: Audio

27.3 get_audio_stream_buffer
============================

void *get_audio_stream_buffer(AUDIOSTREAM *stream);
     You must call this function at regular intervals while an audio
     stream is playing, to provide the next buffer of sample data (the
     smaller the stream buffer size, the more often it must be called).
     If it returns NULL, the stream is still playing the previous lot
     of data, so you don't need to do anything. If it returns a value,
     that is the location of the next buffer to be played, and you
     should load the appropriate number of samples (however many you
     specified when creating the stream) to that address, for example
     using an fread() from a disk file. After filling the buffer with
     data, call free_audio_stream_buffer() to indicate that the new
     data is now valid. Note that this function should not be called
     from a timer handler...

See also:
*Note play_audio_stream::.
*Note free_audio_stream_buffer::.
*Note exstream::.
*Note AUDIOSTREAM::.

File: allegro.info,  Node: free_audio_stream_buffer,  Next: install_sound_input,  Prev: get_audio_stream_buffer,  Up: Audio

27.4 free_audio_stream_buffer
=============================

void free_audio_stream_buffer(AUDIOSTREAM *stream);
     Call this function after get_audio_stream_buffer() returns a
     non-NULL address, to indicate that you have loaded a new block of
     samples to that location and the data is now ready to be played.

See also:
*Note get_audio_stream_buffer::.
*Note exstream::.
*Note AUDIOSTREAM::.

File: allegro.info,  Node: Recording,  Next: File,  Prev: Audio,  Up: Top

28 Recording routines
*********************

* Menu:

* install_sound_input::
* remove_sound_input::
* get_sound_input_cap_bits::
* get_sound_input_cap_stereo::
* get_sound_input_cap_rate::
* get_sound_input_cap_parm::
* set_sound_input_source::
* start_sound_input::
* stop_sound_input::
* read_sound_input::
* digi_recorder::
* midi_recorder::


File: allegro.info,  Node: install_sound_input,  Next: remove_sound_input,  Prev: free_audio_stream_buffer,  Up: Recording

28.1 install_sound_input
========================

int install_sound_input(int digi, int midi);
     Initialises the sound recorder module, returning zero on success.
     You must install the normal sound playback system before calling
     this routine. The two card parameters should use the same
     constants as install_sound(), including DIGI_NONE and MIDI_NONE to
     disable parts of the module, or DIGI_AUTODETECT and
     MIDI_AUTODETECT to guess the hardware.

See also:
*Note install_sound::.
*Note start_sound_input::.
*Note midi_recorder::.
*Note Standard config variables::.
*Note DIGI_*/DOS::.
*Note DIGI_*/Windows::.
*Note DIGI_*/Unix::.
*Note DIGI_*/BeOS::.
*Note DIGI_*/QNX::.
*Note DIGI_*/MacOSX::.
*Note MIDI_*/DOS::.
*Note MIDI_*/Windows::.
*Note MIDI_*/Unix::.
*Note MIDI_*/BeOS::.
*Note MIDI_*/QNX::.
*Note MIDI_*/MacOSX::.

File: allegro.info,  Node: remove_sound_input,  Next: get_sound_input_cap_bits,  Prev: install_sound_input,  Up: Recording

28.2 remove_sound_input
=======================

void remove_sound_input();
     Cleans up after you are finished with the sound input routines.
     You don't normally need to call this, because remove_sound()
     and/or allegro_exit() will do it for you.

See also:
*Note install_sound_input::.
*Note remove_sound::.
*Note allegro_exit::.

File: allegro.info,  Node: get_sound_input_cap_bits,  Next: get_sound_input_cap_stereo,  Prev: remove_sound_input,  Up: Recording

28.3 get_sound_input_cap_bits
=============================

int get_sound_input_cap_bits();
     Checks which sample formats are supported by the current audio
     input driver, returning one of the bitfield values:

          0 = audio input not supported
          8 = eight bit audio input is supported
          16 = sixteen bit audio input is supported
          24 = both eight and sixteen bit audio input are supported

See also:
*Note start_sound_input::.
*Note get_sound_input_cap_parm::.
*Note get_sound_input_cap_rate::.
*Note get_sound_input_cap_stereo::.

File: allegro.info,  Node: get_sound_input_cap_stereo,  Next: get_sound_input_cap_rate,  Prev: get_sound_input_cap_bits,  Up: Recording

28.4 get_sound_input_cap_stereo
===============================

int get_sound_input_cap_stereo();
     Checks whether the current audio input driver is capable of stereo
     recording.

See also:
*Note start_sound_input::.
*Note get_sound_input_cap_parm::.
*Note get_sound_input_cap_bits::.
*Note get_sound_input_cap_rate::.

File: allegro.info,  Node: get_sound_input_cap_rate,  Next: get_sound_input_cap_parm,  Prev: get_sound_input_cap_stereo,  Up: Recording

28.5 get_sound_input_cap_rate
=============================

int get_sound_input_cap_rate(int bits, int stereo);
     Returns the maximum possible sample frequency for recording in the
     specified format, or zero if these settings are not supported.

See also:
*Note start_sound_input::.
*Note get_sound_input_cap_parm::.
*Note get_sound_input_cap_bits::.
*Note get_sound_input_cap_stereo::.

File: allegro.info,  Node: get_sound_input_cap_parm,  Next: set_sound_input_source,  Prev: get_sound_input_cap_rate,  Up: Recording

28.6 get_sound_input_cap_parm
=============================

int get_sound_input_cap_parm(int rate, int bits, int stereo);
     Checks whether the specified recording frequency, number of bits,
     and mono/stereo mode are supported by the current audio driver,
     returning one of the values:

          0  = it is impossible to record in this format
          1  = recording is possible, but audio output will be suspended
          2  = recording is possible at the same time as playing other
               sounds
          -n = sampling rate not supported, but rate 'n' would work
               instead

See also:
*Note start_sound_input::.
*Note get_sound_input_cap_bits::.
*Note get_sound_input_cap_rate::.
*Note get_sound_input_cap_stereo::.

File: allegro.info,  Node: set_sound_input_source,  Next: start_sound_input,  Prev: get_sound_input_cap_parm,  Up: Recording

28.7 set_sound_input_source
===========================

int set_sound_input_source(int source);
     Selects the audio input source, returning zero on success or -1 if
     the hardware does not provide an input select register. The
     parameter should be one of the values:

          SOUND_INPUT_MIC
          SOUND_INPUT_LINE
          SOUND_INPUT_CD

See also:
*Note start_sound_input::.

File: allegro.info,  Node: start_sound_input,  Next: stop_sound_input,  Prev: set_sound_input_source,  Up: Recording

28.8 start_sound_input
======================

int start_sound_input(int rate, int bits, int stereo);
     Starts recording in the specified format, suspending audio
     playback as necessary (this will always happen with the current
     drivers). Returns the buffer size in bytes if successful, or zero
     on error.

See also:
*Note install_sound_input::.
*Note read_sound_input::.
*Note stop_sound_input::.
*Note digi_recorder::.
*Note set_sound_input_source::.
*Note get_sound_input_cap_parm::.
*Note get_sound_input_cap_bits::.
*Note get_sound_input_cap_rate::.
*Note get_sound_input_cap_stereo::.

File: allegro.info,  Node: stop_sound_input,  Next: read_sound_input,  Prev: start_sound_input,  Up: Recording

28.9 stop_sound_input
=====================

void stop_sound_input();
     Stops audio recording, switching the card back into the normal
     playback mode.

See also:
*Note start_sound_input::.

File: allegro.info,  Node: read_sound_input,  Next: digi_recorder,  Prev: stop_sound_input,  Up: Recording

28.10 read_sound_input
======================

int read_sound_input(void *buffer);
     Retrieves the most recently recorded audio buffer into the
     specified location, returning non-zero if a buffer has been copied
     or zero if no new data is yet available. The buffer size can be
     obtained by checking the return value from start_sound_input().
     You must be sure to call this function at regular intervals during
     the recording (typically around 100 times a second), or some data
     will be lost. If you are unable to do this often enough from the
     mainline code, use the digi_recorder() callback to store the
     waveform into a larger buffer of your own. Note: many cards
     produce a click or popping sound when switching between record and
     playback modes, so it is often a good idea to discard the first
     buffer after you start a recording. The waveform is always stored
     in unsigned format, with stereo data consisting of alternate
     left/right samples.

See also:
*Note start_sound_input::.

File: allegro.info,  Node: digi_recorder,  Next: midi_recorder,  Prev: read_sound_input,  Up: Recording

28.11 digi_recorder
===================

extern void (*digi_recorder)();
     If set, this function is called by the input driver whenever a new
     sample buffer becomes available, at which point you can use
     read_sound_input() to copy the data into a more permenent
     location. This routine runs in an interrupt context, so it must
     execute very quickly, the code and all memory that it touches must
     be locked, and you cannot call any operating system routines or
     access disk files.

See also:
*Note install_sound_input::.
*Note start_sound_input::.

File: allegro.info,  Node: midi_recorder,  Next: get_executable_name,  Prev: digi_recorder,  Up: Recording

28.12 midi_recorder
===================

extern void (*midi_recorder)(unsigned char data);
     If set, this function is called by the MIDI input driver whenever
     a new byte of MIDI data becomes available. It runs in an interrupt
     context, so it must execute very quickly and all the code/data
     must be locked.

See also:
*Note install_sound_input::.
*Note midi_out::.

File: allegro.info,  Node: File,  Next: Datafile,  Prev: Recording,  Up: Top

29 File and compression routines
********************************

The following routines implement a fast buffered file I/O system, which
supports the reading and writing of compressed files using a ring buffer
algorithm based on the LZSS compressor by Haruhiko Okumura. This does
not achieve quite such good compression as programs like zip and lha,
but unpacking is very fast and it does not require much memory. Packed
files always begin with the 32-bit value F_PACK_MAGIC, and autodetect
files with the value F_NOPACK_MAGIC.

The following FA_* flags are guaranteed to work: FA_RDONLY, FA_HIDDEN,
FA_SYSTEM, FA_LABEL, FA_DIREC, FA_ARCH. Do not use any other flags from
DOS/Windows or your code will not compile on another platform. Flags
FA_SYSTEM, FA_LABEL and FA_ARCH are valuable only on DOS/Windows
(entries with system flag, volume labels and archive flag). FA_RDONLY
is for directory entries with read-only flag on DOS-like systems or
unwritable by current user on Unix-like systems. FA_HIDDEN is for
entries with hidden flag on DOS-like systems or starting with '.' on
Unix (dotted files - excluding '.' and '..'). FA_DIREC represents
directories. Flags can be combined using '|' (binary OR operator).

When passed to the functions as the 'attrib' parameter, these flags
represent an upper set in which the actual flag set of a matching file
must be included. That is, in order for a file to be matching, its
attributes may contain any of the specified flags but must not contain
any of the unspecified flags. Thus, if you pass 'FA_DIREC | FA_RDONLY',
normal files and directories will be included as well as read-only
files and directories, but not hidden files and directories. Similarly,
if you pass 'FA_ARCH' then both archived and non-archived files will be
included.

* Menu:

* get_executable_name::
* fix_filename_case::
* fix_filename_slashes::
* canonicalize_filename::
* make_absolute_filename::
* make_relative_filename::
* is_relative_filename::
* replace_filename::
* replace_extension::
* append_filename::
* get_filename::
* get_extension::
* put_backslash::
* file_exists::
* exists::
* file_size::
* file_time::
* delete_file::
* for_each_file_ex::
* al_findfirst::
* al_findnext::
* al_findclose::
* find_allegro_resource::
* packfile_password::
* pack_fopen::
* pack_fclose::
* pack_fseek::
* pack_feof::
* pack_ferror::
* pack_getc::
* pack_putc::
* pack_igetw::
* pack_iputw::
* pack_igetl::
* pack_iputl::
* pack_mgetw::
* pack_mputw::
* pack_mgetl::
* pack_mputl::
* pack_fread::
* pack_fwrite::
* pack_fgets::
* pack_fputs::
* pack_fopen_chunk::
* pack_fclose_chunk::


File: allegro.info,  Node: get_executable_name,  Next: fix_filename_case,  Prev: midi_recorder,  Up: File

29.1 get_executable_name
========================

void get_executable_name(char *buf, int size);
     Fills buf with the full path to the current executable, writing at
     most size bytes.  This generally comes from argv[0], but on Unix
     systems if argv[0] does not specify the path, we search for our
     file in $PATH.



File: allegro.info,  Node: fix_filename_case,  Next: fix_filename_slashes,  Prev: get_executable_name,  Up: File

29.2 fix_filename_case
======================

char *fix_filename_case(char *path);
     Converts a filename to a standardised case. On DOS platforms, they
     will be entirely uppercase. Returns a copy of the path parameter.

See also:
*Note fix_filename_slashes::.
*Note canonicalize_filename::.

File: allegro.info,  Node: fix_filename_slashes,  Next: canonicalize_filename,  Prev: fix_filename_case,  Up: File

29.3 fix_filename_slashes
=========================

char *fix_filename_slashes(char *path);
     Converts all the directory separators in a filename to a standard
     character. On DOS platforms, this is a backslash. Returns a copy
     of the path parameter.

See also:
*Note fix_filename_case::.
*Note canonicalize_filename::.

File: allegro.info,  Node: canonicalize_filename,  Next: make_absolute_filename,  Prev: fix_filename_slashes,  Up: File

29.4 canonicalize_filename
==========================

char *canonicalize_filename(char *dest, const char *filename, int size);
     Converts any filename into its canonical form, i.e. the minimal
     absolute filename describing the same file, storing at most size
     bytes into the dest buffer. Returns a copy of the dest parameter.

See also:
*Note fix_filename_case::.
*Note fix_filename_slashes::.

File: allegro.info,  Node: make_absolute_filename,  Next: make_relative_filename,  Prev: canonicalize_filename,  Up: File

29.5 make_absolute_filename
===========================

char *make_absolute_filename(char *dest, const char *path, const char *filename, int size);
     Makes an absolute filename from an absolute path and a relative
     filename, storing at most size bytes into the dest buffer. Returns
     a copy of the dest parameter.

See also:
*Note make_relative_filename::.
*Note is_relative_filename::.

File: allegro.info,  Node: make_relative_filename,  Next: is_relative_filename,  Prev: make_absolute_filename,  Up: File

29.6 make_relative_filename
===========================

char *make_relative_filename(char *dest, const char *path, const char *filename, int size);
     Attempts to make a relative filename from an absolute path and an
     absolute filename, storing at most size bytes into the dest
     buffer. Returns a copy of the dest parameter if it succeeds or
     NULL if it fails.

See also:
*Note make_absolute_filename::.
*Note is_relative_filename::.

File: allegro.info,  Node: is_relative_filename,  Next: replace_filename,  Prev: make_relative_filename,  Up: File

29.7 is_relative_filename
=========================

int is_relative_filename(const char *filename);
     Returns TRUE if the filename is relative or FALSE if it is
     absolute.

See also:
*Note make_absolute_filename::.
*Note make_relative_filename::.

File: allegro.info,  Node: replace_filename,  Next: replace_extension,  Prev: is_relative_filename,  Up: File

29.8 replace_filename
=====================

char *replace_filename(char *dest, const char *path,  const char *filename, int size);
     Replaces the specified path+filename with a new filename tail,
     storing at most size bytes into the dest buffer. Returns a copy of
     the dest parameter.

See also:
*Note get_filename::.
*Note replace_extension::.
*Note append_filename::.

File: allegro.info,  Node: replace_extension,  Next: append_filename,  Prev: replace_filename,  Up: File

29.9 replace_extension
======================

char *replace_extension(char *dest, const char *filename,  const char *ext, int size);
     Replaces the specified filename+extension with a new extension
     tail, storing at most size bytes into the dest buffer. Returns a
     copy of the dest parameter.

See also:
*Note get_extension::.
*Note replace_filename::.

File: allegro.info,  Node: append_filename,  Next: get_filename,  Prev: replace_extension,  Up: File

29.10 append_filename
=====================

char *append_filename(char *dest, const char *path,  const char *filename, int size);
     Concatenates the specified filename onto the end of the specified
     path, storing at most size bytes into the dest buffer. Returns a
     copy of the dest parameter.

See also:
*Note replace_filename::.

File: allegro.info,  Node: get_filename,  Next: get_extension,  Prev: append_filename,  Up: File

29.11 get_filename
==================

char *get_filename(const char *path);
     When passed a completely specified file path, this returns a
     pointer to the filename portion. Both '\' and '/' are recognized
     as directory separators.

See also:
*Note get_extension::.
*Note put_backslash::.
*Note replace_filename::.

File: allegro.info,  Node: get_extension,  Next: put_backslash,  Prev: get_filename,  Up: File

29.12 get_extension
===================

char *get_extension(const char *filename);
     When passed a complete filename (with or without path information)
     this returns a pointer to the file extension.

See also:
*Note get_filename::.
*Note put_backslash::.
*Note replace_extension::.

File: allegro.info,  Node: put_backslash,  Next: file_exists,  Prev: get_extension,  Up: File

29.13 put_backslash
===================

void put_backslash(char *filename);
     If the last character of the filename is not a '\', '/', '#' or a
     device separator (ie. ':' under DOS), this routine will
     concatenate either a '\' or '/' on to it (depending on the
     platform). Note: ignore the function name, it's out of date.

See also:
*Note get_extension::.
*Note get_filename::.

File: allegro.info,  Node: file_exists,  Next: exists,  Prev: put_backslash,  Up: File

29.14 file_exists
=================

int file_exists(const char *filename, int attrib, int *aret);
     Checks whether a file matching the given name and attributes (see
     above) exists, returning non-zero if it does. If aret is not NULL,
     it will be set to the attributes of the matching file. If an error
     occurs the system error code will be stored in errno.

See also:
*Note exists::.
*Note file_size::.
*Note file_time::.

File: allegro.info,  Node: exists,  Next: file_size,  Prev: file_exists,  Up: File

29.15 exists
============

int exists(const char *filename);
     Shortcut version of file_exists(), which checks for normal files,
     which may have the archive or read-only bits set, but are not
     hidden, directories, system files, etc.

See also:
*Note file_exists::.
*Note file_size::.
*Note file_time::.

File: allegro.info,  Node: file_size,  Next: file_time,  Prev: exists,  Up: File

29.16 file_size
===============

long file_size(const char *filename);
     Returns the size of a file, in bytes. If the file does not exist
     or an error occurs, it will return zero and store the system error
     code in errno.

See also:
*Note file_exists::.
*Note file_time::.

File: allegro.info,  Node: file_time,  Next: delete_file,  Prev: file_size,  Up: File

29.17 file_time
===============

time_t file_time(const char *filename);
     Returns the modification time (number of seconds since 00:00:00 GMT
     1/1/1970) of a file. If the file does not exist or an error
     occurs, it will return zero and store the system error code in
     errno.

See also:
*Note file_exists::.
*Note file_size::.

File: allegro.info,  Node: delete_file,  Next: for_each_file_ex,  Prev: file_time,  Up: File

29.18 delete_file
=================

int delete_file(const char *filename);
     Removes a file from the disk.



File: allegro.info,  Node: for_each_file_ex,  Next: al_findfirst,  Prev: delete_file,  Up: File

29.19 for_each_file_ex
======================

int for_each_file_ex(const char *name, int in_attrib, int out_attrib, int (*callback)(const char *filename, int attrib, void *param), void *param);
     Finds all the files on disk which match the given wildcard
     specification and file attributes, and executes callback() once
     for each. in_attrib is a bitmask specifying the attributes the
     files must carry, out_attrib is a bitmask specifying the
     attributes the files must not carry; attributes which are not
     specified in either bitmasks are not taken into account for
     deciding whether callback() is invoked or not. callback() will be
     passed three arguments: the first is a string which contains the
     completed filename, the second is the actual attributes of the
     file, and the third is a void pointer which is simply a copy of
     param (you can use this for whatever you like). It must return 0
     to let the enumeration proceed, or any non-zero value to stop it.
     If an error occurs, the error code will be stored in errno but the
     enumeration won't stop. Returns the number of successful calls
     made to callback(), that is the number of times callback() was
     called and returned 0.



File: allegro.info,  Node: al_findfirst,  Next: al_findnext,  Prev: for_each_file_ex,  Up: File

29.20 al_findfirst
==================

int al_findfirst(const char *pattern, struct al_ffblk *info, int attrib);
     Low-level function for searching files. This function finds the
     first file which matches the given wildcard specification and file
     attributes (see above). The information about the file (if any)
     will be put in the al_ffblk structure which you have to provide.
     The function returns zero if a match is found, nonzero if none is
     found or if an error occured and, in the latter case, sets errno
     accordingly. The al_ffblk structure looks like:

          struct al_ffblk
          {
             int attrib;       - actual attributes of the file found
             time_t time;      - modification time of file
             long size;        - size of file
             char name[512];   - name of file
          };

     There is some other stuff in the structure as well, but it is
     there for internal use only.

See also:
*Note al_findnext::.
*Note al_findclose::.
*Note al_ffblk::.

File: allegro.info,  Node: al_findnext,  Next: al_findclose,  Prev: al_findfirst,  Up: File

29.21 al_findnext
=================

int al_findnext(struct al_ffblk *info);
     This finds the next file in a search started by al_findfirst().
     Returns zero if a match is found, nonzero if none is found or if
     an error occured and, in the latter case, sets errno accordingly.

See also:
*Note al_findfirst::.
*Note al_findclose::.
*Note al_ffblk::.

File: allegro.info,  Node: al_findclose,  Next: find_allegro_resource,  Prev: al_findnext,  Up: File

29.22 al_findclose
==================

void al_findclose(struct al_ffblk *info);
     This closes a previously opened search with al_findfirst().

See also:
*Note al_findfirst::.
*Note al_findnext::.
*Note al_ffblk::.

File: allegro.info,  Node: find_allegro_resource,  Next: packfile_password,  Prev: al_findclose,  Up: File

29.23 find_allegro_resource
===========================

int find_allegro_resource(char *dest, const char *resource,  const char *ext, const char *datafile,  const char *objectname, const char *envvar,  const char *subdir, int size);
     Searches for a support file, eg. allegro.cfg or language.dat.
     Passed a resource string describing what you are looking for,
     along with extra optional information such as the default
     extension, what datafile to look inside, what the datafile object
     name is likely to be, any special environment variable to check,
     and any subdirectory that you would like to check as well as the
     default location, this function looks in a hell of a lot of
     different places :-) Returns zero on success, and stores a full
     path to the file (at most size bytes) into the dest buffer.



File: allegro.info,  Node: packfile_password,  Next: pack_fopen,  Prev: find_allegro_resource,  Up: File

29.24 packfile_password
=======================

void packfile_password(const char *password);
     Sets the encryption password to be used for all read/write
     operations on files opened in future using Allegro's packfile
     functions (whether they are compressed or not), including all the
     save, load and config routines. Files written with an encryption
     password cannot be read unless the same password is selected, so
     be careful: if you forget the key, I can't make your data come
     back again! Pass NULL or an empty string to return to the normal,
     non-encrypted mode. If you are using this function to prevent
     people getting access to your datafiles, be careful not to store
     an obvious copy of the password in your executable: if there are
     any strings like "I'm the password for the datafile", it would be
     fairly easy to get access to your data :-)

     Note #1: when writing a packfile, you can change the password to
     whatever you want after opening the file, without affecting the
     write operation.  On the contrary, when writing a sub-chunk of a
     packfile, you must make sure that the password that was active at
     the time the sub-chunk was opened is still active before closing
     the sub-chunk. This is guaranteed to be true if you didn't call
     the packfile_password() routine in the meantime. Read operations,
     either on packfiles or sub-chunks, have no such restriction.

     Note #2: as explained above, the password is used for all
     read/write operations on files, including for several functions of
     the library that operate on files without explicitly using
     packfiles (e.g. load_bitmap()).  The unencrypted mode is mandatory
     in order for those functions to work.  Therefore remember to call
     packfile_password(NULL) before using them if you previously
     changed the password. As a rule of thumb, always call
     packfile_password(NULL) when you are done with operations on
     packfiles.

See also:
*Note pack_fopen::.
*Note load_datafile::.

File: allegro.info,  Node: pack_fopen,  Next: pack_fclose,  Prev: packfile_password,  Up: File

29.25 pack_fopen
================

PACKFILE *pack_fopen(const char *filename, const char *mode);
     Opens a file according to mode, which may contain any of the flags:

        * 'r' - open file for reading.

        * 'w' - open file for writing, overwriting any existing data.

        * 'p' - open file in packed mode. Data will be compressed as it
          is written to the file, and automatically uncompressed during
          read operations. Files created in this mode will produce
          garbage if they are read without this flag being set.

        * '!' - open file for writing in normal, unpacked mode, but add
          the value F_NOPACK_MAGIC to the start of the file, so that it
          can later be opened in packed mode and Allegro will
          automatically detect that the data does not need to be
          decompressed.

     Instead of these flags, one of the constants F_READ, F_WRITE,
     F_READ_PACKED, F_WRITE_PACKED or F_WRITE_NOPACK may be used as the
     mode parameter. On success, pack_fopen() returns a pointer to a
     file structure, and on error it returns NULL and stores an error
     code in errno. An attempt to read a normal file in packed mode
     will cause errno to be set to EDOM.

     The packfile functions also understand several "magic" filenames
     that are used for special purposes. These are:

        * "#" - read data that has been appended to your executable
          file with the exedat utility, as if it was a regular
          independent disk file.

        * 'filename.dat#object_name' - open a specific object from a
          datafile, and read from it as if it was a regular file. You
          can treat nested datafiles exactly like a normal directory
          structure, for example you could open
          'filename.dat#graphics/level1/mapdata'.

        * '#object_name' - combination of the above, reading an object
          from a datafile that has been appended onto your executable.

     With these special filenames, the contents of a datafile object or
     appended file can be read in an identical way to a normal disk
     file, so any of the file access functions in Allegro (eg.
     load_pcx() and set_config_file()) can be used to read from them.
     Note that you can't write to these special files, though: the fake
     file is read only. Also, you must save your datafile uncompressed
     or with per-object compression if you are planning on loading
     individual objects from it (otherwise there will be an excessive
     amount of seeking when it is read). Finally, be aware that the
     special Allegro object types aren't the same format as the files
     you import the data from. When you import data like bitmaps or
     samples into the grabber, they are converted into a special
     Allegro-specific format, but the '#' marker file syntax reads the
     objects as raw binary chunks. This means that if, for example, you
     want to use load_pcx to read an image from a datafile, you should
     import it as a binary block rather than as a BITMAP object.

See also:
*Note pack_fclose::.
*Note pack_fopen_chunk::.
*Note packfile_password::.
*Note pack_fread::.
*Note pack_getc::.
*Note file_select_ex::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_fclose,  Next: pack_fseek,  Prev: pack_fopen,  Up: File

29.26 pack_fclose
=================

int pack_fclose(PACKFILE *f);
     Closes the stream f previously opened with pack_fopen(). After you
     have closed the stream, performing operations on it will yield
     errors in your application (e.g. crash it) or even block your OS.

     Returns zero on success. On error, returns an error code which is
     also stored in errno. This function can fail only when writing to
     files: if the file was opened in read mode, it will always succeed.

See also:
*Note pack_fopen::.
*Note packfile_password::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_fseek,  Next: pack_feof,  Prev: pack_fclose,  Up: File

29.27 pack_fseek
================

int pack_fseek(PACKFILE *f, int offset);
     Moves the position indicator of the stream f. Unlike the standard
     fseek() function, this only supports forward movements relative to
     the current position and in read-only streams, so don't use
     negative offsets.

     Returns zero on success or a negative number on error, storing the
     error code in errno.

     Note that seeking is very slow when reading compressed files, and
     so should be avoided unless you are sure that the file is not
     compressed.

See also:
*Note pack_fopen::.
*Note pack_fopen_chunk::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_feof,  Next: pack_ferror,  Prev: pack_fseek,  Up: File

29.28 pack_feof
===============

int pack_feof(PACKFILE *f);
     pack_feof() returns nonzero as soon as you reach the end of the
     file. It does not wait for you to attempt to read beyond the end
     of the file, contrary to the ISO C feof() function. The only way
     to know whether you have read beyond the end of the file is to
     check the return value of the read operation you use (and be wary
     of pack_*getl() as EOF is also a valid return value with these
     functions).

See also:
*Note pack_fopen::.
*Note pack_fopen_chunk::.
*Note pack_ferror::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_ferror,  Next: pack_getc,  Prev: pack_feof,  Up: File

29.29 pack_ferror
=================

int pack_ferror(PACKFILE *f);
     Returns nonzero if the error indicator for the stream is set,
     indicating that an error has occurred during a previous operation
     on the stream.

     Since EOF is used to report errors by some functions, it's often
     better to use the pack_feof() function to check explicitly for end
     of file and pack_ferror() to check for errors. Both functions
     check indicators that are part of the internal state of the stream
     to detect correctly the different situations.

See also:
*Note pack_fopen::.
*Note pack_fopen_chunk::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_getc,  Next: pack_putc,  Prev: pack_ferror,  Up: File

29.30 pack_getc
===============

int pack_getc(PACKFILE *f);
     Returns the next character from the stream f, or EOF if the end of
     the file has been reached.

See also:
*Note pack_fopen::.
*Note pack_fopen_chunk::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_putc,  Next: pack_igetw,  Prev: pack_getc,  Up: File

29.31 pack_putc
===============

int pack_putc(int c, PACKFILE *f);
     Puts a character in the stream f.

     Returns zero on success, or EOF on error.

See also:
*Note pack_fopen::.
*Note pack_fopen_chunk::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_igetw,  Next: pack_iputw,  Prev: pack_putc,  Up: File

29.32 pack_igetw
================

int pack_igetw(PACKFILE *f);
     Like pack_getc, but reads a 16-bit word from a file, using Intel
     byte ordering (least significant byte first, a.k.a. little-endian).

See also:
*Note pack_getc::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_iputw,  Next: pack_igetl,  Prev: pack_igetw,  Up: File

29.33 pack_iputw
================

int pack_iputw(int c, PACKFILE *f);
     Like pack_putc, but writes a 16-bit word to a file, using Intel
     byte ordering (least significant byte first, a.k.a. little-endian).

See also:
*Note pack_putc::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_igetl,  Next: pack_iputl,  Prev: pack_iputw,  Up: File

29.34 pack_igetl
================

long pack_igetl(PACKFILE *f);
     Like pack_getc, but reads a 32-bit long from a file, using Intel
     byte ordering (least significant byte first, a.k.a. little-endian).

See also:
*Note pack_getc::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_iputl,  Next: pack_mgetw,  Prev: pack_igetl,  Up: File

29.35 pack_iputl
================

long pack_iputl(long c, PACKFILE *f);
     Like pack_putc, but writes a 32-bit long to a file, using Intel
     byte ordering (least significant byte first, a.k.a. little-endian).

See also:
*Note pack_putc::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_mgetw,  Next: pack_mputw,  Prev: pack_iputl,  Up: File

29.36 pack_mgetw
================

int pack_mgetw(PACKFILE *f);
     Like pack_getc, but reads a 16-bit word from a file, using
     Motorola byte ordering (most significant byte first, a.k.a.
     big-endian).

See also:
*Note pack_getc::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_mputw,  Next: pack_mgetl,  Prev: pack_mgetw,  Up: File

29.37 pack_mputw
================

int pack_mputw(int c, PACKFILE *f);
     Like pack_putc, but writes a 16-bit word to a file, using Motorola
     byte ordering (most significant byte first, a.k.a. big-endian).

See also:
*Note pack_putc::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_mgetl,  Next: pack_mputl,  Prev: pack_mputw,  Up: File

29.38 pack_mgetl
================

long pack_mgetl(PACKFILE *f);
     Like pack_getc, but reads a 32-bit long from a file, using
     Motorola byte ordering (most significant byte first, a.k.a.
     big-endian).

See also:
*Note pack_getc::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_mputl,  Next: pack_fread,  Prev: pack_mgetl,  Up: File

29.39 pack_mputl
================

long pack_mputl(long c, PACKFILE *f);
     Like pack_putc, but writes a 32-bit long to a file, using Motorola
     byte ordering (most significant byte first, a.k.a. big-endian).

See also:
*Note pack_putc::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_fread,  Next: pack_fwrite,  Prev: pack_mputl,  Up: File

29.40 pack_fread
================

long pack_fread(void *p, long n, PACKFILE *f);
     Reads n bytes from the stream f, storing them at the memory
     location pointed to by p.

     Returns the number of bytes read, which will be less than n if EOF
     is reached or an error occurs. Error codes are stored in errno.

See also:
*Note pack_fopen::.
*Note pack_fopen_chunk::.
*Note pack_feof::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_fwrite,  Next: pack_fgets,  Prev: pack_fread,  Up: File

29.41 pack_fwrite
=================

long pack_fwrite(const void *p, long n, PACKFILE *f);
     Writes n bytes to the stream f from memory location pointed to by
     p.

     Returns the number of bytes written, which will be less than n if
     an error occurs. Error codes are stored in errno.

See also:
*Note pack_fopen::.
*Note pack_fopen_chunk::.
*Note pack_feof::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_fgets,  Next: pack_fputs,  Prev: pack_fwrite,  Up: File

29.42 pack_fgets
================

char *pack_fgets(char *p, int max, PACKFILE *f);
     Reads a line from the stream f, storing it at location pointed to
     by p.  Stops when a linefeed is encountered, or 'max' bytes have
     been read. The end of line is handled by detecting the right
     combination of characters for the platform. This supports CR-LF
     (DOS/Windows), LF (Unix), and CR (Mac) formats.

     Returns the pointer p on success, or NULL on error.

     Note, however, that the trailing carriage return is not included
     in the returned string, in order to provide easy code portability
     across platforms. If you need the carriage return, use
     pack_fread() and/or pack_getc() instead.

See also:
*Note pack_fopen::.
*Note pack_fopen_chunk::.
*Note pack_fread::.
*Note pack_getc::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_fputs,  Next: pack_fopen_chunk,  Prev: pack_fgets,  Up: File

29.43 pack_fputs
================

int pack_fputs(const char *p, PACKFILE *f);
     Writes a string to the stream f. The input string is converted
     from the current text encoding format to UTF-8 before writing.
     Newline characters are written as \r\n on DOS and Windows
     platforms. If you don't want this behaviour, use pack_fwrite()
     and/or pack_putc() instead.

     Returns zero on success or a negative number on error.

See also:
*Note pack_fopen::.
*Note pack_fopen_chunk::.
*Note pack_fwrite::.
*Note pack_putc::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_fopen_chunk,  Next: pack_fclose_chunk,  Prev: pack_fputs,  Up: File

29.44 pack_fopen_chunk
======================

PACKFILE *pack_fopen_chunk(PACKFILE *f, int pack);
     Opens a sub-chunk of a file. Chunks are primarily intended for use
     by the datafile code, but they may also be useful for your own
     file routines. A chunk provides a logical view of part of a file,
     which can be compressed as an individual entity and will
     automatically insert and check length counts to prevent reading
     past the end of the chunk. To write a chunk to the file f, use the
     code:

          /* assumes f is a PACKFILE * which has been opened */
          f = pack_fopen_chunk(f, pack);    /* in write mode */
          write some data to f
          f = pack_fclose_chunk(f);

     The data written to the chunk will be prefixed with two length
     counts (32-bit, a.k.a. big-endian). For uncompressed chunks these
     will both be set to the size of the data in the chunk. For
     compressed chunks (created by setting the pack flag), the first
     length will be the raw size of the chunk, and the second will be
     the negative size of the uncompressed data.

     To read the chunk, use the code:

          /* assumes f is a PACKFILE * which has been opened */
          f = pack_fopen_chunk(f, FALSE);    */ in read mode */
          read data from f
          f = pack_fclose_chunk(f);

     This sequence will read the length counts created when the chunk
     was written, and automatically decompress the contents of the
     chunk if it was compressed. The length will also be used to
     prevent reading past the end of the chunk (Allegro will return EOF
     if you attempt this), and to automatically skip past any unread
     chunk data when you call pack_fclose_chunk().

     Chunks can be nested inside each other by making repeated calls to
     pack_fopen_chunk(). When writing a file, the compression status is
     inherited from the parent file, so you only need to set the pack
     flag if the parent is not compressed but you want to pack the
     chunk data. If the parent file is already open in packed mode,
     setting the pack flag will result in data being compressed twice:
     once as it is written to the chunk, and again as the chunk passes
     it on to the parent file.

See also:
*Note pack_fclose_chunk::.
*Note pack_fopen::.
*Note PACKFILE::.

File: allegro.info,  Node: pack_fclose_chunk,  Next: load_datafile,  Prev: pack_fopen_chunk,  Up: File

29.45 pack_fclose_chunk
=======================

PACKFILE *pack_fclose_chunk(PACKFILE *f);
     Closes a sub-chunk of a file, previously obtained by calling
     pack_fopen_chunk().

See also:
*Note pack_fopen_chunk::.
*Note PACKFILE::.

File: allegro.info,  Node: Datafile,  Next: Fixed,  Prev: File,  Up: Top

30 Datafile routines
********************

Datafiles are created by the grabber utility, and have a .dat extension.
They can contain bitmaps, palettes, fonts, samples, MIDI music, FLI/FLC
animations, and any other binary data that you import.

Warning: when using truecolor images, you should always set the graphics
mode before loading any bitmap data! Otherwise the pixel format (RGB or
BGR) will not be known, so the file may be converted wrongly.

See the documentation for pack_fopen() for information about how to read
directly from a specific datafile object.

* Menu:

* load_datafile::
* load_datafile_callback::
* unload_datafile::
* load_datafile_object::
* unload_datafile_object::
* find_datafile_object::
* get_datafile_property::
* register_datafile_object::
* fixup_datafile::
* Using datafiles::


File: allegro.info,  Node: load_datafile,  Next: load_datafile_callback,  Prev: pack_fclose_chunk,  Up: Datafile

30.1 load_datafile
==================

DATAFILE *load_datafile(const char *filename);
     Loads a datafile into memory, and returns a pointer to it, or NULL
     on error. If the datafile has been encrypted, you must first use
     the packfile_password() function to set the appropriate key. See
     grabber.txt for more information. If the datafile contains
     truecolor graphics, you must set the video mode or call
     set_color_conversion() before loading it.

See also:
*Note load_datafile_callback::.
*Note unload_datafile::.
*Note load_datafile_object::.
*Note set_color_conversion::.
*Note fixup_datafile::.
*Note packfile_password::.
*Note find_datafile_object::.
*Note register_datafile_object::.
*Note excustom::.
*Note exdata::.
*Note exexedat::.
*Note exgui::.
*Note exsprite::.
*Note exunicod::.
*Note DATAFILE::.

File: allegro.info,  Node: load_datafile_callback,  Next: unload_datafile,  Prev: load_datafile,  Up: Datafile

30.2 load_datafile_callback
===========================

DATAFILE *load_datafile_callback(const char *filename, void (*callback)(DATAFILE *d));
     Loads a datafile into memory, calling the specified hook function
     once for each object in the file, passing it a pointer to the
     object just read.

See also:
*Note load_datafile::.
*Note unload_datafile::.
*Note load_datafile_object::.
*Note set_color_conversion::.
*Note fixup_datafile::.
*Note packfile_password::.
*Note find_datafile_object::.
*Note register_datafile_object::.
*Note DATAFILE::.

File: allegro.info,  Node: unload_datafile,  Next: load_datafile_object,  Prev: load_datafile_callback,  Up: Datafile

30.3 unload_datafile
====================

void unload_datafile(DATAFILE *dat);
     Frees all the objects in a datafile.

See also:
*Note load_datafile::.
*Note excustom::.
*Note exdata::.
*Note exexedat::.
*Note exgui::.
*Note exsprite::.
*Note exunicod::.
*Note DATAFILE::.

File: allegro.info,  Node: load_datafile_object,  Next: unload_datafile_object,  Prev: unload_datafile,  Up: Datafile

30.4 load_datafile_object
=========================

DATAFILE *load_datafile_object(const char *filename,  const char *objectname);
     Loads a specific object from a datafile. This won't work if you
     strip the object names from the file, and it will be very slow if
     you save the file with global compression. See grabber.txt for
     more information.

See also:
*Note unload_datafile_object::.
*Note load_datafile::.
*Note set_color_conversion::.
*Note find_datafile_object::.
*Note register_datafile_object::.
*Note DATAFILE::.

File: allegro.info,  Node: unload_datafile_object,  Next: find_datafile_object,  Prev: load_datafile_object,  Up: Datafile

30.5 unload_datafile_object
===========================

void unload_datafile_object(DATAFILE *dat);
     Frees an object previously loaded by load_datafile_object().

See also:
*Note load_datafile_object::.
*Note DATAFILE::.

File: allegro.info,  Node: find_datafile_object,  Next: get_datafile_property,  Prev: unload_datafile_object,  Up: Datafile

30.6 find_datafile_object
=========================

DATAFILE *find_datafile_object(const DATAFILE *dat, const char *objectname);
     Searches an already loaded datafile for an object with the
     specified name, returning a pointer to it, or NULL if the object
     cannot be found.  It understands '/' and '#' separators for nested
     datafile paths.

See also:
*Note load_datafile::.
*Note load_datafile_object::.
*Note DATAFILE::.

File: allegro.info,  Node: get_datafile_property,  Next: register_datafile_object,  Prev: find_datafile_object,  Up: Datafile

30.7 get_datafile_property
==========================

const char *get_datafile_property(const DATAFILE *dat, int type);
     Returns the specified property string for the object, or an empty
     string if the property isn't present. See grabber.txt for more
     information.

*Note DATAFILE::.

File: allegro.info,  Node: register_datafile_object,  Next: fixup_datafile,  Prev: get_datafile_property,  Up: Datafile

30.8 register_datafile_object
=============================

void register_datafile_object(int id, void *(*load)(PACKFILE *f, long size), void (*destroy)(void *data));
     Used to add custom object types, specifying functions to load and
     destroy objects of this type. See grabber.txt for more information.

See also:
*Note load_datafile::.
*Note load_datafile_object::.
*Note PACKFILE::.

File: allegro.info,  Node: fixup_datafile,  Next: Using datafiles,  Prev: register_datafile_object,  Up: Datafile

30.9 fixup_datafile
===================

void fixup_datafile(DATAFILE *data);
     If you are using compiled datafiles (produced by the dat2s and
     dat2c utilities) on a platform that doesn't support constructors
     (currently any non GCC-based platform), or if the datafiles
     contain truecolor images, you must call this function once after
     your set the video mode that you will be using. This will ensure
     the datafiles are properly initialised in the first case and
     convert the color values into the appropriate format in the second
     case. It handles flipping between RGB and BGR formats, and
     converting between different color depths whenever that can be done
     without changing the size of the image (ie. changing 15<->16-bit
     hicolor for both bitmaps and RLE sprites, and 24<->32-bit truecolor
     for RLE sprites).

See also:
*Note set_gfx_mode::.
*Note set_color_conversion::.
*Note Differences between platforms: Differences.
*Note DATAFILE::.

File: allegro.info,  Node: Using datafiles,  Next: itofix,  Prev: fixup_datafile,  Up: Datafile

30.10 Using datafiles
=====================

When you load a datafile, you will obtain a pointer to an array of
DATAFILE structures:

     typedef struct DATAFILE
     {
        void *dat;     - pointer to the actual data
        int type;      - type of the data
        long size;     - size of the data in bytes
        void *prop;    - list of object properties
     } DATAFILE;

The type field will be one of the values:

     DAT_FILE       - dat points to a nested datafile
     DAT_DATA       - dat points to a block of binary data
     DAT_FONT       - dat points to a font object
     DAT_SAMPLE     - dat points to a sample structure
     DAT_MIDI       - dat points to a MIDI file
     DAT_PATCH      - dat points to a GUS patch file
     DAT_FLI        - dat points to an FLI/FLC animation
     DAT_BITMAP     - dat points to a BITMAP structure
     DAT_RLE_SPRITE - dat points to a RLE_SPRITE structure
     DAT_C_SPRITE   - dat points to a linear compiled sprite
     DAT_XC_SPRITE  - dat points to a mode-X compiled sprite
     DAT_PALETTE    - dat points to an array of 256 RGB structures
     DAT_END        - special flag to mark the end of the data list

The grabber program can also produce a header file defining the index of
each object within the file as a series of #defined constants, using the
names you gave the objects in the grabber. So, for example, if you have
made a datafile called foo.dat which contains a bitmap called
THE_IMAGE, you could display it with the code fragment:

     #include "foo.h"

     DATAFILE *data = load_datafile("foo.dat");
     draw_sprite(screen, data[THE_IMAGE].dat, x, y);

If you are programming in C++ you will get an error because the dat
field is a void pointer and draw_sprite() expects a BITMAP pointer. You
can get around this with a cast, eg:

     draw_sprite(screen, (BITMAP *)data[THE_IMAGE].dat, x, y);

When you load a single datafile object, you will obtain a pointer to a
single DATAFILE structure. This means that you don't access it any more
like an array, and it doesn't have any DAT_END object. Example:

     music_object = load_datafile_object("datafile.dat", "MUSIC");
     play_midi(music_object->dat);


File: allegro.info,  Node: Fixed,  Next: 3D,  Prev: Datafile,  Up: Top

31 Fixed point math routines
****************************

Allegro provides some routines for working with fixed point numbers, and
defines the type '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.

* Menu:

* itofix::
* fixtoi::
* fixfloor::
* fixceil::
* ftofix::
* fixtof::
* fixmul::
* fixdiv::
* fixadd::
* fixsub::
* Fixed point trig::
* fixtorad_r::
* radtofix_r::
* fixsin::
* fixcos::
* fixtan::
* fixasin::
* fixacos::
* fixatan::
* fixatan2::
* fixsqrt::
* fixhypot::
* Fix class::


File: allegro.info,  Node: itofix,  Next: fixtoi,  Prev: Using datafiles,  Up: Fixed

31.1 itofix
===========

fixed itofix(int x);
     Converts an integer to fixed point. This is the same thing as
     x<<16.

See also:
*Note fixtoi::.
*Note ftofix::.
*Note fixtof::.
*Note ex12bit::.
*Note ex3buf::.
*Note ex3d::.
*Note exblend::.
*Note excustom::.
*Note exfixed::.
*Note exlights::.
*Note exspline::.
*Note exsprite::.
*Note exstars::.
*Note fixed::.

File: allegro.info,  Node: fixtoi,  Next: fixfloor,  Prev: itofix,  Up: Fixed

31.2 fixtoi
===========

int fixtoi(fixed x);
     Converts fixed point to integer, rounding as required.

See also:
*Note itofix::.
*Note ftofix::.
*Note fixtof::.
*Note fixfloor::.
*Note fixceil::.
*Note ex12bit::.
*Note ex3buf::.
*Note ex3d::.
*Note exblend::.
*Note excustom::.
*Note exlights::.
*Note exspline::.
*Note exstars::.
*Note exupdate::.
*Note fixed::.

File: allegro.info,  Node: fixfloor,  Next: fixceil,  Prev: fixtoi,  Up: Fixed

31.3 fixfloor
=============

int fixfloor(fixed x);
     Returns the greatest integer not greater than x. That is, it rounds
     towards negative infinity.

See also:
*Note fixtoi::.
*Note fixceil::.
*Note fixed::.

File: allegro.info,  Node: fixceil,  Next: ftofix,  Prev: fixfloor,  Up: Fixed

31.4 fixceil
============

int fixceil(fixed x);
     Returns the smallest integer not less than x. That is, it rounds
     towards positive infinity.

See also:
*Note fixtoi::.
*Note fixfloor::.
*Note fixed::.

File: allegro.info,  Node: ftofix,  Next: fixtof,  Prev: fixceil,  Up: Fixed

31.5 ftofix
===========

fixed ftofix(double x);
     Converts a floating point value to fixed point.

See also:
*Note fixtof::.
*Note itofix::.
*Note fixtoi::.
*Note exfixed::.
*Note exspline::.
*Note exupdate::.
*Note fixed::.

File: allegro.info,  Node: fixtof,  Next: fixmul,  Prev: ftofix,  Up: Fixed

31.6 fixtof
===========

double fixtof(fixed x);
     Converts fixed point to floating point.

See also:
*Note ftofix::.
*Note itofix::.
*Note fixtoi::.
*Note exfixed::.
*Note exspline::.
*Note exstars::.
*Note fixed::.

File: allegro.info,  Node: fixmul,  Next: fixdiv,  Prev: fixtof,  Up: Fixed

31.7 fixmul
===========

fixed fixmul(fixed x, fixed y);
     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 or division by zero occurs, 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 set errno=0 before calling
     fixmul().

See also:
*Note fixadd::.
*Note fixsub::.
*Note fixdiv::.
*Note ex3buf::.
*Note excustom::.
*Note exfixed::.
*Note exspline::.
*Note exstars::.
*Note exupdate::.
*Note fixed::.

File: allegro.info,  Node: fixdiv,  Next: fixadd,  Prev: fixmul,  Up: Fixed

31.8 fixdiv
===========

fixed fixdiv(fixed x, fixed y);
     Fixed point division: see comments about fixmul().

See also:
*Note fixadd::.
*Note fixsub::.
*Note fixmul::.
*Note exfixed::.
*Note fixed::.

File: allegro.info,  Node: fixadd,  Next: fixsub,  Prev: fixdiv,  Up: Fixed

31.9 fixadd
===========

fixed fixadd(fixed x, fixed y);
     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 clamp the result, rather than just letting
     it wrap, and set errno.

See also:
*Note fixsub::.
*Note fixmul::.
*Note fixdiv::.
*Note fixed::.

File: allegro.info,  Node: fixsub,  Next: Fixed point trig,  Prev: fixadd,  Up: Fixed

31.10 fixsub
============

fixed fixsub(fixed x, fixed y);
     Fixed point subtraction: see comments about fixadd().

See also:
*Note fixadd::.
*Note fixmul::.
*Note fixdiv::.
*Note fixed::.

File: allegro.info,  Node: Fixed point trig,  Next: fixtorad_r,  Prev: fixsub,  Up: Fixed

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

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, eliminating all those tiresome 'if (angle >=
360)' checks.


File: allegro.info,  Node: fixtorad_r,  Next: radtofix_r,  Prev: Fixed point trig,  Up: Fixed

31.12 fixtorad_r
================

extern const fixed fixtorad_r;
     This constant gives a ratio which can be used to convert a number
     in fixed point angle format to a number in radians: if 'y' is an
     angle in fixed point angle format then use: 'x = fixmul(y,
     fixtorad_r);' to get its value 'x' in radians.

See also:
*Note fixmul::.
*Note radtofix_r::.
*Note fixed::.

File: allegro.info,  Node: radtofix_r,  Next: fixsin,  Prev: fixtorad_r,  Up: Fixed

31.13 radtofix_r
================

extern const fixed radtofix_r;
     This constant gives a ratio which can be used to convert a number
     in radians to a number in fixed point angle format: if 'x' is an
     angle in radians, then use: 'y = fixmul(x, radtofix_r);' to get
     its value 'y' in fixed point angle format.

See also:
*Note fixmul::.
*Note fixtorad_r::.
*Note fixed::.

File: allegro.info,  Node: fixsin,  Next: fixcos,  Prev: radtofix_r,  Up: Fixed

31.14 fixsin
============

fixed fixsin(fixed x);
     Lookup table sine.

See also:
*Note Fixed point trig::.
*Note ex12bit::.
*Note ex3buf::.
*Note exblend::.
*Note excustom::.
*Note exspline::.
*Note exupdate::.
*Note fixed::.

File: allegro.info,  Node: fixcos,  Next: fixtan,  Prev: fixsin,  Up: Fixed

31.15 fixcos
============

fixed fixcos(fixed x);
     Lookup table cosine.

See also:
*Note Fixed point trig::.
*Note ex12bit::.
*Note ex3buf::.
*Note exblend::.
*Note excustom::.
*Note exspline::.
*Note exupdate::.
*Note fixed::.

File: allegro.info,  Node: fixtan,  Next: fixasin,  Prev: fixcos,  Up: Fixed

31.16 fixtan
============

fixed fixtan(fixed x);
     Lookup table tangent.

See also:
*Note Fixed point trig::.
*Note fixed::.

File: allegro.info,  Node: fixasin,  Next: fixacos,  Prev: fixtan,  Up: Fixed

31.17 fixasin
=============

fixed fixasin(fixed x);
     Lookup table inverse sine.

See also:
*Note Fixed point trig::.
*Note fixed::.

File: allegro.info,  Node: fixacos,  Next: fixatan,  Prev: fixasin,  Up: Fixed

31.18 fixacos
=============

fixed fixacos(fixed x);
     Lookup table inverse cosine.

See also:
*Note Fixed point trig::.
*Note fixed::.

File: allegro.info,  Node: fixatan,  Next: fixatan2,  Prev: fixacos,  Up: Fixed

31.19 fixatan
=============

fixed fixatan(fixed x);
     Fixed point inverse tangent.

See also:
*Note Fixed point trig::.
*Note fixed::.

File: allegro.info,  Node: fixatan2,  Next: fixsqrt,  Prev: fixatan,  Up: Fixed

31.20 fixatan2
==============

fixed fixatan2(fixed y, fixed x);
     Fixed point version of the libc atan2() routine.

See also:
*Note Fixed point trig::.
*Note exlights::.
*Note exspline::.
*Note fixed::.

File: allegro.info,  Node: fixsqrt,  Next: fixhypot,  Prev: fixatan2,  Up: Fixed

31.21 fixsqrt
=============

fixed fixsqrt(fixed x);
     Fixed point square root.

See also:
*Note Fixed point trig::.
*Note exfixed::.
*Note exlights::.
*Note exspline::.
*Note fixed::.

File: allegro.info,  Node: fixhypot,  Next: Fix class,  Prev: fixsqrt,  Up: Fixed

31.22 fixhypot
==============

fixed fixhypot(fixed x, fixed y);
     Fixed point hypotenuse (returns the square root of x*x + y*y).

See also:
*Note Fixed point trig::.
*Note fixed::.

File: allegro.info,  Node: Fix class,  Next: identity_matrix,  Prev: fixhypot,  Up: Fixed

31.23 Fix class
===============

If you are programming in C++ you can ignore all the above and use the
fix class instead, which overloads a lot of operators to provide
automatic conversion to and from integer and floating point values, and
calls the above routines as they are required. You should not mix the
fix class with the fixed typedef though, because the compiler will
mistake the fixed values for regular integers and insert unnecessary
conversions. For example, if x is an object of class fix, calling
fixsqrt(x) will return the wrong result.  You should use the overloaded
sqrt(x) or x.sqrt() instead.


File: allegro.info,  Node: 3D,  Next: Quaternion,  Prev: Fixed,  Up: Top

32 3D math routines
*******************

Allegro contains some 3d helper functions for manipulating vectors,
constructing and using transformation matrices, and doing perspective
projections from 3d space onto the screen. It is not, and never will
be, a fully fledged 3d library (my goal is to supply generic support
routines, not shrink-wrapped graphics code :-) but these functions may
be useful for developing your own 3d code.

Allegro uses a right-handed coordinate system, i.e. if you point the
thumb of your right hand along the x axis, and the index finger along
the y axis, your middle finger points in the direction of the z axis.
This also means, for any rotation, if you point the thumb of your right
hand along the axis of rotation, then the fingers curl in the positive
direction of rotation.

All the 3d math functions are available in two versions: one which uses
fixed point arithmetic, and another which uses floating point. The
syntax for these is identical, but the floating point functions and
structures are postfixed with '_f', eg. the fixed point function
cross_product() has a floating point equivalent cross_product_f(). If
you are programming in C++, Allegro also overloads these functions for
use with the 'fix' class.

3d transformations are accomplished by the use of a modelling matrix.
This is a 4x4 array of numbers that can be multiplied with a 3d point
to produce a different 3d point. By putting the right values into the
matrix, it can be made to do various operations like translation,
rotation, and scaling. The clever bit is that you can multiply two
matrices together to produce a third matrix, and this will have the
same effect on points as applying the original two matrices one after
the other. For example, if you have one matrix that rotates a point and
another that shifts it sideways, you can combine them to produce a
matrix that will do the rotation and the shift in a single step. You
can build up extremely complex transformations in this way, while only
ever having to multiply each point by a single matrix.

Allegro actually cheats in the way it implements the matrix structure.
Rotation and scaling of a 3d point can be done with a simple 3x3
matrix, but in order to translate it and project it onto the screen,
the matrix must be extended to 4x4, and the point extended into 4d
space by the addition of an extra coordinate, w=1. This is a bad thing
in terms of efficiency, but fortunately an optimisation is possible.
Given the 4x4 matrix:

     ( a, b, c, d )
     ( e, f, g, h )
     ( i, j, k, l )
     ( m, n, o, p )

a pattern can be observed in which parts of it do what. The top left 3x3
grid implements rotation and scaling. The three values in the top right
column (d, h, and l) implement translation, and as long as the matrix is
only used for affine transformations, m, n and o will always be zero
and p will always be 1. If you don't know what affine means, read Foley
& Van Damme: basically it covers scaling, translation, and rotation,
but not projection. Since Allegro uses a separate function for
projection, the matrix functions only need to support affine
transformations, which means that there is no need to store the bottom
row of the matrix. Allegro implicitly assumes that it contains
(0,0,0,1), and optimises the matrix manipulation functions accordingly.
Read chapter "Structures and types defined by Allegro" for an internal
view of the MATRIX/_f structures.

* Menu:

* identity_matrix::
* get_translation_matrix::
* get_scaling_matrix::
* get_x_rotate_matrix::
* get_y_rotate_matrix::
* get_z_rotate_matrix::
* get_rotation_matrix::
* get_align_matrix::
* get_align_matrix_f::
* get_vector_rotation_matrix::
* get_transformation_matrix::
* get_transformation_matrix_f::
* get_camera_matrix::
* get_camera_matrix_f::
* qtranslate_matrix::
* qscale_matrix::
* matrix_mul::
* vector_length::
* normalize_vector::
* dot_product::
* cross_product::
* polygon_z_normal::
* apply_matrix::
* set_projection_viewport::
* persp_project::


File: allegro.info,  Node: identity_matrix,  Next: get_translation_matrix,  Prev: Fix class,  Up: 3D

32.1 identity_matrix
====================

extern MATRIX identity_matrix;

extern MATRIX_f identity_matrix_f;
     Global variables containing the 'do nothing' identity matrix.
     Multiplying by the identity matrix has no effect.

*Note MATRIX::.
*Note MATRIX_f::.

File: allegro.info,  Node: get_translation_matrix,  Next: get_scaling_matrix,  Prev: identity_matrix,  Up: 3D

32.2 get_translation_matrix
===========================

void get_translation_matrix(MATRIX *m, fixed x, fixed y, fixed z);

void get_translation_matrix_f(MATRIX_f *m, float x, float y, float z);
     Constructs a translation matrix, storing it in m. When applied to
     the point (px, py, pz), this matrix will produce the point (px+x,
     py+y, pz+z). In other words, it moves things sideways.

See also:
*Note apply_matrix::.
*Note get_transformation_matrix::.
*Note qtranslate_matrix::.
*Note exstars::.
*Note fixed::.
*Note MATRIX::.
*Note MATRIX_f::.

File: allegro.info,  Node: get_scaling_matrix,  Next: get_x_rotate_matrix,  Prev: get_translation_matrix,  Up: 3D

32.3 get_scaling_matrix
=======================

void get_scaling_matrix(MATRIX *m, fixed x, fixed y, fixed z);

void get_scaling_matrix_f(MATRIX_f *m, float x, float y, float z);
     Constructs a scaling matrix, storing it in m. When applied to the
     point (px, py, pz), this matrix will produce the point (px*x,
     py*y, pz*z). In other words, it stretches or shrinks things.

See also:
*Note apply_matrix::.
*Note get_transformation_matrix::.
*Note qscale_matrix::.
*Note fixed::.
*Note MATRIX::.
*Note MATRIX_f::.

File: allegro.info,  Node: get_x_rotate_matrix,  Next: get_y_rotate_matrix,  Prev: get_scaling_matrix,  Up: 3D

32.4 get_x_rotate_matrix
========================

void get_x_rotate_matrix(MATRIX *m, fixed r);

void get_x_rotate_matrix_f(MATRIX_f *m, float r);
     Construct X axis rotation matrices, storing them in m. When
     applied to a point, these matrices will rotate it about the X axis
     by the specified angle (given in binary, 256 degrees to a circle
     format).

See also:
*Note apply_matrix::.
*Note get_rotation_matrix::.
*Note get_y_rotate_matrix::.
*Note get_z_rotate_matrix::.
*Note fixed::.
*Note MATRIX::.
*Note MATRIX_f::.

File: allegro.info,  Node: get_y_rotate_matrix,  Next: get_z_rotate_matrix,  Prev: get_x_rotate_matrix,  Up: 3D

32.5 get_y_rotate_matrix
========================

void get_y_rotate_matrix(MATRIX *m, fixed r);

void get_y_rotate_matrix_f(MATRIX_f *m, float r);
     Construct Y axis rotation matrices, storing them in m. When
     applied to a point, these matrices will rotate it about the Y axis
     by the specified angle (given in binary, 256 degrees to a circle
     format).

See also:
*Note apply_matrix::.
*Note get_rotation_matrix::.
*Note get_x_rotate_matrix::.
*Note get_z_rotate_matrix::.
*Note fixed::.
*Note MATRIX::.
*Note MATRIX_f::.

File: allegro.info,  Node: get_z_rotate_matrix,  Next: get_rotation_matrix,  Prev: get_y_rotate_matrix,  Up: 3D

32.6 get_z_rotate_matrix
========================

void get_z_rotate_matrix(MATRIX *m, fixed r);

void get_z_rotate_matrix_f(MATRIX_f *m, float r);
     Construct Z axis rotation matrices, storing them in m. When
     applied to a point, these matrices will rotate it about the Z axis
     by the specified angle (given in binary, 256 degrees to a circle
     format).

See also:
*Note apply_matrix::.
*Note get_rotation_matrix::.
*Note get_x_rotate_matrix::.
*Note get_y_rotate_matrix::.
*Note fixed::.
*Note MATRIX::.
*Note MATRIX_f::.

File: allegro.info,  Node: get_rotation_matrix,  Next: get_align_matrix,  Prev: get_z_rotate_matrix,  Up: 3D

32.7 get_rotation_matrix
========================

void get_rotation_matrix(MATRIX *m, fixed x, fixed y, fixed z);

void get_rotation_matrix_f(MATRIX_f *m, float x, float y, float z);
     Constructs a transformation matrix which will rotate points around
     all three axis by the specified amounts (given in binary, 256
     degrees to a circle format).

See also:
*Note apply_matrix::.
*Note get_transformation_matrix::.
*Note get_vector_rotation_matrix::.
*Note get_x_rotate_matrix::.
*Note get_y_rotate_matrix::.
*Note get_z_rotate_matrix::.
*Note get_align_matrix::.
*Note ex12bit::.
*Note exquat::.
*Note exstars::.
*Note fixed::.
*Note MATRIX::.
*Note MATRIX_f::.

File: allegro.info,  Node: get_align_matrix,  Next: get_align_matrix_f,  Prev: get_rotation_matrix,  Up: 3D

32.8 get_align_matrix
=====================

void get_align_matrix(MATRIX *m, fixed xfront, yfront, zfront,  fixed xup, fixed yup, fixed zup);
     Rotates a matrix so that it is aligned along the specified
     coordinate vectors (they need not be normalized or perpendicular,
     but the up and front must not be equal). A front vector of 1,0,0
     and up vector of 0,1,0 will return the identity matrix.

See also:
*Note apply_matrix::.
*Note get_camera_matrix::.
*Note fixed::.
*Note MATRIX::.

File: allegro.info,  Node: get_align_matrix_f,  Next: get_vector_rotation_matrix,  Prev: get_align_matrix,  Up: 3D

32.9 get_align_matrix_f
=======================

void get_align_matrix_f(MATRIX *m, float xfront, yfront, zfront,  float xup, yup, zup);
     Floating point version of get_align_matrix().

See also:
*Note get_align_matrix::.
*Note MATRIX::.

File: allegro.info,  Node: get_vector_rotation_matrix,  Next: get_transformation_matrix,  Prev: get_align_matrix_f,  Up: 3D

32.10 get_vector_rotation_matrix
================================

void get_vector_rotation_matrix(MATRIX *m, fixed x, y, z, fixed a);

void get_vector_rotation_matrix_f(MATRIX_f *m, float x, y, z, float a);
     Constructs a transformation matrix which will rotate points around
     the specified x,y,z vector by the specified angle (given in
     binary, 256 degrees to a circle format).

See also:
*Note apply_matrix::.
*Note get_rotation_matrix::.
*Note get_align_matrix::.
*Note excamera::.
*Note fixed::.
*Note MATRIX::.
*Note MATRIX_f::.

File: allegro.info,  Node: get_transformation_matrix,  Next: get_transformation_matrix_f,  Prev: get_vector_rotation_matrix,  Up: 3D

32.11 get_transformation_matrix
===============================

void get_transformation_matrix(MATRIX *m, fixed scale, fixed xrot, yrot, zrot, x, y, z);
     Constructs a transformation matrix which will rotate points around
     all three axis by the specified amounts (given in binary, 256
     degrees to a circle format), scale the result by the specified
     amount (pass 1 for no change of scale), and then translate to the
     requested x, y, z position.

See also:
*Note apply_matrix::.
*Note get_rotation_matrix::.
*Note get_scaling_matrix::.
*Note get_translation_matrix::.
*Note fixed::.
*Note MATRIX::.

File: allegro.info,  Node: get_transformation_matrix_f,  Next: get_camera_matrix,  Prev: get_transformation_matrix,  Up: 3D

32.12 get_transformation_matrix_f
=================================

void get_transformation_matrix_f(MATRIX_f *m, float scale, float xrot, yrot, zrot, x, y, z);
     Floating point version of get_transformation_matrix().

See also:
*Note get_transformation_matrix::.
*Note MATRIX_f::.

File: allegro.info,  Node: get_camera_matrix,  Next: get_camera_matrix_f,  Prev: get_transformation_matrix_f,  Up: 3D

32.13 get_camera_matrix
=======================

void get_camera_matrix(MATRIX *m, fixed x, y, z, xfront, yfront, zfront, fixed xup, yup, zup, fov, aspect);
     Constructs a camera matrix for translating world-space objects
     into a normalised view space, ready for the perspective
     projection. The x, y, and z parameters specify the camera
     position, xfront, yfront, and zfront are the 'in front' vector
     specifying which way the camera is facing (this can be any length:
     normalisation is not required), and xup, yup, and zup are the 'up'
     direction vector. The fov parameter specifies the field of view
     (ie. width of the camera focus) in binary, 256 degrees to the
     circle format. For typical projections, a field of view in the
     region 32-48 will work well. Finally, the aspect ratio is used to
     scale the Y dimensions of the image relative to the X axis, so you
     can use it to adjust the proportions of the output image (set it
     to 1 for no scaling). Note that versions prior to 4.1.0 multiplied
     this aspect ratio by 4/3.

See also:
*Note apply_matrix::.
*Note get_align_matrix::.
*Note fixed::.
*Note MATRIX::.

File: allegro.info,  Node: get_camera_matrix_f,  Next: qtranslate_matrix,  Prev: get_camera_matrix,  Up: 3D

32.14 get_camera_matrix_f
=========================

void get_camera_matrix_f(MATRIX_f *m, float x, y, z, xfront, yfront, zfront, float xup, yup, zup, fov, aspect);
     Floating point version of get_camera_matrix().

See also:
*Note get_camera_matrix::.
*Note MATRIX_f::.

File: allegro.info,  Node: qtranslate_matrix,  Next: qscale_matrix,  Prev: get_camera_matrix_f,  Up: 3D

32.15 qtranslate_matrix
=======================

void qtranslate_matrix(MATRIX *m, fixed x, fixed y, fixed z);

void qtranslate_matrix_f(MATRIX_f *m, float x, float y, float z);
     Optimised routine for translating an already generated matrix: this
     simply adds in the translation offset, so there is no need to
     build two temporary matrices and then multiply them together.

See also:
*Note get_translation_matrix::.
*Note fixed::.
*Note MATRIX::.
*Note MATRIX_f::.

File: allegro.info,  Node: qscale_matrix,  Next: matrix_mul,  Prev: qtranslate_matrix,  Up: 3D

32.16 qscale_matrix
===================

void qscale_matrix(MATRIX *m, fixed scale);

void qscale_matrix_f(MATRIX_f *m, float scale);
     Optimised routine for scaling an already generated matrix: this
     simply adds in the scale factor, so there is no need to build two
     temporary matrices and then multiply them together.

See also:
*Note get_scaling_matrix::.
*Note fixed::.
*Note MATRIX::.
*Note MATRIX_f::.

File: allegro.info,  Node: matrix_mul,  Next: vector_length,  Prev: qscale_matrix,  Up: 3D

32.17 matrix_mul
================

void matrix_mul(const MATRIX *m1, *m2, MATRIX *out);

void matrix_mul_f(const MATRIX_f *m1, *m2, MATRIX_f *out);
     Multiplies two matrices, storing the result in out (this may be a
     duplicate of one of the input matrices, but it is faster when the
     inputs and output are all different). The resulting matrix will
     have the same effect as the combination of m1 and m2, ie. when
     applied to a point p, (p * out) = ((p * m1) * m2). Any number of
     transformations can be concatenated in this way. Note that matrix
     multiplication is not commutative, ie. matrix_mul(m1, m2) !=
     matrix_mul(m2, m1).

See also:
*Note apply_matrix::.
*Note exquat::.
*Note exscn3d::.
*Note MATRIX::.
*Note MATRIX_f::.

File: allegro.info,  Node: vector_length,  Next: normalize_vector,  Prev: matrix_mul,  Up: 3D

32.18 vector_length
===================

fixed vector_length(fixed x, fixed y, fixed z);

float vector_length_f(float x, float y, float z);
     Calculates the length of the vector (x, y, z), using that good 'ole
     Pythagoras theorem.

See also:
*Note normalize_vector::.
*Note fixed::.

File: allegro.info,  Node: normalize_vector,  Next: dot_product,  Prev: vector_length,  Up: 3D

32.19 normalize_vector
======================

void normalize_vector(fixed *x, fixed *y, fixed *z);

void normalize_vector_f(float *x, float *y, float *z);
     Converts the vector (*x, *y, *z) to a unit vector. This points in
     the same direction as the original vector, but has a length of one.

See also:
*Note vector_length::.
*Note dot_product::.
*Note cross_product::.
*Note exstars::.
*Note fixed::.

File: allegro.info,  Node: dot_product,  Next: cross_product,  Prev: normalize_vector,  Up: 3D

32.20 dot_product
=================

fixed dot_product(fixed x1, y1, z1, x2, y2, z2);

float dot_product_f(float x1, y1, z1, x2, y2, z2);
     Calculates the dot product (x1, y1, z1) . (x2, y2, z2), returning
     the result.

See also:
*Note cross_product::.
*Note normalize_vector::.
*Note exstars::.
*Note fixed::.

File: allegro.info,  Node: cross_product,  Next: polygon_z_normal,  Prev: dot_product,  Up: 3D

32.21 cross_product
===================

void cross_product(fixed x1, y1, z1, x2, y2, z2, *xout, *yout, *zout);

void cross_product_f(float x1, y1, z1, x2, y2, z2, *xout, *yout, *zout);
     Calculates the cross product (x1, y1, z1) x (x2, y2, z2), storing
     the result in (*xout, *yout, *zout). The cross product is
     perpendicular to both of the input vectors, so it can be used to
     generate polygon normals.

See also:
*Note dot_product::.
*Note polygon_z_normal::.
*Note normalize_vector::.
*Note exstars::.
*Note fixed::.

File: allegro.info,  Node: polygon_z_normal,  Next: apply_matrix,  Prev: cross_product,  Up: 3D

32.22 polygon_z_normal
======================

fixed polygon_z_normal(const V3D *v1, *v2, *v3);

float polygon_z_normal_f(const V3D_f *v1, *v2, *v3);
     Finds the Z component of the normal vector to the specified three
     vertices (which must be part of a convex polygon). This is used
     mainly in back-face culling. The back-faces of closed polyhedra
     are never visible to the viewer, therefore they never need to be
     drawn. This can cull on average half the polygons from a scene. If
     the normal is negative the polygon can safely be culled. If it is
     zero, the polygon is perpendicular to the screen.

See also:
*Note cross_product::.
*Note ex3d::.
*Note fixed::.
*Note V3D::.
*Note V3D_f::.

File: allegro.info,  Node: apply_matrix,  Next: set_projection_viewport,  Prev: polygon_z_normal,  Up: 3D

32.23 apply_matrix
==================

void apply_matrix(const MATRIX *m, fixed x, y, z, *xout, *yout, *zout);

void apply_matrix_f(const MATRIX_f *m, float x, y, z, *xout, *yout, *zout);
     Multiplies the point (x, y, z) by the transformation matrix m,
     storing the result in (*xout, *yout, *zout).

See also:
*Note matrix_mul::.
*Note ex12bit::.
*Note ex3d::.
*Note exstars::.
*Note fixed::.
*Note MATRIX::.
*Note MATRIX_f::.

File: allegro.info,  Node: set_projection_viewport,  Next: persp_project,  Prev: apply_matrix,  Up: 3D

32.24 set_projection_viewport
=============================

void set_projection_viewport(int x, int y, int w, int h);
     Sets the viewport used to scale the output of the persp_project()
     function. Pass the dimensions of the screen area you want to draw
     onto, which will typically be 0, 0, SCREEN_W, and SCREEN_H.

See also:
*Note persp_project::.
*Note ex3d::.
*Note excamera::.
*Note exquat::.
*Note exscn3d::.
*Note exstars::.
*Note exzbuf::.

File: allegro.info,  Node: persp_project,  Next: identity_quat,  Prev: set_projection_viewport,  Up: 3D

32.25 persp_project
===================

void persp_project(fixed x, y, z, *xout, *yout);

void persp_project_f(float x, y, z, *xout, *yout);
     Projects the 3d point (x, y, z) into 2d screen space, storing the
     result in (*xout, *yout) and using the scaling parameters
     previously set by calling set_projection_viewport(). This function
     projects from the normalized viewing pyramid, which has a camera
     at the origin and facing along the positive z axis. The x axis
     runs left/right, y runs up/down, and z increases with depth into
     the screen. The camera has a 90 degree field of view, ie. points
     on the planes x=z and -x=z will map onto the left and right edges
     of the screen, and the planes y=z and -y=z map to the top and
     bottom of the screen. If you want a different field of view or
     camera location, you should transform all your objects with an
     appropriate viewing matrix, eg. to get the effect of panning the
     camera 10 degrees to the left, rotate all your objects 10 degrees
     to the right.

See also:
*Note set_projection_viewport::.
*Note ex3d::.
*Note exstars::.
*Note fixed::.

File: allegro.info,  Node: Quaternion,  Next: GUI,  Prev: 3D,  Up: Top

33 Quaternion math routines
***************************

Quaternions are an alternate way to represent the rotation part of a
transformation, and can be easier to manipulate than matrices. As with a
matrix, you can encode a geometric transformations in one, concatenate
several of them to merge multiple transformations, and apply them to a
vector, but they can only store pure rotations. The big advantage is
that you can accurately interpolate between two quaternions to get a
part-way rotation, avoiding the gimbal problems of the more
conventional euler angle interpolation.

Quaternions only have floating point versions, without any _f suffix.
Other than that, most of the quaternion functions correspond with a
matrix function that performs a similar operation.

Quaternion means 'of four parts', and that's exactly what it is. Here
is the structure:

     typedef struct QUAT
     {
        float w, x, y, z;
     }

You will have lots of fun figuring out what these numbers actually
mean, but that is beyond the scope of this documentation. Quaternions
do work - trust me.

* Menu:

* identity_quat::
* get_x_rotate_quat::
* get_rotation_quat::
* get_vector_rotation_quat::
* quat_to_matrix::
* matrix_to_quat::
* quat_mul::
* apply_quat::
* quat_interpolate::
* quat_slerp::


File: allegro.info,  Node: identity_quat,  Next: get_x_rotate_quat,  Prev: persp_project,  Up: Quaternion

33.1 identity_quat
==================

extern QUAT identity_quat;
     Global variable containing the 'do nothing' identity quaternion.
     Multiplying by the identity quaternion has no effect.

*Note QUAT::.

File: allegro.info,  Node: get_x_rotate_quat,  Next: get_rotation_quat,  Prev: identity_quat,  Up: Quaternion

33.2 get_x_rotate_quat
======================

void get_x_rotate_quat(QUAT *q, float r);

void get_y_rotate_quat(QUAT *q, float r);

void get_z_rotate_quat(QUAT *q, float r);
     Construct axis rotation quaternions, storing them in q. When
     applied to a point, these quaternions will rotate it about the
     relevant axis by the specified angle (given in binary, 256 degrees
     to a circle format).

*Note QUAT::.

File: allegro.info,  Node: get_rotation_quat,  Next: get_vector_rotation_quat,  Prev: get_x_rotate_quat,  Up: Quaternion

33.3 get_rotation_quat
======================

void get_rotation_quat(QUAT *q, float x, float y, float z);
     Constructs a quaternion that will rotate points around all three
     axis by the specified amounts (given in binary, 256 degrees to a
     circle format).

See also:
*Note exquat::.
*Note QUAT::.

File: allegro.info,  Node: get_vector_rotation_quat,  Next: quat_to_matrix,  Prev: get_rotation_quat,  Up: Quaternion

33.4 get_vector_rotation_quat
=============================

void get_vector_rotation_quat(QUAT *q, float x, y, z, float a);
     Constructs a quaternion that will rotate points around the
     specified x,y,z vector by the specified angle (given in binary,
     256 degrees to a circle format).

*Note QUAT::.

File: allegro.info,  Node: quat_to_matrix,  Next: matrix_to_quat,  Prev: get_vector_rotation_quat,  Up: Quaternion

33.5 quat_to_matrix
===================

void quat_to_matrix(const QUAT *q, MATRIX_f *m);
     Constructs a rotation matrix from a quaternion.

See also:
*Note exquat::.
*Note MATRIX_f::.
*Note QUAT::.

File: allegro.info,  Node: matrix_to_quat,  Next: quat_mul,  Prev: quat_to_matrix,  Up: Quaternion

33.6 matrix_to_quat
===================

void matrix_to_quat(const MATRIX_f *m, QUAT *q);
     Constructs a quaternion from a rotation matrix. Translation is
     discarded during the conversion. Use get_align_matrix_f() if the
     matrix is not orthonormalized, because strange things may happen
     otherwise.

*Note MATRIX_f::.
*Note QUAT::.

File: allegro.info,  Node: quat_mul,  Next: apply_quat,  Prev: matrix_to_quat,  Up: Quaternion

33.7 quat_mul
=============

void quat_mul(const QUAT *p, const QUAT *q, QUAT *out);
     Multiplies two quaternions, storing the result in out. The
     resulting quaternion will have the same effect as the combination
     of p and q, ie.  when applied to a point, (point * out) = ((point
     * p) * q). Any number of rotations can be concatenated in this
     way. Note that quaternion multiplication is not commutative, ie.
     quat_mul(p, q) != quat_mul(q, p).

*Note QUAT::.

File: allegro.info,  Node: apply_quat,  Next: quat_interpolate,  Prev: quat_mul,  Up: Quaternion

33.8 apply_quat
===============

void apply_quat(const QUAT *q, float x, y, z, *xout, *yout, *zout);
     Multiplies the point (x, y, z) by the quaternion q, storing the
     result in (*xout, *yout, *zout). This is quite a bit slower than
     apply_matrix_f(), so only use it to translate a few points. If you
     have many points, it is much more efficient to call
     quat_to_matrix() and then use apply_matrix_f().

*Note QUAT::.

File: allegro.info,  Node: quat_interpolate,  Next: quat_slerp,  Prev: apply_quat,  Up: Quaternion

33.9 quat_interpolate
=====================

void quat_interpolate(const QUAT *from, *to, float t, QUAT *out);
     Constructs a quaternion that represents a rotation between from
     and to.  The argument t can be anything between 0 and 1 and
     represents where between from and to the result will be. 0 returns
     from, 1 returns to, and 0.5 will return a rotation exactly in
     between. The result is copied to out. This function will create
     the short rotation (less than 180 degrees) between from and to.

See also:
*Note exquat::.
*Note QUAT::.

File: allegro.info,  Node: quat_slerp,  Next: d_clear_proc,  Prev: quat_interpolate,  Up: Quaternion

33.10 quat_slerp
================

void quat_slerp(const QUAT *from, *to, float t, QUAT *out, int how);
     The same as quat_interpolate(), but allows more control over how
     the rotation is done. The how parameter can be any one of the
     values:

          QUAT_SHORT  - like quat_interpolate(), use shortest path
          QUAT_LONG   - rotation will be greater than 180 degrees
          QUAT_CW     - rotate clockwise when viewed from above
          QUAT_CCW    - rotate counterclockwise when viewed from above
          QUAT_USER   - the quaternions are interpolated exactly as
                        given

*Note QUAT::.

File: allegro.info,  Node: GUI,  Next: DOS,  Prev: Quaternion,  Up: Top

34 GUI routines
***************

Allegro contains an object-oriented dialog manager, which was originally
based on the Atari GEM system (form_do(), objc_draw(), etc: old ST
programmers will know what I'm talking about :-) You can use the GUI
as-is to knock out simple interfaces for things like the test program
and grabber utility, or you can use it as a basis for more complicated
systems of your own. Allegro lets you define your own object types by
writing new dialog procedures, so you can take complete control over
the visual aspects of the interface while still using Allegro to handle
input from the mouse, keyboard, joystick, etc.

A GUI dialog is stored as an array of DIALOG objects, read chapter
"Structures and types defined by Allegro" for an internal description
of the DIALOG structure. The array should end with an object which has
the proc pointer set to NULL. Each object has a flags field which may
contain any combination of the bit flags:

     D_EXIT          - this object should close the dialog when it is
                       clicked
     D_SELECTED      - this object is selected
     D_GOTFOCUS      - this object has got the input focus
     D_GOTMOUSE      - the mouse is currently on top of this object
     D_HIDDEN        - this object is hidden and inactive
     D_DISABLED      - this object is greyed-out and inactive
     D_DIRTY         - this object needs to be redrawn
     D_INTERNAL      - don't use this! It is for internal use by the
                       library...
     D_USER          - any powers of two above this are free for your
                       own use

Each object is controlled by a dialog procedure, which is stored in the
proc pointer. This will be called by the dialog manager whenever any
action concerning the object is required, or you can call it directly
with the object_message() function. The dialog procedure should follow
the form:

     int foo(int msg, DIALOG *d, int c);

It will be passed a flag (msg) indicating what action it should
perform, a pointer to the object concerned (d), and if msg is MSG_CHAR
or MSG_XCHAR, the key that was pressed (c). Note that d is a pointer to
a specific object, and not to the entire dialog.

The dialog procedure should return one of the values:

     D_O_K          - normal return status
     D_CLOSE        - tells the dialog manager to close the dialog
     D_REDRAW       - tells the dialog manager to redraw the entire
                      dialog
     D_REDRAWME     - tells the dialog manager to redraw the current
                      object
     D_WANTFOCUS    - requests that the input focus be given to this
                      object
     D_USED_CHAR    - MSG_CHAR and MSG_XCHAR return this if they used
                      the key

Dialog procedures may be called with any of the messages:

MSG_START:
Tells the object to initialise itself. The dialog manager sends this to
all the objects in a dialog just before it displays the dialog.

MSG_END:
Sent to all objects when closing a dialog, allowing them to perform
whatever cleanup operations they require.

MSG_DRAW:
Tells the object to draw itself onto the screen. The mouse pointer will
be turned off when this message is sent, so the drawing code does not
need to worry about it.

MSG_CLICK:
Informs the object that a mouse button has been clicked while the mouse
was on top of the object. Typically an object will perform its own mouse
tracking as long as the button is held down, and only return from this
message handler when it is released.

MSG_DCLICK:
Sent when the user double-clicks on an object. A MSG_CLICK will be sent
when the button is first pressed, then MSG_DCLICK if it is released and
pressed again within a short space of time.

MSG_KEY:
Sent when the keyboard shortcut for the object is pressed, or if enter,
space, or a joystick button is pressed while it has the input focus.

MSG_CHAR:
When a key is pressed, this message is sent to the object that has the
input focus, with a readkey() format character code (ASCII value in the
low byte, scancode in the high byte) as the c parameter. If the object
deals with the keypress it should return D_USED_CHAR, otherwise it
should return D_O_K to allow the default keyboard interface to operate.
If you need to access Unicode character input, you should use MSG_UCHAR
instead of MSG_CHAR.

MSG_UCHAR:
If an object ignores the MSG_CHAR input, this message will be sent
immediately after it, passed the full Unicode key value as the c
parameter. This enables you to read character codes greater than 255,
but cannot tell you anything about the scancode: if you need to know
that, use MSG_CHAR instead. This handler should return D_USED_CHAR if it
processed the input, or D_O_K otherwise.

MSG_XCHAR:
When a key is pressed, Allegro will send a MSG_CHAR and MSG_UCHAR to the
object with the input focus. If this object doesn't process the key (ie.
it returns D_O_K rather than D_USED_CHAR), the dialog manager will look
for an object with a matching keyboard shortcut in the key field, and
send it a MSG_KEY. If this fails, it broadcasts a MSG_XCHAR to all
objects in the dialog, allowing them to respond to special keypresses
even when they don't have the input focus. Normally you should ignore
this message (return D_O_K rather than D_USED_CHAR), in which case
Allegro will perform default actions such as moving the focus in
response to the arrow keys and closing the dialog if ESC is pressed.

MSG_WANTFOCUS:
Queries whether an object is willing to accept the input focus. It
should return D_WANTFOCUS if it does, or D_O_K if it isn't interested
in getting user input.

MSG_GOTFOCUS:
MSG_LOSTFOCUS:
Sent whenever an object gains or loses the input focus. These messages
will always be followed by a MSG_DRAW, to let objects display themselves
differently when they have the input focus. If you return D_WANTFOCUS in
response to a MSG_LOSTFOCUS event, this will prevent your object from
losing the focus when the mouse moves off it onto the screen background
or some inert object, so it will only lose the input focus when some
other object is ready to take over the focus (this trick is used by the
d_edit_proc() object).

MSG_GOTMOUSE:
MSG_LOSTMOUSE:
Sent when the mouse moves on top of or away from an object. Unlike the
focus messages, these are not followed by a MSG_DRAW, so if the object
is displayed differently when the mouse is on top of it, it is
responsible for redrawing itself in response to these messages.

MSG_IDLE:
Sent whenever the dialog manager has nothing better to do.

MSG_RADIO:
Sent by radio button objects to deselect other buttons in the same group
when they are clicked. The group number is passed in the c message
parameter.

MSG_WHEEL:
Sent to the focused object whenever the mouse wheel moves. The c message
parameter contains the number of clicks.

MSG_LPRESS, MSG_MPRESS, MSG_RPRESS:
Sent when the corresponding mouse button is pressed.

MSG_LRELEASE, MSG_MRELEASE, MSG_RRELEASE:
Sent when the corresponding mouse button is released.

MSG_USER:
The first free message value. Any numbers from here on (MSG_USER,
MSG_USER+1, MSG_USER+2, ... MSG_USER+n) are free to use for whatever you
like.

Allegro provides several standard dialog procedures. You can use these
as they are to provide simple user interface objects, or you can call
them from within your own dialog procedures, resulting in a kind of OOP
inheritance.  For instance, you could make an object which calls
d_button_proc to draw itself, but handles the click message in a
different way, or an object which calls d_button_proc for everything
except drawing itself, so it would behave like a normal button but
could look completely different.

Since the release of Allegro version 3.9.33 (CVS), some GUI objects and
menus are being drawn differently unlike in previous Allegro versions.
The changes are the following:

   * Shadows under d_shadow_box_proc and d_button_proc are always black.

   * The most important (and immediately visible) change is, that some
     objects are being drawn smaller. The difference is exactly one
     pixel in both height and width, when comparing to previous
     versions. The reason is, that in previous versions these objects
     were too large on the screen - their size was d->w+1 and d->h+1
     pixels (and not d->w and d->h, as it should be). This change
     affects the following objects :

          d_box_proc,
          d_shadow_box_proc,
          d_button_proc,
          d_check_proc,
          d_radio_proc,
          d_list_proc,
          d_text_list_proc and
          d_textbox_proc.

     When you want to convert old dialogs to look equally when
     compiling with the new Allegro version, just increase the size of
     the mentioned objects by one pixel in both width and height fields.

   * When a GUI menu item (not in a bar menu) has a child menu, there
     is a small arrow next to the child menu name, pointing to the
     right - so the user can immediately see that this menu item has a
     child menu - and there is no need to use such menu item names as
     for example "New...", to show that it has a child menu. The
     submenu will be drawn to the right of the parent menu, trying not
     to overlap it.

Menus had been forgotten during the changes for 3.9.33 (CVS), so they
were still drawn too large until version 4.1.0.

* Menu:

* d_clear_proc::
* d_box_proc::
* d_bitmap_proc::
* d_text_proc::
* d_button_proc::
* d_check_proc::
* d_radio_proc::
* d_icon_proc::
* d_keyboard_proc::
* d_edit_proc::
* d_list_proc::
* d_text_list_proc::
* d_textbox_proc::
* d_slider_proc::
* d_menu_proc::
* d_yield_proc::
* gui_mouse_focus::
* gui_fg_color::
* gui_mg_color::
* gui_font_baseline::
* gui_mouse_x::
* GUI font::
* gui_textout_ex::
* gui_strlen::
* position_dialog::
* centre_dialog::
* set_dialog_color::
* find_dialog_focus::
* offer_focus::
* object_message::
* dialog_message::
* broadcast_dialog_message::
* do_dialog::
* popup_dialog::
* init_dialog::
* update_dialog::
* shutdown_dialog::
* active_dialog::
* GUI menus::
* do_menu::
* init_menu::
* update_menu::
* shutdown_menu::
* active_menu::
* gui_menu_draw_menu::
* alert::
* alert3::
* file_select_ex::
* gfx_mode_select::
* gfx_mode_select_ex::
* gfx_mode_select_filter::
* gui_shadow_box_proc::


File: allegro.info,  Node: d_clear_proc,  Next: d_box_proc,  Prev: quat_slerp,  Up: GUI

34.1 d_clear_proc
=================

int d_clear_proc(int msg, DIALOG *d, int c);
     This just clears the screen when it is drawn. Useful as the first
     object in a dialog.

See also:
*Note excustom::.
*Note exgui::.
*Note DIALOG::.

File: allegro.info,  Node: d_box_proc,  Next: d_bitmap_proc,  Prev: d_clear_proc,  Up: GUI

34.2 d_box_proc
===============

int d_box_proc(int msg, DIALOG *d, int c);

int d_shadow_box_proc(int msg, DIALOG *d, int c);
     These draw boxes onto the screen, with or without a shadow.

See also:
*Note exgui::.
*Note exrgbhsv::.
*Note DIALOG::.

File: allegro.info,  Node: d_bitmap_proc,  Next: d_text_proc,  Prev: d_box_proc,  Up: GUI

34.3 d_bitmap_proc
==================

int d_bitmap_proc(int msg, DIALOG *d, int c);
     This draws a bitmap onto the screen, which should be pointed to by
     the dp field.

See also:
*Note exgui::.
*Note exrgbhsv::.
*Note DIALOG::.

File: allegro.info,  Node: d_text_proc,  Next: d_button_proc,  Prev: d_bitmap_proc,  Up: GUI

34.4 d_text_proc
================

int d_text_proc(int msg, DIALOG *d, int c);

int d_ctext_proc(int msg, DIALOG *d, int c);

int d_rtext_proc(int msg, DIALOG *d, int c);
     These draw text onto the screen. The dp field should point to the
     string to display. d_ctext_proc() centers the string horizontally,
     and d_rtext_proc() right aligns it. Any '&' characters in the
     string will be replaced with lines underneath the following
     character, for displaying keyboard shortcuts (as in MS Windows).
     To display a single ampersand, put "&&". To draw the text in
     something other than the default font, set the dp2 field to point
     to your custom font data.

See also:
*Note exgui::.
*Note exrgbhsv::.
*Note DIALOG::.

File: allegro.info,  Node: d_button_proc,  Next: d_check_proc,  Prev: d_text_proc,  Up: GUI

34.5 d_button_proc
==================

int d_button_proc(int msg, DIALOG *d, int c);
     A button object (the dp field points to the text string). This
     object can be selected by clicking on it with the mouse or by
     pressing its keyboard shortcut. If the D_EXIT flag is set,
     selecting it will close the dialog, otherwise it will toggle on
     and off. Like d_text_proc(), ampersands can be used to display the
     keyboard shortcut of the button.

See also:
*Note excustom::.
*Note exgui::.
*Note DIALOG::.

File: allegro.info,  Node: d_check_proc,  Next: d_radio_proc,  Prev: d_button_proc,  Up: GUI

34.6 d_check_proc
=================

int d_check_proc(int msg, DIALOG *d, int c);
     This is an example of how you can derive objects from other
     objects. Most of the functionality comes from d_button_proc(), but
     it displays itself as a check box. If the d1 field is non-zero,
     the text will be printed to the right of the check, otherwise it
     will be on the left.

     Note: the object width should allow space for the text as well as
     the check box (which is square, with sides equal to the object
     height).

See also:
*Note excustom::.
*Note exgui::.
*Note DIALOG::.

File: allegro.info,  Node: d_radio_proc,  Next: d_icon_proc,  Prev: d_check_proc,  Up: GUI

34.7 d_radio_proc
=================

int d_radio_proc(int msg, DIALOG *d, int c);
     A radio button object. A dialog can contain any number of radio
     button groups: selecting a radio button causes other buttons
     within the same group to be deselected. The dp field points to the
     text string, d1 specifies the group number, and d2 is the button
     style (0=circle, 1=square).

See also:
*Note exgui::.
*Note DIALOG::.

File: allegro.info,  Node: d_icon_proc,  Next: d_keyboard_proc,  Prev: d_radio_proc,  Up: GUI

34.8 d_icon_proc
================

int d_icon_proc(int msg, DIALOG *d, int c);
     A bitmap button. The fg color is used for the dotted line showing
     focus, and the bg color for the shadow used to fill in the top and
     left sides of the button when "pressed". d1 is the "push depth",
     ie. the number of pixels the icon will be shifted to the right and
     down when selected (default 2) if there is no "selected" image. d2
     is the distance by which the dotted line showing focus is indented
     (default 2). dp points to a bitmap for the icon, while dp2 and dp3
     are the selected and disabled images respectively (optional, may
     be NULL).

See also:
*Note exgui::.
*Note DIALOG::.

File: allegro.info,  Node: d_keyboard_proc,  Next: d_edit_proc,  Prev: d_icon_proc,  Up: GUI

34.9 d_keyboard_proc
====================

int d_keyboard_proc(int msg, DIALOG *d, int c);
     This is an invisible object for implementing keyboard shortcuts.
     You can put an ASCII code in the key field of the dialog object (a
     character such as 'a' to respond to a simple keypress, or a number
     1-26 to respond to a control key a-z), or you can put a keyboard
     scancode in the d1 and/or d2 fields. When one of these keys is
     pressed, the object will call the function pointed to by dp. This
     should return an int, which will be passed back to the dialog
     manager, so it can return D_O_K, D_REDRAW, D_CLOSE, etc.

See also:
*Note exgui::.
*Note DIALOG::.

File: allegro.info,  Node: d_edit_proc,  Next: d_list_proc,  Prev: d_keyboard_proc,  Up: GUI

34.10 d_edit_proc
=================

int d_edit_proc(int msg, DIALOG *d, int c);
     An editable text object (the dp field points to the string). When
     it has the input focus (obtained by clicking on it with the
     mouse), text can be typed into this object. The d1 field specifies
     the maximum number of characters that it will accept, and d2 is
     the text cursor position within the string.

     Note: dp must point to a buffer at least (d1 + 1) * 6 bytes long
     because, depending on the encoding format in use, a single
     character can occupy up to 6 bytes and room must be reserved for
     the terminating null character.

See also:
*Note excustom::.
*Note exgui::.
*Note DIALOG::.

File: allegro.info,  Node: d_list_proc,  Next: d_text_list_proc,  Prev: d_edit_proc,  Up: GUI

34.11 d_list_proc
=================

int d_list_proc(int msg, DIALOG *d, int c);
     A list box object. This will allow the user to scroll through a
     list of items and to select one by clicking or with the arrow
     keys. If the D_EXIT flag is set, double clicking on a list item
     will close the dialog. The index of the selected item is held in
     the d1 field, and d2 is used to store how far it has scrolled
     through the list. The dp field points to a function which will be
     called to obtain information about the contents of the list. This
     should follow the form:

          char *foobar(int index, int *list_size);

     If index is zero or positive, the function should return a pointer
     to the string which is to be displayed at position index in the
     list. If index is negative, it should return NULL and list_size
     should be set to the number of items in the list.

     To create a multiple selection listbox, set the dp2 field to an
     array of byte flags indicating the selection state of each list
     item (non-zero for selected entries). This table must be at least
     as big as the number of objects in the list!

See also:
*Note exgui::.
*Note DIALOG::.

File: allegro.info,  Node: d_text_list_proc,  Next: d_textbox_proc,  Prev: d_list_proc,  Up: GUI

34.12 d_text_list_proc
======================

int d_text_list_proc(int msg, DIALOG *d, int c);
     Like d_list_proc, but allows the user to type in the first few
     characters of a listbox entry in order to select it. Uses dp3
     internally, so you mustn't store anything important there yourself.

See also:
*Note exgui::.
*Note DIALOG::.

File: allegro.info,  Node: d_textbox_proc,  Next: d_slider_proc,  Prev: d_text_list_proc,  Up: GUI

34.13 d_textbox_proc
====================

int d_textbox_proc(int msg, DIALOG *d, int c);
     A text box object. The dp field points to the text which is to be
     displayed in the box. If the text is long, there will be a vertical
     scrollbar on the right hand side of the object which can be used to
     scroll through the text. The default is to print the text with word
     wrapping, but if the D_SELECTED flag is set, the text will be
     printed with character wrapping. The d1 field is used internally
     to store the number of lines of text, and d2 is used to store how
     far it has scrolled through the text.

See also:
*Note exgui::.
*Note DIALOG::.

File: allegro.info,  Node: d_slider_proc,  Next: d_menu_proc,  Prev: d_textbox_proc,  Up: GUI

34.14 d_slider_proc
===================

int d_slider_proc(int msg, DIALOG *d, int c);
     A slider control object. This object holds a value in d2, in the
     range from 0 to d1. It will display as a vertical slider if h is
     greater than or equal to w, otherwise it will display as a
     horizontal slider. The dp field can contain an optional bitmap to
     use for the slider handle, and dp2 can contain an optional
     callback function, which is called each time d2 changes. The
     callback function should have the following prototype:

          int function(void *dp3, int d2);

     The d_slider_proc object will return the value of the callback
     function.

See also:
*Note exgui::.
*Note exrgbhsv::.
*Note DIALOG::.

File: allegro.info,  Node: d_menu_proc,  Next: d_yield_proc,  Prev: d_slider_proc,  Up: GUI

34.15 d_menu_proc
=================

int d_menu_proc(int msg, DIALOG *d, int c);
     This object is a menu bar which will drop down child menus when it
     is clicked or if an alt+key corresponding to one of the shortcuts
     in the menu is pressed. It ignores a lot of the fields in the
     dialog structure, in particular the color is taken from the
     gui_*_color variables, and the width and height are calculated
     automatically (the w and h fields from the DIALOG are only used as
     a minimum size.) The dp field points to an array of menu
     structures: see do_menu() for more information. The top level menu
     will be displayed as a horizontal bar, but when child menus drop
     down from it they will be in the normal vertical format used by
     do_menu(). When a menu item is selected, the return value from the
     menu callback function is passed back to the dialog manager, so
     your callbacks should return D_O_K, D_REDRAW, or D_CLOSE.

See also:
*Note GUI menus::.
*Note active_menu::.
*Note gui_menu_draw_menu::.
*Note exgui::.
*Note DIALOG::.

File: allegro.info,  Node: d_yield_proc,  Next: gui_mouse_focus,  Prev: d_menu_proc,  Up: GUI

34.16 d_yield_proc
==================

int d_yield_proc(int msg, DIALOG *d, int c);
     An invisible helper object that yields timeslices for the
     scheduler (if the system supports it) when the gui has nothing to
     do but waiting for user actions. You should put one instance of
     this object in each dialog array because it may be needed on
     systems with an unusual scheduling algorithm (for instance QNX) in
     order to make the GUI fully responsive.

See also:
*Note exgui::.
*Note DIALOG::.

File: allegro.info,  Node: gui_mouse_focus,  Next: gui_fg_color,  Prev: d_yield_proc,  Up: GUI

34.17 gui_mouse_focus
=====================

extern int gui_mouse_focus;
     If set, the input focus follows the mouse pointer around the
     dialog, otherwise a click is required to move it.



File: allegro.info,  Node: gui_fg_color,  Next: gui_mg_color,  Prev: gui_mouse_focus,  Up: GUI

34.18 gui_fg_color
==================

extern int gui_fg_color;

extern int gui_bg_color;
     The foreground and background colors for the standard dialogs
     (alerts, menus, and the file selector). They default to 255 and 0.

See also:
*Note gui_mg_color::.
*Note set_dialog_color::.
*Note exgui::.

File: allegro.info,  Node: gui_mg_color,  Next: gui_font_baseline,  Prev: gui_fg_color,  Up: GUI

34.19 gui_mg_color
==================

extern int gui_mg_color;
     The color used for displaying greyed-out dialog objects (with the
     D_DISABLED flag set). Defaults to 8.

See also:
*Note gui_fg_color::.
*Note set_dialog_color::.
*Note exgui::.

File: allegro.info,  Node: gui_font_baseline,  Next: gui_mouse_x,  Prev: gui_mg_color,  Up: GUI

34.20 gui_font_baseline
=======================

extern int gui_font_baseline;
     If set to a non-zero value, adjusts the keyboard shortcut
     underscores to account for the height of the descenders in your
     font.



File: allegro.info,  Node: gui_mouse_x,  Next: GUI font,  Prev: gui_font_baseline,  Up: GUI

34.21 gui_mouse_x
=================

extern int (*gui_mouse_x)();

extern int (*gui_mouse_y)();

extern int (*gui_mouse_z)();

extern int (*gui_mouse_b)();
     Hook functions, used by the GUI routines whenever they need to
     access the mouse state. By default these just return copies of the
     mouse_x, mouse_y, mouse_z, and mouse_b variables, but they could
     be used to offset or scale the mouse position, or read input from
     a different source entirely.



File: allegro.info,  Node: GUI font,  Next: gui_textout_ex,  Prev: gui_mouse_x,  Up: GUI

34.22 GUI font
==============

You can change the global 'font' pointer to make the GUI objects use
something other than the standard 8x8 font. The standard dialog
procedures, menus, and alert boxes, will work with fonts of any size,
but the gfx_mode_select() dialog will look wrong with anything other
than 8x8 fonts.


File: allegro.info,  Node: gui_textout_ex,  Next: gui_strlen,  Prev: GUI font,  Up: GUI

34.23 gui_textout_ex
====================

int gui_textout_ex(BITMAP *bmp, const char *s, int x, y, color, bg, centre);
     Helper function for use by the GUI routines. Draws a text string
     onto the screen, interpreting the '&' character as an underbar for
     displaying keyboard shortcuts. Returns the width of the output
     string in pixels.

See also:
*Note gui_strlen::.
*Note BITMAP::.

File: allegro.info,  Node: gui_strlen,  Next: position_dialog,  Prev: gui_textout_ex,  Up: GUI

34.24 gui_strlen
================

int gui_strlen(const char *s);
     Helper function for use by the GUI routines. Returns the length of
     a string in pixels, ignoring '&' characters.

See also:
*Note gui_textout_ex::.

File: allegro.info,  Node: position_dialog,  Next: centre_dialog,  Prev: gui_strlen,  Up: GUI

34.25 position_dialog
=====================

void position_dialog(DIALOG *dialog, int x, int y);
     Moves an array of dialog objects to the specified screen position
     (specified as the top left corner of the dialog).

See also:
*Note centre_dialog::.
*Note exgui::.
*Note DIALOG::.

File: allegro.info,  Node: centre_dialog,  Next: set_dialog_color,  Prev: position_dialog,  Up: GUI

34.26 centre_dialog
===================

void centre_dialog(DIALOG *dialog);
     Moves an array of dialog objects so that it is centered in the
     screen.

See also:
*Note position_dialog::.
*Note set_dialog_color::.
*Note DIALOG::.

File: allegro.info,  Node: set_dialog_color,  Next: find_dialog_focus,  Prev: centre_dialog,  Up: GUI

34.27 set_dialog_color
======================

void set_dialog_color(DIALOG *dialog, int fg, int bg);
     Sets the foreground and background colors of an array of dialog
     objects.

See also:
*Note gui_fg_color::.
*Note gui_mg_color::.
*Note centre_dialog::.
*Note exgui::.
*Note DIALOG::.

File: allegro.info,  Node: find_dialog_focus,  Next: offer_focus,  Prev: set_dialog_color,  Up: GUI

34.28 find_dialog_focus
=======================

int find_dialog_focus(DIALOG *dialog);
     Searches the dialog for the object which has the input focus,
     returning an index or -1 if the focus is not set. This is useful
     if you are calling do_dialog() several times in a row and want to
     leave the focus in the same place it was when the dialog was last
     displayed, as you can call do_dialog(dlg, find_dialog_focus(dlg));

See also:
*Note do_dialog::.
*Note init_dialog::.
*Note offer_focus::.
*Note DIALOG::.

File: allegro.info,  Node: offer_focus,  Next: object_message,  Prev: find_dialog_focus,  Up: GUI

34.29 offer_focus
=================

int offer_focus(DIALOG *dialog, int obj, int *focus_obj, int force);
     Offers the input focus to a particular object. Normally the
     function sends the MSG_WANTFOCUS message to query whether the
     object is willing to accept the focus. However, passing any non
     zero value as force argument instructs the function to
     authoritatively set the focus to the object.

See also:
*Note find_dialog_focus::.
*Note DIALOG::.

File: allegro.info,  Node: object_message,  Next: dialog_message,  Prev: offer_focus,  Up: GUI

34.30 object_message
====================

int object_message(DIALOG *dialog, int msg, int c);
     Sends a message to an object and returns the answer it has
     generated.  Remember that the first parameter is the dialog object
     (not a whole array) that you wish to send the message to. For
     example, to make the second object in a dialog draw itself, you
     might write:

          object_message(&dialog[1], MSG_DRAW, 0);

     The function will take care of scaring and unscaring the mouse if
     the message is MSG_DRAW.
See also:
*Note dialog_message::.
*Note scare_mouse::.
*Note scare_mouse_area::.
*Note unscare_mouse::.
*Note excustom::.
*Note exrgbhsv::.
*Note DIALOG::.

File: allegro.info,  Node: dialog_message,  Next: broadcast_dialog_message,  Prev: object_message,  Up: GUI

34.31 dialog_message
====================

int dialog_message(DIALOG *dialog, int msg, int c, int *obj);
     Sends a message to all the objects in an array. If any of the
     dialog procedures return values other than D_O_K, it returns the
     value and sets obj to the index of the object which produced it.

See also:
*Note object_message::.
*Note broadcast_dialog_message::.
*Note DIALOG::.

File: allegro.info,  Node: broadcast_dialog_message,  Next: do_dialog,  Prev: dialog_message,  Up: GUI

34.32 broadcast_dialog_message
==============================

int broadcast_dialog_message(int msg, int c);
     Broadcasts a message to all the objects in the active dialog. If
     any of the dialog procedures return values other than D_O_K, it
     returns that value.

See also:
*Note dialog_message::.
*Note active_dialog::.

File: allegro.info,  Node: do_dialog,  Next: popup_dialog,  Prev: broadcast_dialog_message,  Up: GUI

34.33 do_dialog
===============

int do_dialog(DIALOG *dialog, int focus_obj);
     The basic dialog manager function. This displays a dialog (an
     array of dialog objects, terminated by one with a NULL dialog
     procedure), and sets the input focus to the focus_obj (-1 if you
     don't want anything to have the focus). It interprets user input
     and dispatches messages as they are required, until one of the
     dialog procedures tells it to close the dialog, at which point it
     returns the index of the object that caused it to exit, or until
     ESC is pressed, at which point it returns -1.

See also:
*Note popup_dialog::.
*Note init_dialog::.
*Note centre_dialog::.
*Note set_dialog_color::.
*Note find_dialog_focus::.
*Note excustom::.
*Note exgui::.
*Note exrgbhsv::.
*Note DIALOG::.

File: allegro.info,  Node: popup_dialog,  Next: init_dialog,  Prev: do_dialog,  Up: GUI

34.34 popup_dialog
==================

int popup_dialog(DIALOG *dialog, int focus_obj);
     Like do_dialog(), but it stores the data on the screen before
     drawing the dialog and restores it when the dialog is closed. The
     screen area to be stored is calculated from the dimensions of the
     first object in the dialog, so all the other objects should lie
     within this one.

See also:
*Note do_dialog::.
*Note DIALOG::.

File: allegro.info,  Node: init_dialog,  Next: update_dialog,  Prev: popup_dialog,  Up: GUI

34.35 init_dialog
=================

DIALOG_PLAYER *init_dialog(DIALOG *dialog, int focus_obj);
     This function provides lower level access to the same
     functionality as do_dialog(), but allows you to combine a dialog
     box with your own program control structures. It initialises a
     dialog, returning a pointer to a player object that can be used
     with update_dialog() and shutdown_dialog(). With these functions,
     you could implement your own version of do_dialog() with the lines:

          DIALOG_PLAYER *player = init_dialog(dialog, focus_obj);

          while (update_dialog(player))
             ;

          return shutdown_dialog(player);

See also:
*Note update_dialog::.
*Note shutdown_dialog::.
*Note do_dialog::.
*Note DIALOG::.
*Note DIALOG_PLAYER::.

File: allegro.info,  Node: update_dialog,  Next: shutdown_dialog,  Prev: init_dialog,  Up: GUI

34.36 update_dialog
===================

int update_dialog(DIALOG_PLAYER *player);
     Updates the status of a dialog object returned by init_dialog().
     Returns TRUE if the dialog is still active, or FALSE if it has
     terminated. Upon a return value of FALSE, it is up to you whether
     to call shutdown_dialog() or to continue execution. The object
     that requested the exit can be determined from the player->obj
     field.

See also:
*Note init_dialog::.
*Note DIALOG_PLAYER::.

File: allegro.info,  Node: shutdown_dialog,  Next: active_dialog,  Prev: update_dialog,  Up: GUI

34.37 shutdown_dialog
=====================

int shutdown_dialog(DIALOG_PLAYER *player);
     Destroys a dialog player object returned by init_dialog(),
     returning the object that caused it to exit (this is the same as
     the return value from do_dialog()).

See also:
*Note init_dialog::.
*Note DIALOG_PLAYER::.

File: allegro.info,  Node: active_dialog,  Next: GUI menus,  Prev: shutdown_dialog,  Up: GUI

34.38 active_dialog
===================

extern DIALOG *active_dialog;
     Global pointer to the most recent activated dialog. This may be
     useful if an object needs to iterate through a list of all its
     siblings.

See also:
*Note do_dialog::.
*Note init_dialog::.
*Note broadcast_dialog_message::.
*Note DIALOG::.

File: allegro.info,  Node: GUI menus,  Next: do_menu,  Prev: active_dialog,  Up: GUI

34.39 GUI menus
===============

Popup or pulldown menus are created as an array of MENU structures. Read
chapter "Structures and types defined by Allegro" for an internal
description of the MENU structure.

Each menu item contains a text string. This can use the '&' character to
indicate keyboard shortcuts, or can be an zero-length string to display
the item as a non-selectable splitter bar. If the string contains a
"\t" tab character, any text after this will be right-justified, eg.
for displaying keyboard shortcut information. The proc pointer is a
function which will be called when the menu item is selected, and child
points to another menu, allowing you to create nested menus. Both proc
and child may be NULL. The proc function returns an integer which is
ignored if the menu was brought up by calling do_menu(), but which is
passed back to the dialog manager if it was created by a d_menu_proc()
object. The array of menu items is terminated by an entry with a NULL
text pointer.

Menu items can be disabled (greyed-out) by setting the D_DISABLED bit
in the flags field, and a check mark can be displayed next to them by
setting the D_SELECTED bit. With the default alignment and font this
will usually overlap the menu text, so if you are going to use checked
menu items it would be a good idea to prefix all your options with a
space or two, to ensure there is room for the check.

See also:
*Note do_menu::.
*Note d_menu_proc::.
*Note gui_menu_draw_menu::.

File: allegro.info,  Node: do_menu,  Next: init_menu,  Prev: GUI menus,  Up: GUI

34.40 do_menu
=============

int do_menu(MENU *menu, int x, int y);
     Displays and animates a popup menu at the specified screen
     coordinates (these will be adjusted if the menu does not entirely
     fit on the screen).  Returns the index of the menu item that was
     selected, or -1 if the menu was cancelled. Note that the return
     value cannot indicate selection from child menus, so you will have
     to use the callback functions if you want multi-level menus.

See also:
*Note GUI menus::.
*Note d_menu_proc::.
*Note active_menu::.
*Note gui_menu_draw_menu::.
*Note MENU::.

File: allegro.info,  Node: init_menu,  Next: update_menu,  Prev: do_menu,  Up: GUI

34.41 init_menu
===============

MENU_PLAYER *init_menu(MENU *menu, int x, int y);
     This function provides lower level access to the same
     functionality as do_menu(), but allows you to combine a popup menu
     with your own program control structures. It initialises a menu,
     returning a pointer to a menu player object that can be used with
     update_menu() and shutdown_menu().  With these functions, you
     could implement your own version of do_menu() with the lines:

          MENU_PLAYER *player = init_menu(menu, x, y);

          while (update_menu(player))
             ;

          return shutdown_menu(player);

See also:
*Note update_menu::.
*Note shutdown_menu::.
*Note do_menu::.
*Note MENU::.
*Note MENU_PLAYER::.

File: allegro.info,  Node: update_menu,  Next: shutdown_menu,  Prev: init_menu,  Up: GUI

34.42 update_menu
=================

int update_menu(MENU_PLAYER *player);
     Updates the status of a menu object returned by init_menu().
     Returns TRUE if the menu is still active, or FALSE if it has
     terminated. Upon a return value of FALSE, it is up to you to call
     shutdown_menu() or to continue execution.

See also:
*Note init_menu::.
*Note shutdown_menu::.
*Note MENU_PLAYER::.

File: allegro.info,  Node: shutdown_menu,  Next: active_menu,  Prev: update_menu,  Up: GUI

34.43 shutdown_menu
===================

int shutdown_menu(MENU_PLAYER *player);
     Destroys a menu player object returned by init_menu(), returning
     the index of the menu item that was selected, or -1 if the menu
     was cancelled (this is the same as the return value from
     do_menu()).

See also:
*Note init_menu::.
*Note update_menu::.
*Note MENU_PLAYER::.

File: allegro.info,  Node: active_menu,  Next: gui_menu_draw_menu,  Prev: shutdown_menu,  Up: GUI

34.44 active_menu
=================

extern MENU *active_menu;
     When a menu callback procedure is triggered, this will be set to
     the menu item that was selected, so your routine can determine
     where it was called from.

See also:
*Note GUI menus::.
*Note exgui::.
*Note MENU::.

File: allegro.info,  Node: gui_menu_draw_menu,  Next: alert,  Prev: active_menu,  Up: GUI

34.45 gui_menu_draw_menu
========================

extern void (*gui_menu_draw_menu)(int x, int y, int w, int h);

extern void (*gui_menu_draw_menu_item)(MENU *m, int x, int y, int w, int h, int bar, int sel);
     If set, these functions will be called whenever a menu needs to be
     drawn, so you can change how menus look.

     gui_menu_draw_menu() is passed the position and size of the menu.
     It should draw the background of the menu onto screen.

     gui_menu_draw_menu_item() is called once for each menu item that is
     to be drawn. bar will be set if the item is part of a top-level
     horizontal menu bar, and sel will be set if the menu item is
     selected. It should also draw onto screen.

See also:
*Note GUI menus::.
*Note MENU::.

File: allegro.info,  Node: alert,  Next: alert3,  Prev: gui_menu_draw_menu,  Up: GUI

34.46 alert
===========

int alert(const char *s1, *s2, *s3, const char *b1, *b2, int c1, c2);
     Displays a popup alert box, containing three lines of text
     (s1-s3), and with either one or two buttons. The text for these
     buttons is passed in b1 and b2 (b2 may be NULL), and the keyboard
     shortcuts in c1 and c2.  Returns 1 or 2 depending on which button
     was clicked. If the alert is dismissed by pressing ESC when ESC is
     not one of the keyboard shortcuts, it treats it as a click on the
     second button (this is consistent with the common "Ok", "Cancel"
     alert).

See also:
*Note alert3::.
*Note gui_fg_color::.
*Note ex3buf::.
*Note exgui::.
*Note exspline::.

File: allegro.info,  Node: alert3,  Next: file_select_ex,  Prev: alert,  Up: GUI

34.47 alert3
============

int alert3(const char *s1, *s2, *s3, const char *b1, *b2, *b3, int c1, c2, c3);
     Like alert(), but with three buttons. Returns 1, 2, or 3.

See also:
*Note alert::.
*Note gui_fg_color::.

File: allegro.info,  Node: file_select_ex,  Next: gfx_mode_select,  Prev: alert3,  Up: GUI

34.48 file_select_ex
====================

int file_select_ex(const char *message, char *path, const char *ext, int size, int w, int h);
     Displays the Allegro file selector, with the message as caption.
     The path parameter contains the initial filename to display (this
     can be used to set the starting directory, or to provide a default
     filename for a save-as operation). The user selection is returned
     by altering the path buffer, whose maximum capacity in bytes is
     specified by the size parameter.  Note that it should have room
     for at least 80 characters (not bytes), so you should reserve 6x
     that amount, just to be sure. The list of files is filtered
     according to the file extensions in the ext parameter.  Passing
     NULL includes all files; "PCX;BMP" includes only files with .PCX
     or .BMP extensions. If you wish to control files by their
     attributes, one of the fields in the extension list can begin with
     a slash, followed by a set of attribute characters. Any attribute
     written on its own, or with a '+' before it, indicates to include
     only files which have that attribute set. Any attribute with a '-'
     before it indicates to leave out any files with that attribute.
     The flag characters are 'r' (read-only), 'h' (hidden), 's'
     (system), 'd' (directory) and 'a' (archive). For example, an
     extension string of "PCX;BMP;/+r-h" will display only PCX or BMP
     files that are read-only and not hidden. The directories are not
     affected in the same way as the other files by the extension
     string: the extensions are never taken into account for them and
     the other attributes are taken into account only when 'd' is
     mentioned in the string; in other words, all directories are
     included when 'd' is not mentioned in the string. The file
     selector is stretched to the width and height specified in the w
     and h parameters, and to the size of the standard Allegro font.
     If either the width or height argument is set to zero, it is
     stretched to the corresponding screen dimension. This function
     returns zero if it was closed with the Cancel button or non-zero
     if it was OK'd.

See also:
*Note gui_fg_color::.

File: allegro.info,  Node: gfx_mode_select,  Next: gfx_mode_select_ex,  Prev: file_select_ex,  Up: GUI

34.49 gfx_mode_select
=====================

int gfx_mode_select(int *card, int *w, int *h);
     Displays the Allegro graphics mode selection dialog, which allows
     the user to select a screen mode and graphics card. Stores the
     selection in the three variables, and returns zero if it was
     closed with the Cancel button or non-zero if it was OK'd.

See also:
*Note gfx_mode_select_ex::.
*Note gfx_mode_select_filter::.
*Note set_gfx_mode::.
*Note gui_fg_color::.

File: allegro.info,  Node: gfx_mode_select_ex,  Next: gfx_mode_select_filter,  Prev: gfx_mode_select,  Up: GUI

34.50 gfx_mode_select_ex
========================

int gfx_mode_select_ex(int *card, int *w, int *h, int *color_depth);
     Extended version of the graphics mode selection dialog, which
     allows the user to select the color depth as well as the
     resolution and hardware driver. This version of the function reads
     the initial values from the parameters when it activates, so you
     can specify the default values.

See also:
*Note gfx_mode_select::.
*Note gfx_mode_select_filter::.
*Note set_color_depth::.
*Note set_gfx_mode::.
*Note gui_fg_color::.
*Note ex3d::.
*Note exscn3d::.
*Note exswitch::.
*Note exupdate::.
*Note exzbuf::.

File: allegro.info,  Node: gfx_mode_select_filter,  Next: gui_shadow_box_proc,  Prev: gfx_mode_select_ex,  Up: GUI

34.51 gfx_mode_select_filter
============================

int gfx_mode_select_filter(int *card, int *w, int *h, int *color_depth, int (*filter)(int, int, int, int));
     Even more extended version of the graphics mode selection dialog,
     which allows the programmer to customize the contents of the
     dialog and the user to select the color depth as well as the
     resolution and hardware driver.  `filter' will be passed (card, w,
     h, color_depth) quadruplets and must return 0 to let the specified
     quadruplet be added to the list of displayed modes. This version
     of the function reads the initial values from the parameters when
     it activates, so you can specify the default values.

See also:
*Note gfx_mode_select::.
*Note gfx_mode_select_ex::.
*Note set_color_depth::.
*Note set_gfx_mode::.
*Note gui_fg_color::.

File: allegro.info,  Node: gui_shadow_box_proc,  Next: JOY_TYPE_*/DOS,  Prev: gfx_mode_select_filter,  Up: GUI

34.52 gui_shadow_box_proc
=========================

extern int (*gui_shadow_box_proc)(int msg, struct DIALOG *d, int c);

extern int (*gui_ctext_proc)(int msg, struct DIALOG *d, int c);

extern int (*gui_button_proc)(int msg, struct DIALOG *d, int c);

extern int (*gui_edit_proc)(int msg, struct DIALOG *d, int c);

extern int (*gui_list_proc)(int msg, struct DIALOG *d, int c);

extern int (*gui_text_list_proc)(int msg, struct DIALOG *d, int c);
     If set, these functions will be used by the standard Allegro
     dialogs.  This allows you to customise the look and feel, much
     like gui_fg_color and gui_bg_color, but much more flexibly.

See also:
*Note alert::.
*Note alert3::.
*Note file_select_ex::.
*Note gfx_mode_select::.
*Note gui_fg_color::.
*Note DIALOG::.

File: allegro.info,  Node: DOS,  Next: Windows,  Prev: GUI,  Up: Top

35 DOS specifics
****************

* Menu:

* JOY_TYPE_*/DOS::
* GFX_*/DOS::
* DIGI_*/DOS::
* MIDI_*/DOS::
* split_modex_screen::
* i_love_bill::


File: allegro.info,  Node: JOY_TYPE_*/DOS,  Next: GFX_*/DOS,  Prev: gui_shadow_box_proc,  Up: DOS

35.1 JOY_TYPE_*/DOS
===================

Drivers JOY_TYPE_*/DOS
     The DOS library supports the following type parameters for the
     install_joystick() function:

        * JOY_TYPE_AUTODETECT
          Attempts to autodetect your joystick hardware. It isn't
          possible to reliably distinguish between all the possible
          input setups, so this routine can only ever choose the
          standard joystick, Sidewider, GamePad Pro, or GrIP drivers,
          but it will use information from the configuration file if
          one is available (this can be created using the setup utility
          or by calling the save_joystick_data() function), so you can
          always use JOY_TYPE_AUTODETECT in your code and then select
          the exact hardware type from the setup program.

        * JOY_TYPE_NONE
          Dummy driver for machines without any joystick.

        * JOY_TYPE_STANDARD
          A normal two button stick.

        * JOY_TYPE_2PADS
          Dual joystick mode (two sticks, each with two buttons).

        * JOY_TYPE_4BUTTON
          Enable the extra buttons on a 4-button joystick.

        * JOY_TYPE_6BUTTON
          Enable the extra buttons on a 6-button joystick.

        * JOY_TYPE_8BUTTON
          Enable the extra buttons on an 8-button joystick.

        * JOY_TYPE_FSPRO
          CH Flightstick Pro or compatible stick, which provides four
          buttons, an analogue throttle control, and a 4-direction
          coolie hat.

        * JOY_TYPE_WINGEX
          A Logitech Wingman Extreme, which should also work with any
          Thrustmaster Mk.I compatible joystick. It provides support
          for four buttons and a coolie hat. This also works with the
          Wingman Warrior, if you plug in the 15 pin plug (remember to
          unplug the 9-pin plug!) and set the tiny switch in front to
          the "H" position (you will not be able to use the throttle or
          the spinner though).

        * JOY_TYPE_SIDEWINDER
          The Microsoft Sidewinder digital pad (supports up to four
          controllers, each with ten buttons and a digital direction
          control).

        * JOY_TYPE_SIDEWINDER_AG
          An alternative driver to JOY_TYPE_SIDEWINDER.  Try this if
          your Sidewinder isn't recognized with JOY_TYPE_SIDEWINDER.

        * JOY_TYPE_SIDEWINDER_PP
          The Microsoft Sidewinder 3D/Precision/Force Feedback Pro
          joysticks.

        * JOY_TYPE_GAMEPAD_PRO
          The Gravis GamePad Pro (supports up to two controllers, each
          with ten buttons and a digital direction control).

        * JOY_TYPE_GRIP
          Gravis GrIP driver, using the grip.gll driver file.

        * JOY_TYPE_GRIP4
          Version of the Gravis GrIP driver that is constrained to only
          move along the four main axis.

        * JOY_TYPE_SNESPAD_LPT1
          JOY_TYPE_SNESPAD_LPT2
          JOY_TYPE_SNESPAD_LPT3
          SNES joypads connected to LPT1, LPT2, and LPT3 respectively.

        * JOY_TYPE_PSXPAD_LPT1
          JOY_TYPE_PSXPAD_LPT2
          JOY_TYPE_PSXPAD_LPT3
          PSX joypads connected to LPT1, LPT2, and LPT3 respectively.
          See http://www.ziplabel.com/dpadpro/index.html for information
          about the parallel cable required. The driver automagically
          detects which types of PSX pads are connected out of digital,
          analog (red or green mode), NegCon, multi taps, Namco light
          guns, Jogcons (force feedback steering wheel) and the mouse.
          If the controller isn't recognised it is treated as an analog
          controller, meaning the driver should work with just about
          anything. You can connect controllers in any way you see fit,
          but only the first 8 will be used.

          The Sony Dual Shock or Namco Jogcon will reset themselves (to
          digital mode) after not being polled for 5 seconds. This is
          normal, the same thing happens on a Playstation, it's
          designed to stop any vibration in case the host machine
          crashes. Other mode switching controllers may have similar
          quirks. However, if this happens to a Jogcon controller the
          mode button is disabled. To reenable the mode button on the
          Jogcon you need to hold down the Start and Select buttons at
          the same time.

          The G-con45 needs to be connected to (and pointed at) a TV
          type monitor connected to your computer. The composite video
          out on my video card works fine for this (a Hercules Stingray
          128/3D 8Mb). The TV video modes in Mame should work too.

        * JOY_TYPE_N64PAD_LPT1
          JOY_TYPE_N64PAD_LPT2
          JOY_TYPE_N64PAD_LPT3
          N64 joypads connected to LPT1, LPT2, and LPT3 respectively.
          See http://www.st-hans.de/N64.htm for information about the
          necessary hardware adaptor. It supports up to four
          controllers on a single parallel port. There is no need to
          calibrate the analog stick, as this is done by the controller
          itself when powered up. This means that the stick has to be
          centred when the controller is initialised.  One possible
          issue people may have with this driver is that it is
          physically impossible to move the analog stick fully
          diagonal, but I can't see this causing any major problems.
          This is because of the shape of the rim that the analog stick
          rests against. Like the Gravis Game Pad Pro, this driver
          briefly needs to disable hardware interrupts while polling.
          This causes a noticable performance hit on my machine in both
          drivers, but there is no way around it. At a (very) rough
          guess I'd say it slows down Mame 5% - 10%.

        * JOY_TYPE_DB9_LPT1
          JOY_TYPE_DB9_LPT2
          JOY_TYPE_DB9_LPT3
          A pair of two-button joysticks connected to LPT1, LPT2, and
          LPT3 respectively. Port 1 is compatible with Linux joy-db9
          driver (multisystem 2-button), and port 2 is compatible with
          Atari interface for DirectPad Pro. See the source file
          (src/dos/multijoy.c) for pinout information.

        * JOY_TYPE_TURBOGRAFIX_LPT1
          JOY_TYPE_TURBOGRAFIX_LPT2
          JOY_TYPE_TURBOGRAFIX_LPT3
          These drivers support up to 7 joysticks, each one with up to 5
          buttons, connected to LPT1, LPT2, and LPT3 respectively. They
          use the TurboGraFX interface by Steffen Schwenke: see
          http://www.burg-halle.de/~schwenke/parport.html for details
          on how to build this.

        * JOY_TYPE_WINGWARRIOR
          A Wingman Warrior joystick.

        * JOY_TYPE_IFSEGA_ISA
          JOY_TYPE_IFSEGA_PCI
          JOY_TYPE_IFSEGA_PCI_FAST
          Drivers for the IF-SEGA joystick interface cards by the
          IO-DATA company (these come in PCI, PCI2, and ISA variants).

See also:
*Note install_joystick::.

File: allegro.info,  Node: GFX_*/DOS,  Next: DIGI_*/DOS,  Prev: JOY_TYPE_*/DOS,  Up: DOS

35.2 GFX_*/DOS
==============

Drivers GFX_*/DOS
     The DOS library supports the following card parameters for the
     set_gfx_mode() function:

        * GFX_TEXT
          Return to text mode.

        * GFX_AUTODETECT
          Let Allegro pick an appropriate graphics driver.

        * GFX_AUTODETECT_FULLSCREEN
          Autodetects a graphics driver, but will only use fullscreen
          drivers, failing if these are not available on current
          platform.

        * GFX_AUTODETECT_WINDOWED
          Same as above, but uses only windowed drivers. This will
          always fail under DOS.

        * GFX_SAFE
          Special driver for when you want to reliably set a graphics
          mode and don't really care what resolution or color depth you
          get. See the set_gfx_mode() documentation for details.

        * GFX_VGA
          The standard 256-color VGA mode 13h, using the GFX_VGA
          driver. This is normally sized 320x200, which will work on
          any VGA but doesn't support large virtual screens and
          hardware scrolling. Allegro also provides some tweaked
          variants of the mode which are able to scroll, sized 320x100
          (with a 200 pixel high virtual screen), 160x120 (with a 409
          pixel high virtual screen), 256x256 (no scrolling), and 80x80
          (with a 819 pixel high virtual screen).

        * GFX_MODEX
          Mode-X will work on any VGA card, and provides a range of
          different 256-color tweaked resolutions.

             * Stable mode-X resolutions:

                  * Square aspect ratio: 320x240

                  * Skewed aspect ratio: 256x224, 256x240, 320x200,
                    320x400, 320x480, 320x600, 360x200, 360x240,
                    360x360, 360x400, 360x480

               These have worked on every card/monitor that I've tested.

             * Unstable mode-X resolutions:

                  * Square aspect ratio: 360x270, 376x282, 400x300

                  * Skewed aspect ratio: 256x200, 256x256, 320x350,
                    360x600, 376x308, 376x564, 400x150, 400x600

               These only work on some monitors. They were fine on my
               old machine, but don't get on very well with my new
               monitor. If you are worried about the possibility of
               damaging your monitor by using these modes, don't be. Of
               course I'm not providing any warranty with any of this,
               and if your hardware does blow up that is tough, but I
               don't think this sort of tweaking can do any damage.
               From the documentation of Robert Schmidt's TWEAK program:

               "Some time ago, putting illegal or unsupported values or
               combinations of such into the video card registers might
               prove hazardous to both your monitor and your health. I
               have *never* claimed that bad things can't happen if you
               use TWEAK, although I'm pretty sure it never will. I've
               never heard of any damage arising from trying out TWEAK,
               or from general VGA tweaking in any case."

          Most of the mode-X drawing functions are slower than in mode
          13h, due to the complexity of the planar bitmap organisation,
          but solid area fills and plane-aligned blits from one part of
          video memory to another can be significantly faster,
          particularly on older hardware. Mode-X can address the full
          256k of VGA RAM, so hardware scrolling and page flipping are
          possible, and it is possible to split the screen in order to
          scroll the top part of the display but have a static status
          indicator at the bottom.

        * GFX_VESA1
          Use the VESA 1.x driver.

        * GFX_VESA2B
          Use the VBE 2.0 banked mode driver.

        * GFX_VESA2L
          Use the VBE 2.0 linear framebuffer driver.

        * GFX_VESA3
          Use the VBE 3.0 driver. This is the only VESA driver that
          supports the request_refresh_rate() function.

          The standard VESA modes are 640x480, 800x600, and 1024x768.
          These ought to work with any SVGA card: if they don't, get a
          copy of the SciTech Display Doctor and see if that fixes it.
          What color depths are available will depend on your hardware.
          Most cards support both 15 and 16-bit resolutions, but if at
          all possible I would advise you to support both (it's not
          hard...) in case one is not available. Some cards provide
          both 24 and 32-bit truecolor, in which case it is a choice
          between 24 (saves memory) or 32 (faster), but many older cards
          have no 32-bit mode and some newer ones don't support 24-bit
          resolutions. Use the vesainfo test program to see what modes
          your VESA driver provides.

          Many cards also support 640x400, 1280x1024, and 1600x1200,
          but these aren't available on everything, for example the S3
          chipset has no 640x400 mode. Other weird resolution may be
          possible, eg. some Tseng boards can do 640x350, and the
          Avance Logic has a 512x512 mode.

          The SciTech Display Doctor provides several scrollable low
          resolution modes in a range of different color depths
          (320x200, 320x240, 320x400, 320x480, 360x200, 360x240,
          360x400, and 360x480 all work on my ET4000 with 8, 15, or 16
          bits per pixel). These are lovely, allowing scrolling and
          page flipping without the complexity of the mode-X planar
          setup, but unfortunately they aren't standard so you will need
          Display Doctor in order to use them.

        * GFX_VBEAF
          VBE/AF is a superset of the VBE 2.0 standard, which provides
          an API for accessing hardware accelerator features. VBE/AF
          drivers are currently only available from the FreeBE/AF
          project or as part of the SciTech Display Doctor package, but
          they can give dramatic speed improvements when used with
          suitable hardware. For a detailed discussion of hardware
          acceleration issues, refer to the documentation for the
          gfx_capabilities flag.

          You can use the afinfo test program to check whether you have
          a VBE/AF driver, and to see what resolutions it supports.

          The SciTech VBE/AF drivers require nearptr access to be
          enabled, so any stray pointers are likely to crash your
          machine while their drivers are in use. This means it may be
          a good idea to use VESA while debugging your program, and
          only switch to VBE/AF once the code is working correctly. The
          FreeBE/AF drivers do not have this problem.

        * GFX_XTENDED
          An unchained 640x400 mode, as described by Mark Feldman in
          the PCGPE.  This uses VESA to select an SVGA mode (so it will
          only work on cards supporting the VESA 640x400 resolution),
          and then unchains the VGA hardware as for mode-X. This allows
          the entire screen to be addressed without the need for bank
          switching, but hardware scrolling and page flipping are not
          possible. This driver will never be autodetected (the normal
          VESA 640x400 mode will be chosen instead), so if you want to
          use it you will have to explicitly pass GFX_XTENDED to
          set_gfx_mode().

See also:
*Note set_gfx_mode::.

File: allegro.info,  Node: DIGI_*/DOS,  Next: MIDI_*/DOS,  Prev: GFX_*/DOS,  Up: DOS

35.3 DIGI_*/DOS
===============

Drivers DIGI_*/DOS
     The DOS sound functions support the following digital soundcards:

          DIGI_AUTODETECT      - let Allegro pick a digital sound driver
          DIGI_NONE            - no digital sound
          DIGI_SB              - Sound Blaster (autodetect type)
          DIGI_SB10            - SB 1.0 (8-bit mono single shot dma)
          DIGI_SB15            - SB 1.5 (8-bit mono single shot dma)
          DIGI_SB20            - SB 2.0 (8-bit mono auto-initialised
                                 dma)
          DIGI_SBPRO           - SB Pro (8-bit stereo)
          DIGI_SB16            - SB16 (16-bit stereo)
          DIGI_AUDIODRIVE      - ESS AudioDrive
          DIGI_SOUNDSCAPE      - Ensoniq Soundscape
          DIGI_WINSOUNDSYS     - Windows Sound System

See also:
*Note detect_digi_driver::.
*Note install_sound::.
*Note install_sound_input::.

File: allegro.info,  Node: MIDI_*/DOS,  Next: split_modex_screen,  Prev: DIGI_*/DOS,  Up: DOS

35.4 MIDI_*/DOS
===============

Drivers MIDI_*/DOS
     The DOS sound functions support the following MIDI soundcards:

          MIDI_AUTODETECT      - let Allegro pick a MIDI sound driver
          MIDI_NONE            - no MIDI sound
          MIDI_ADLIB           - Adlib or SB FM synth (autodetect type)
          MIDI_OPL2            - OPL2 synth (mono, used in Adlib and SB)
          MIDI_2XOPL2          - dual OPL2 synths (stereo, used in
                                 SB Pro-I)
          MIDI_OPL3            - OPL3 synth (stereo, SB Pro-II
                                 and above)
          MIDI_SB_OUT          - SB MIDI interface
          MIDI_MPU             - MPU-401 MIDI interface
          MIDI_DIGMID          - sample-based software wavetable player
          MIDI_AWE32           - AWE32 (EMU8000 chip)

See also:
*Note detect_midi_driver::.
*Note install_sound::.
*Note install_sound_input::.

File: allegro.info,  Node: split_modex_screen,  Next: i_love_bill,  Prev: MIDI_*/DOS,  Up: DOS

35.5 split_modex_screen
=======================

void split_modex_screen(int line);
     This function is only available in mode-X. It splits the VGA
     display into two parts at the specified line. The top half of the
     screen can be scrolled to any part of video memory with the
     scroll_screen() function, but the part below the specified line
     number will remain fixed and will display from position (0, 0) of
     the screen bitmap. After splitting the screen you will generally
     want to scroll so that the top part of the display starts lower
     down in video memory, and then create two sub-bitmaps to access
     the two sections (see examples/exscroll.c for a demonstration of
     how this could be done). To disable the split, call
     split_modex_screen(0).

See also:
*Note set_gfx_mode::.
*Note scroll_screen::.
*Note exscroll::.

File: allegro.info,  Node: i_love_bill,  Next: GFX_*/Windows,  Prev: split_modex_screen,  Up: DOS

35.6 i_love_bill
================

extern int i_love_bill;
     When running in clean DOS mode, the timer handler dynamically
     reprograms the clock chip to generate interrupts at exactly the
     right times, which gives an extremely high accuracy.
     Unfortunately, this constant speed adjustment doesn't work under
     most multitasking systems (notably Windows), so there is an
     alternative mode that just locks the hardware timer interrupt to a
     speed of 200 ticks per second. This reduces the accuracy of the
     timer (for instance, rest() will round the delay time to the
     nearest 5 milliseconds), and prevents the vertical retrace
     simulator from working, but on the plus side, it makes Allegro
     programs work under Windows. This flag is set by allegro_init() if
     it detects the presence of a multitasking OS, and enables the
     fixed rate timer mode.

See also:
*Note install_timer::.
*Note allegro_init::.
*Note os_type::.

File: allegro.info,  Node: Windows,  Next: Unix,  Prev: DOS,  Up: Top

36 Windows specifics
********************

A Windows program that uses the Allegro library is only required to
include one or more header files from the include/allegro tree, or
allegro.h; however, if it also needs to directly call non portable
Win32 API functions, it must include the Windows-specific header file
winalleg.h after the Allegro headers, and before any Win32 API header
file. By default winalleg.h includes the main Win32 C API header file
windows.h. If instead you want to use the C++ interface to the Win32
API (a.k.a. the Microsoft Foundation Classes), define the preprocessor
symbol ALLEGRO_AND_MFC before including any Allegro header so that
afxwin.h will be included. Note that, in this latter case, the Allegro
debugging macros ASSERT() and TRACE() are renamed AL_ASSERT() and
AL_TRACE() respectively.

Windows GUI applications start with a WinMain() entry point, rather
than the standard main() entry point. Allegro is configured to build
GUI applications by default and to do some magic in order to make a
regular main() work with them, but you have to help it out a bit by
writing END_OF_MAIN() right after your main() function. If you don't
want to do that, you can just include winalleg.h and write a WinMain()
function. Note that this magic may bring about conflicts with a few
programs using direct calls to Win32 API functions; for these programs,
the regular WinMain() is required and the magic must be disabled by
defining the preprocessor symbol ALLEGRO_NO_MAGIC_MAIN before including
Allegro headers.

If you want to build a console application using Allegro, you have to
define the preprocessor symbol ALLEGRO_USE_CONSOLE before including
Allegro headers; it will instruct the library to use console features
and also to disable the special processing of the main() function
described above.

When creating the main window, Allegro searches the executable for an
ICON resource named "allegro_icon". If it is present, Allegro
automatically loads it and uses it as its application icon; otherwise,
Allegro uses the default IDI_APPLICATION icon. See the manual of your
compiler for a method to create an ICON resource, or use the wfixicon
utility from the tools/win directory.

DirectX requires that system and video bitmaps (including the screen) be
locked before you can draw onto them. This will be done automatically,
but you can usually get much better performance by doing it yourself:
see the acquire_bitmap() function for details.

Due to a major oversight in the design of DirectX, there is no way to
preserve the contents of video memory when the user switches away from
your program. You need to be prepared for the fact that your screen
contents, and the contents of any video memory bitmaps, may be
destroyed at any point. You can use the set_display_switch_callback()
function to find out when this happens.

On the Windows platform, the only return values for the
desktop_color_depth() function are 8, 16, 24 and 32. This means that
15-bit and 16-bit desktops cannot be differentiated and are both
reported as 16-bit desktops. See below for the consequences for
windowed and overlay DirectX drivers.

* Menu:

* GFX_*/Windows::
* DIGI_*/Windows::
* MIDI_*/Windows::
* win_get_window::
* win_set_window::
* win_set_wnd_create_proc::
* win_get_dc::
* win_release_dc::
* GDI routines::
* set_gdi_color_format::
* set_palette_to_hdc::
* convert_palette_to_hpalette::
* convert_hpalette_to_palette::
* convert_bitmap_to_hbitmap::
* convert_hbitmap_to_bitmap::
* draw_to_hdc::
* blit_to_hdc::
* stretch_blit_to_hdc::
* blit_from_hdc::
* stretch_blit_from_hdc::


File: allegro.info,  Node: GFX_*/Windows,  Next: DIGI_*/Windows,  Prev: i_love_bill,  Up: Windows

36.1 GFX_*/Windows
==================

Drivers GFX_*/Windows
     The Windows library supports the following card parameters for the
     set_gfx_mode() function:

        * GFX_TEXT
          This closes any graphics mode previously opened with
          set_gfx_mode.

        * GFX_AUTODETECT
          Let Allegro pick an appropriate graphics driver.

        * GFX_AUTODETECT_FULLSCREEN
          Autodetects a graphics driver, but will only use fullscreen
          drivers, failing if these are not available on current
          platform.

        * GFX_AUTODETECT_WINDOWED
          Same as above, but uses only windowed drivers.

        * GFX_SAFE
          Special driver for when you want to reliably set a graphics
          mode and don't really care what resolution or color depth you
          get. See the set_gfx_mode() documentation for details.

        * GFX_DIRECTX
          Alias for GFX_DIRECTX_ACCEL.

        * GFX_DIRECTX_ACCEL
          The regular fullscreen DirectX driver, running with hardware
          acceleration enabled.

        * GFX_DIRECTX_SOFT
          DirectX fullscreen driver that only uses software drawing,
          rather than any hardware accelerated features.

        * GFX_DIRECTX_SAFE
          Simplified fullscreen DirectX driver that doesn't support any
          hardware acceleration, video or system bitmaps, etc.

        * GFX_DIRECTX_WIN
          The regular windowed DirectX driver, running in color
          conversion mode when the color depth doesn't match that of
          the Windows desktop. Color conversion is much slower than
          direct drawing and is not supported between 15-bit and 16-bit
          color depths. This limitation is needed to work around that
          of desktop_color_depth() (see above) and allows to select the
          direct drawing mode in a reliable way on desktops reported as
          16-bit:

               if (desktop_color_depth() == 16) {
                  set_color_depth(16);
                  if (set_gfx_mode(GFX_DIRECTX_WIN, 640, 480, 0, 0)
                      != 0) {
                     set_color_depth(15);
                     if (set_gfx_mode(GFX_DIRECTX_WIN, 640, 480, 0, 0)
                         != 0) {
                        /* 640x480 direct drawing mode not supported */
                        goto Error;
                     }
                  }
                  /* ok, we are in direct drawing mode */
               }

          Note that, mainly for performance reasons, this driver
          requires the width of the screen to be a multiple of 4.

        * GFX_DIRECTX_OVL
          The DirectX overlay driver. It uses special hardware features
          to run your program in a windowed mode: it doesn't work on
          all hardware, but performance is excellent on cards that are
          capable of it. It requires the color depth to be the same as
          that of the Windows desktop. In light of the limitation of
          desktop_color_depth() (see above), the reliable way of
          setting the overlay driver on desktops reported as 16-bit is:

               if (desktop_color_depth() == 16) {
                  set_color_depth(16);
                  if (set_gfx_mode(GFX_DIRECTX_OVL, 640, 480, 0, 0)
                      != 0) {
                     set_color_depth(15);
                     if (set_gfx_mode(GFX_DIRECTX_OVL, 640, 480, 0, 0)
                         != 0) {
                        /* 640x480 overlay driver not supported */
                        goto Error;
                     }
                  }
                  /* ok, the 640x480 overlay driver is running */
               }

        * GFX_GDI
          The windowed GDI driver. It is extremely slow, but is
          guaranteed to work on all hardware, so it can be useful for
          situations where you want to run in a window and don't care
          about performance. Note that this driver features a hardware
          mouse cursor emulation in order to speed up basic mouse
          operations (like GUI operations).

See also:
*Note set_gfx_mode::.

File: allegro.info,  Node: DIGI_*/Windows,  Next: MIDI_*/Windows,  Prev: GFX_*/Windows,  Up: Windows

36.2 DIGI_*/Windows
===================

Drivers DIGI_*/Windows
     The Windows sound functions support the following digital
     soundcards:

          DIGI_AUTODETECT      - let Allegro pick a digital sound driver
          DIGI_NONE            - no digital sound
          DIGI_DIRECTX(n)      - use DirectSound device #n (zero-based)
                                 with direct mixing
          DIGI_DIRECTAMX(n)    - use DirectSound device #n (zero-based)
                                 with Allegro mixing
          DIGI_WAVOUTID(n)     - high (n=0) or low (n=1) quality WaveOut
                                 device

See also:
*Note detect_digi_driver::.
*Note install_sound::.
*Note install_sound_input::.

File: allegro.info,  Node: MIDI_*/Windows,  Next: win_get_window,  Prev: DIGI_*/Windows,  Up: Windows

36.3 MIDI_*/Windows
===================

Drivers MIDI_*/Windows
     The Windows sound functions support the following MIDI soundcards:

          MIDI_AUTODETECT      - let Allegro pick a MIDI sound driver
          MIDI_NONE            - no MIDI sound
          MIDI_WIN32MAPPER     - use win32 MIDI mapper
          MIDI_WIN32(n)        - use win32 device #n (zero-based)
          MIDI_DIGMID          - sample-based software wavetable player

The following functions provide a platform specific interface to
seamlessly integrate Allegro into general purpose Win32 programs. To
use these routines, you must include winalleg.h after other Allegro
headers.

See also:
*Note detect_midi_driver::.
*Note install_sound::.
*Note install_sound_input::.

File: allegro.info,  Node: win_get_window,  Next: win_set_window,  Prev: MIDI_*/Windows,  Up: Windows

36.4 win_get_window
===================

HWND win_get_window(void);
     Retrieves a handle to the window used by Allegro. Note that Allegro
     uses an underlying window even though you don't set any graphics
     mode, unless you have installed the neutral system driver
     (SYSTEM_NONE).



File: allegro.info,  Node: win_set_window,  Next: win_set_wnd_create_proc,  Prev: win_get_window,  Up: Windows

36.5 win_set_window
===================

void win_set_window(HWND wnd);
     Registers an user-created window to be used by Allegro. This
     function is meant to be called before initialising the library
     with allegro_init() or installing the autodetected system driver
     (SYSTEM_AUTODETECT). It lets you attach Allegro to any already
     existing window and prevents the library from creating its own,
     thus leaving you total control over the window; in particular, you
     are responsible for processing the events as usual (Allegro will
     automatically monitor a few of them, but will not filter out any
     of them). You can then use every component of the library
     (graphics, mouse, keyboard, sound, timers and so on), bearing in
     mind that some Allegro functions are blocking (e.g. readkey() if
     the key buffer is empty) and thus must be carefully manipulated by
     the window thread.

     However you can also call it after the library has been
     initialised, provided that no graphics mode is set. In this case
     the keyboard, mouse, joystick, sound and sound recording modules
     will be restarted.

     Passing NULL instructs Allegro to switch back to its built-in
     window if an user-created window was registered, or to request a
     new handle from Windows for its built-in window if this was
     already in use.



File: allegro.info,  Node: win_set_wnd_create_proc,  Next: win_get_dc,  Prev: win_set_window,  Up: Windows

36.6 win_set_wnd_create_proc
============================

void win_set_wnd_create_proc(HWND (*proc)(WNDPROC));
     Registers an user-defined procedure to be used by Allegro for
     creating its window. This function must be called *before*
     initializing the library with allegro_init() or installing the
     autodetected system driver (SYSTEM_AUTODETECT). It lets you
     customize Allegro's window but only by its creation: unlike with
     win_set_window(), you have no control over the window once it has
     been created (in particular, you are not responsible for
     processing the events). The registered function will be passed a
     window procedure (WNDPROC object) that it must make the procedure
     of the new window of and it must return a handle to the new
     window. You can then use the full-featured library in the regular
     way.



File: allegro.info,  Node: win_get_dc,  Next: win_release_dc,  Prev: win_set_wnd_create_proc,  Up: Windows

36.7 win_get_dc
===============

HDC win_get_dc(BITMAP *bmp);
     Retrieves a handle to the device context of a DirectX video or
     system bitmap.

*Note BITMAP::.

File: allegro.info,  Node: win_release_dc,  Next: GDI routines,  Prev: win_get_dc,  Up: Windows

36.8 win_release_dc
===================

void win_release_dc(BITMAP *bmp, HDC dc);
     Releases a handle to the device context of the bitmap that was
     previously retrieved with win_get_dc().

*Note BITMAP::.

File: allegro.info,  Node: GDI routines,  Next: set_gdi_color_format,  Prev: win_release_dc,  Up: Windows

36.9 GDI routines
=================

The following GDI routines are a very platform specific thing, to allow
drawing Allegro memory bitmaps onto a Windows device context. When you
want to use this, you'll have to install the neutral system driver
(SYSTEM_NONE) or attach Allegro to an external window with
win_set_window().

There are two ways to draw your Allegro bitmaps to the Windows GDI.
When you are using static bitmaps (for example just some pictures
loaded from a datafile), you can convert them to DDB (device-dependent
bitmaps) with convert_bitmap_to_hbitmap() and then just use Win32's
BitBlt() to draw it.

When you are using dynamic bitmaps (for example some things which react
to user input), it's better to use set_palette_to_hdc() and
blit_to_hdc() functions, which work with DIB (device-independent
bitmaps).

There are also functions to blit from a device context into an Allegro
BITMAP, so you can do things like screen capture.

All the drawing and conversion functions use the current palette as a
color conversion table. You can alter the current palette with the
set_palette_to_hdc() or select_palette() functions. Warning: when the
GDI system color palette is explicitly changed, (by another
application, for example) the current Allegro palette is not updated
along with it!

To use these routines, you must include winalleg.h after Allegro
headers.


File: allegro.info,  Node: set_gdi_color_format,  Next: set_palette_to_hdc,  Prev: GDI routines,  Up: Windows

36.10 set_gdi_color_format
==========================

void set_gdi_color_format(void);
     Tells Allegro to use the GDI color layout for truecolor images.
     This is optional, but it will make the conversions work faster. If
     you are going to call this, you should do it right after
     initialising Allegro and before creating any graphics.



File: allegro.info,  Node: set_palette_to_hdc,  Next: convert_palette_to_hpalette,  Prev: set_gdi_color_format,  Up: Windows

36.11 set_palette_to_hdc
========================

void set_palette_to_hdc(HDC dc, PALETTE pal);
     Selects and realizes an Allegro palette on the specified device
     context.

*Note PALETTE::.

File: allegro.info,  Node: convert_palette_to_hpalette,  Next: convert_hpalette_to_palette,  Prev: set_palette_to_hdc,  Up: Windows

36.12 convert_palette_to_hpalette
=================================

HPALETTE convert_palette_to_hpalette(PALETTE pal);
     Converts an Allegro palette to a Windows palette and returns a
     handle to it. You should call DeleteObject() when you no longer
     need it.

See also:
*Note convert_hpalette_to_palette::.
*Note PALETTE::.

File: allegro.info,  Node: convert_hpalette_to_palette,  Next: convert_bitmap_to_hbitmap,  Prev: convert_palette_to_hpalette,  Up: Windows

36.13 convert_hpalette_to_palette
=================================

void convert_hpalette_to_palette(HPALETTE hpal, PALETTE pal);
     Converts a Windows palette to an Allegro palette.

See also:
*Note convert_palette_to_hpalette::.
*Note PALETTE::.

File: allegro.info,  Node: convert_bitmap_to_hbitmap,  Next: convert_hbitmap_to_bitmap,  Prev: convert_hpalette_to_palette,  Up: Windows

36.14 convert_bitmap_to_hbitmap
===============================

HBITMAP convert_bitmap_to_hbitmap(BITMAP *bitmap);
     Converts an Allegro memory bitmap to a Windows DDB and returns a
     handle to it. This bitmap uses its own memory, so you can destroy
     the original bitmap without affecting the converted one. You
     should call DeleteObject() when you no longer need this bitmap.

See also:
*Note convert_hbitmap_to_bitmap::.
*Note BITMAP::.

File: allegro.info,  Node: convert_hbitmap_to_bitmap,  Next: draw_to_hdc,  Prev: convert_bitmap_to_hbitmap,  Up: Windows

36.15 convert_hbitmap_to_bitmap
===============================

BITMAP *convert_hbitmap_to_bitmap(HBITMAP bitmap);
     Creates an Allegro memory bitmap from a Windows DDB.

See also:
*Note convert_bitmap_to_hbitmap::.
*Note BITMAP::.

File: allegro.info,  Node: draw_to_hdc,  Next: blit_to_hdc,  Prev: convert_hbitmap_to_bitmap,  Up: Windows

36.16 draw_to_hdc
=================

void draw_to_hdc(HDC dc, BITMAP *bitmap, int x, int y);
     Draws an entire Allegro bitmap to a Windows device context, using
     the same parameters as the draw_sprite() function.

See also:
*Note blit_to_hdc::.
*Note stretch_blit_to_hdc::.
*Note draw_sprite::.
*Note BITMAP::.

File: allegro.info,  Node: blit_to_hdc,  Next: stretch_blit_to_hdc,  Prev: draw_to_hdc,  Up: Windows

36.17 blit_to_hdc
=================

void blit_to_hdc(BITMAP *bitmap, HDC dc, int sx, sy, dx, dy, w, h);
     Blits an Allegro memory bitmap to a Windows device context, using
     the same parameters as the blit() function.

See also:
*Note draw_to_hdc::.
*Note stretch_blit_to_hdc::.
*Note blit_from_hdc::.
*Note blit::.
*Note BITMAP::.

File: allegro.info,  Node: stretch_blit_to_hdc,  Next: blit_from_hdc,  Prev: blit_to_hdc,  Up: Windows

36.18 stretch_blit_to_hdc
=========================

void stretch_blit_to_hdc(BITMAP *bitmap, HDC dc, int sx, sy, sw, sh, int dx, dy, dw, dh);
     Blits an Allegro memory bitmap to a Windows device context, using
     the same parameters as the stretch_blit() function.

See also:
*Note draw_to_hdc::.
*Note blit_to_hdc::.
*Note stretch_blit_from_hdc::.
*Note stretch_blit::.
*Note BITMAP::.

File: allegro.info,  Node: blit_from_hdc,  Next: stretch_blit_from_hdc,  Prev: stretch_blit_to_hdc,  Up: Windows

36.19 blit_from_hdc
===================

void blit_from_hdc(HDC hdc, BITMAP *bitmap, int sx, sy, dx, dy, w, h);
     Blits from a Windows device context to an Allegro memory bitmap,
     using the same parameters as the blit() function. See
     stretch_blit_from_hdc() for details.

See also:
*Note stretch_blit_from_hdc::.
*Note blit_to_hdc::.
*Note blit::.
*Note BITMAP::.

File: allegro.info,  Node: stretch_blit_from_hdc,  Next: GFX_*/Linux,  Prev: blit_from_hdc,  Up: Windows

36.20 stretch_blit_from_hdc
===========================

void stretch_blit_from_hdc(HDC hcd, BITMAP *bitmap, int sx, sy, sw, sh, int dx, dy, dw, dh);
     Blits from a Windows device context to an Allegro memory bitmap,
     using the same parameters as the stretch_blit() function. It uses
     the current Allegro palette and does conversion to this palette,
     regardless of the current DC palette. So if you are blitting from
     8-bit mode, you should first set the DC palette with the
     set_palette_to_hdc() function.

See also:
*Note blit_from_hdc::.
*Note stretch_blit_to_hdc::.
*Note stretch_blit::.
*Note BITMAP::.

File: allegro.info,  Node: Unix,  Next: BeOS,  Prev: Windows,  Up: Top

37 Unix specifics
*****************

In order to locate things like the config and translation files, Allegro
needs to know the path to your executable. Since there is no standard
way to find that, it needs to capture a copy of your argv[] parameter,
and it does this with some preprocessor macro trickery. Unfortunately
it can't quite pull this off without a little bit of your help, so you
will have to write END_OF_MAIN() right after your main() function.
Pretty easy, really, and if you forget, you'll get a nice linker error
about a missing _mangled_main function to remind you :-)

* Menu:

* GFX_*/Linux::
* GFX_*/X::
* DIGI_*/Unix::
* MIDI_*/Unix::
* xwin_set_window_name::


File: allegro.info,  Node: GFX_*/Linux,  Next: GFX_*/X,  Prev: stretch_blit_from_hdc,  Up: Unix

37.1 GFX_*/Linux
================

Drivers GFX_*/Linux
     When running in Linux console mode, Allegro supports the following
     card parameters for the set_gfx_mode() function:

        * GFX_TEXT
          Return to text mode.

        * GFX_AUTODETECT
          Let Allegro pick an appropriate graphics driver.

        * GFX_AUTODETECT_FULLSCREEN
          Autodetects a graphics driver, but will only use fullscreen
          drivers, failing if these are not available on current
          platform.

        * GFX_AUTODETECT_WINDOWED
          Same as above, but uses only windowed drivers. This will
          always fail under Linux console mode.

        * GFX_SAFE
          Special driver for when you want to reliably set a graphics
          mode and don't really care what resolution or color depth you
          get. See the set_gfx_mode() documentation for details.

        * GFX_FBCON
          Use the framebuffer device (eg. /dev/fb0). This requires you
          to have framebuffer support compiled into your kernel, and
          correctly configured for your hardware. It is currently the
          only console mode driver that will work without root
          permissions, unless you are using a development version of
          SVGAlib.

        * GFX_VBEAF
          Use a VBE/AF driver (vbeaf.drv), assuming that you have
          installed one which works under Linux (currently only two of
          the FreeBE/AF project drivers are capable of this: I don't
          know about the SciTech ones).  VBE/AF requires root
          permissions, but is currently the only Linux driver which
          supports hardware accelerated graphics.

        * GFX_SVGALIB
          Use the SVGAlib library for graphics output. This requires
          root permissions if your version of SVGAlib requires them.

        * GFX_VGA
          GFX_MODEX
          Use direct hardware access to set standard VGA or mode-X
          resolutions, supporting the same modes as in the DOS versions
          of these drivers.  Requires root permissions.

See also:
*Note set_gfx_mode::.
*Note GFX_*/X::.

File: allegro.info,  Node: GFX_*/X,  Next: DIGI_*/Unix,  Prev: GFX_*/Linux,  Up: Unix

37.2 GFX_*/X
============

Drivers GFX_*/X
     When running in X mode, Allegro supports the following card
     parameters for the set_gfx_mode() function:

        * GFX_TEXT
          This closes any graphics mode previously opened with
          set_gfx_mode.

        * GFX_AUTODETECT
          Let Allegro pick an appropriate graphics driver.

        * GFX_AUTODETECT_FULLSCREEN
          Autodetects a graphics driver, but will only use fullscreen
          drivers, failing if these are not available on current
          platform.

        * GFX_AUTODETECT_WINDOWED
          Same as above, but uses only windowed drivers.

        * GFX_SAFE
          Special driver for when you want to reliably set a graphics
          mode and don't really care what resolution or color depth you
          get. See the set_gfx_mode() documentation for details.

        * GFX_XWINDOWS
          The standard X graphics driver. This should work on any Unix
          system, and can operate remotely. It does not require root
          permissions.

        * GFX_XWINDOWS_FULLSCREEN
          The same as above, but while GFX_XWINDOWS runs windowed, this
          one uses the XF86VidMode extension to make it run in
          fullscreen mode even without root permissions. You're still
          using the standard X protocol though, so expect the same low
          performances as with the windowed driver version.

        * GFX_XDGA
          Use the XFree86 DGA 1.0 extension to write directly to the
          screen surface. DGA is normally much faster than the standard
          X mode, but does not produce such well behaved windowed
          programs, and will not work remotely. This driver requires
          root permissions.

        * GFX_XDGA_FULLSCREEN
          Like GFX_XDGA, but also changes the screen resolution so that
          it will run fullscreen. This driver requires root permissions.

        * GFX_XDGA2
          Use new DGA 2.0 extension provided by XFree86 4.0.x. This
          will work in fullscreen mode, and it will support hardware
          acceleration if available. This driver requires root
          permissions.

        * GFX_XDGA2_SOFT
          The same as GFX_XDGA2, but turns off hardware acceleration
          support.  This driver requires root permissions.

See also:
*Note set_gfx_mode::.
*Note GFX_*/Linux::.

File: allegro.info,  Node: DIGI_*/Unix,  Next: MIDI_*/Unix,  Prev: GFX_*/X,  Up: Unix

37.3 DIGI_*/Unix
================

Drivers DIGI_*/Unix
     The Unix sound functions support the following digital soundcards:

          DIGI_AUTODETECT      - let Allegro pick a digital sound driver
          DIGI_NONE            - no digital sound
          DIGI_OSS             - Open Sound System
          DIGI_ESD             - Enlightened Sound Daemon
          DIGI_ARTS            - aRts (Analog Real-Time Synthesizer)
          DIGI_ALSA            - ALSA sound driver

See also:
*Note detect_digi_driver::.
*Note install_sound::.
*Note install_sound_input::.

File: allegro.info,  Node: MIDI_*/Unix,  Next: xwin_set_window_name,  Prev: DIGI_*/Unix,  Up: Unix

37.4 MIDI_*/Unix
================

Drivers MIDI_*/Unix
     The Unix sound functions support the following MIDI soundcards:

          MIDI_AUTODETECT      - let Allegro pick a MIDI sound driver
          MIDI_NONE            - no MIDI sound
          MIDI_OSS             - Open Sound System
          MIDI_DIGMID          - sample-based software wavetable player
          MIDI_ALSA            - ALSA RawMIDI driver

See also:
*Note detect_midi_driver::.
*Note install_sound::.
*Note install_sound_input::.

File: allegro.info,  Node: xwin_set_window_name,  Next: GFX_*/BeOS,  Prev: MIDI_*/Unix,  Up: Unix

37.5 xwin_set_window_name
=========================

void xwin_set_window_name(const char *name, const char *group);
     This function is only available under X. It lets you to specify the
     window name and group (or class). They are important because they
     allow the window manager to remember the window attributes
     (position, layer, etc). Note that the name and the title of the
     window are two different things: the title is what appears in the
     title bar of the window, but usually has no other effects on the
     behaviour of the application.

See also:
*Note set_window_title::.

File: allegro.info,  Node: BeOS,  Next: QNX,  Prev: Unix,  Up: Top

38 BeOS specifics
*****************

* Menu:

* GFX_*/BeOS::
* DIGI_*/BeOS::
* MIDI_*/BeOS::


File: allegro.info,  Node: GFX_*/BeOS,  Next: DIGI_*/BeOS,  Prev: xwin_set_window_name,  Up: BeOS

38.1 GFX_*/BeOS
===============

Drivers GFX_*/BeOS
     BeOS Allegro supports the following card parameters for the
     set_gfx_mode() function:

        * GFX_TEXT
          This closes any graphics mode previously opened with
          set_gfx_mode.

        * GFX_AUTODETECT
          Let Allegro pick an appropriate graphics driver.

        * GFX_AUTODETECT_FULLSCREEN
          Autodetects a graphics driver, but will only use fullscreen
          drivers, failing if these are not available on current
          platform.

        * GFX_AUTODETECT_WINDOWED
          Same as above, but uses only windowed drivers.

        * GFX_SAFE
          Special driver for when you want to reliably set a graphics
          mode and don't really care what resolution. See the
          set_gfx_mode() documentation for details.

        * GFX_BWINDOWSCREEN_ACCEL
          Fullscreen exclusive mode. Supports only resolutions higher
          or equal to 640x480, and uses hardware acceleration if
          available.

        * GFX_BWINDOWSCREEN
          Works the same as GFX_BWINDOWSCREEN_ACCEL, but disables
          acceleration.

        * GFX_BDIRECTWINDOW
          Fast windowed mode using the BDirectWindow class. Not all
          graphics cards support this.

        * GFX_BWINDOW
          Normal windowed mode using the BWindow class. Slow but always
          works.

        * GFX_BWINDOW_OVERLAY
          Fullscreen mode using BWindow with a BBitmap overlay. This
          mode isn't supported by all graphics cards, only supports 15,
          16 and 32-bit color depths, but allows any fullscreen
          resolution, even low ones that are normally unavailable under
          BeOS.

See also:
*Note set_gfx_mode::.

File: allegro.info,  Node: DIGI_*/BeOS,  Next: MIDI_*/BeOS,  Prev: GFX_*/BeOS,  Up: BeOS

38.2 DIGI_*/BeOS
================

Drivers DIGI_*/BeOS
     The BeOS sound functions support the following digital soundcards:

          DIGI_AUTODETECT      - let Allegro pick a digital sound driver
          DIGI_NONE            - no digital sound
          DIGI_BEOS            - BeOS digital output

See also:
*Note detect_digi_driver::.
*Note install_sound::.
*Note install_sound_input::.

File: allegro.info,  Node: MIDI_*/BeOS,  Next: GFX_*/QNX,  Prev: DIGI_*/BeOS,  Up: BeOS

38.3 MIDI_*/BeOS
================

Drivers MIDI_*/BeOS
     The BeOS sound functions support the following MIDI soundcards:

          MIDI_AUTODETECT      - let Allegro pick a MIDI sound driver
          MIDI_NONE            - no MIDI sound
          MIDI_BEOS            - BeOS MIDI output
          MIDI_DIGMID          - sample-based software wavetable player

See also:
*Note detect_midi_driver::.
*Note install_sound::.
*Note install_sound_input::.

File: allegro.info,  Node: QNX,  Next: MacOS,  Prev: BeOS,  Up: Top

39 QNX specifics
****************

* Menu:

* GFX_*/QNX::
* DIGI_*/QNX::
* MIDI_*/QNX::
* qnx_get_window::


File: allegro.info,  Node: GFX_*/QNX,  Next: DIGI_*/QNX,  Prev: MIDI_*/BeOS,  Up: QNX

39.1 GFX_*/QNX
==============

Drivers GFX_*/QNX
     QNX Allegro supports the following card parameters for the
     set_gfx_mode() function:

        * GFX_TEXT
          This closes any graphics mode previously opened with
          set_gfx_mode.

        * GFX_AUTODETECT
          Let Allegro pick an appropriate graphics driver.

        * GFX_AUTODETECT_FULLSCREEN
          Autodetects a graphics driver, but will only use fullscreen
          drivers, failing if these are not available on current
          platform.

        * GFX_AUTODETECT_WINDOWED
          Same as above, but uses only windowed drivers.

        * GFX_SAFE
          Special driver for when you want to reliably set a graphics
          mode and don't really care what resolution. See the
          set_gfx_mode() documentation for details.

        * GFX_PHOTON
          Alias for GFX_PHOTON_ACCEL.

        * GFX_PHOTON_ACCEL
          Fullscreen exclusive mode through Photon, running with
          hardware acceleration enabled.

        * GFX_PHOTON_SOFT
          Fullscreen exclusive mode that only uses software drawing,
          rather than any hardware accelerated features.

        * GFX_PHOTON_SAFE
          Simplified fullscreen exclusive driver that doesn't support
          any hardware acceleration, video or system bitmaps, etc.

        * GFX_PHOTON_WIN
          The regular windowed Photon driver, running in color
          conversion mode when the color depth doesn't match that of
          the Photon desktop. Color conversion is much slower than
          direct drawing. Note that, mainly for performance reasons,
          this driver requires the width of the screen to be a multiple
          of 4.

See also:
*Note set_gfx_mode::.

File: allegro.info,  Node: DIGI_*/QNX,  Next: MIDI_*/QNX,  Prev: GFX_*/QNX,  Up: QNX

39.2 DIGI_*/QNX
===============

Drivers DIGI_*/QNX
     The QNX sound functions support the following digital soundcards:

          DIGI_AUTODETECT      - let Allegro pick a digital sound driver
          DIGI_NONE            - no digital sound
          DIGI_ALSA            - ALSA sound driver

See also:
*Note detect_digi_driver::.
*Note install_sound::.
*Note install_sound_input::.

File: allegro.info,  Node: MIDI_*/QNX,  Next: qnx_get_window,  Prev: DIGI_*/QNX,  Up: QNX

39.3 MIDI_*/QNX
===============

Drivers MIDI_*/QNX
     The QNX sound functions support the following MIDI soundcards:

          MIDI_AUTODETECT      - let Allegro pick a MIDI sound driver
          MIDI_NONE            - no MIDI sound
          MIDI_ALSA            - ALSA RawMIDI driver
          MIDI_DIGMID          - sample-based software wavetable player

The following functions provide a platform specific interface to
seamlessly integrate Allegro into general purpose QNX programs. To use
these routines, you must include qnxalleg.h after other Allegro headers.

See also:
*Note detect_midi_driver::.
*Note install_sound::.
*Note install_sound_input::.

File: allegro.info,  Node: qnx_get_window,  Next: GFX_*/MacOSX,  Prev: MIDI_*/QNX,  Up: QNX

39.4 qnx_get_window
===================

PtWidget_t qnx_get_window(void);
     Retrieves a handle to the window used by Allegro. Note that Allegro
     uses an underlying window even though you don't set any graphics
     mode, unless you have installed the neutral system driver
     (SYSTEM_NONE).



File: allegro.info,  Node: MacOS,  Next: Differences,  Prev: QNX,  Up: Top

40 MacOS X specifics
********************

* Menu:

* GFX_*/MacOSX::
* DIGI_*/MacOSX::
* MIDI_*/MacOSX::


File: allegro.info,  Node: GFX_*/MacOSX,  Next: DIGI_*/MacOSX,  Prev: qnx_get_window,  Up: MacOS

40.1 GFX_*/MacOSX
=================

Drivers GFX_*/MacOSX
     MacOS X Allegro supports the following card parameters for the
     set_gfx_mode() function:

        * GFX_TEXT
          This closes any graphics mode previously opened with
          set_gfx_mode.

        * GFX_AUTODETECT
          Let Allegro pick an appropriate graphics driver.

        * GFX_AUTODETECT_FULLSCREEN
          Autodetects a graphics driver, but will only use fullscreen
          drivers, failing if these are not available on current
          platform.

        * GFX_AUTODETECT_WINDOWED
          Same as above, but uses only windowed drivers.

        * GFX_SAFE
          Special driver for when you want to reliably set a graphics
          mode and don't really care what resolution. See the
          set_gfx_mode() documentation for details.

        * GFX_QUARTZ_FULLSCREEN
          Fullscreen exclusive mode, using the CGDirectDisplay
          interface.  Supports only resolutions higher or equal to
          640x480, and uses hardware acceleration if available.

        * GFX_QUARTZ_WINDOW
          Windowed mode using QuickDraw in a Cocoa window.

See also:
*Note set_gfx_mode::.

File: allegro.info,  Node: DIGI_*/MacOSX,  Next: MIDI_*/MacOSX,  Prev: GFX_*/MacOSX,  Up: MacOS

40.2 DIGI_*/MacOSX
==================

Drivers DIGI_*/MacOSX
     The MacOS X sound functions support the following digital
     soundcards:

          DIGI_AUTODETECT      - let Allegro pick a digital sound driver
          DIGI_NONE            - no digital sound
          DIGI_CORE_AUDIO      - CoreAudio digital output (OS >= X.2 required)
          DIGI_SOUND_MANAGER   - Carbon Sound Manager digital output

See also:
*Note detect_digi_driver::.
*Note install_sound::.
*Note install_sound_input::.

File: allegro.info,  Node: MIDI_*/MacOSX,  Next: al_assert,  Prev: DIGI_*/MacOSX,  Up: MacOS

40.3 MIDI_*/MacOSX
==================

Drivers MIDI_*/MacOSX
     The MacOS X sound functions support the following MIDI soundcards:

          MIDI_AUTODETECT      - let Allegro pick a MIDI sound driver
          MIDI_NONE            - no MIDI sound
          MIDI_CORE_AUDIO      - CoreAudio MIDI synthesizer (OS >= X.2 required)
          MIDI_QUICKTIME       - QuickTime Music Note Allocator MIDI output
          MIDI_DIGMID          - sample-based software wavetable player

See also:
*Note detect_midi_driver::.
*Note install_sound::.
*Note install_sound_input::.

File: allegro.info,  Node: Differences,  Next: Reducing,  Prev: MacOS,  Up: Top

41 Differences between platforms
********************************

Here's a quick summary of things that may cause problems when moving
your code from one platform to another (you can find a more detailed
version of this in the docs section of the Allegro website).

The Windows, Unix and MacOS X versions require you to write
END_OF_MAIN() after your main() function, which is used to magically
turn an ANSI C style main() into a Windows style WinMain(), and so that
the Unix code can grab a copy of your argv[] parameter. MacOS X uses it
to shell the user main() inside a Cocoa application.

On many platforms Allegro runs very slowly if you rely on it in order to
automatically lock bitmaps when drawing onto them. For good performance,
you need to call acquire_bitmap() and release_bitmap() yourself, and try
to keep the amount of locking to a minimum.

The Windows version may lose the contents of video memory if the user
switches away from your program, so you need to deal with that.

None of the currently supported platforms require input polling, but it
is possible that some future ones might, so if you want to ensure 100%
portability of your program, you should call poll_mouse() and
poll_keyboard() in all the relevant places.

Allegro defines a number of standard macros that can be used to check
various attributes of the current platform:

ALLEGRO_PLATFORM_STR
Text string containing the name of the current platform.

ALLEGRO_DOS
ALLEGRO_DJGPP
ALLEGRO_WATCOM
ALLEGRO_WINDOWS
ALLEGRO_MSVC
ALLEGRO_MINGW32
ALLEGRO_BCC32
ALLEGRO_UNIX
ALLEGRO_LINUX
ALLEGRO_BEOS
ALLEGRO_QNX
ALLEGRO_DARWIN
ALLEGRO_MACOSX
ALLEGRO_GCC
Defined if you are building for a relevant system. Often several of
these will apply, eg. DOS+Watcom, or Windows+GCC+MinGW32.

ALLEGRO_I386
ALLEGRO_BIG_ENDIAN
ALLEGRO_LITTLE_ENDIAN
Defined if you are building for a processor of the relevant type.

ALLEGRO_MULTITHREADED
Defined if the library is internally multi-threaded on this system.

ALLEGRO_USE_CONSTRUCTOR
Defined if the compiler supports constructor/destructor functions.

ALLEGRO_VRAM_SINGLE_SURFACE
Defined if the screen is a single large surface that is then partitioned
into multiple video sub-bitmaps (eg. DOS), rather than each video bitmap
being a totally unique entity (eg. Windows).

ALLEGRO_CONSOLE_OK
Defined if when you are not in a graphics mode, there is a text mode
console that you can printf() to, and from which the user could
potentially redirect stdout to capture it even while you are in a
graphics mode. If this define is absent, you are running in an
environment like Windows that has no stdout at all.

ALLEGRO_MAGIC_MAIN
Defined if Allegro uses a magic main, i.e takes over the main() entry
point and turns it into a secondary entry point suited to its needs.

ALLEGRO_LFN
Non-zero if long filenames are supported, or zero if you are limited to
8.3 format (in the djgpp version, this is a variable depending on the
runtime environment).

LONG_LONG
Defined to whatever represents a 64-bit "long long" integer for the
current compiler, or not defined if that isn't supported.

OTHER_PATH_SEPARATOR
Defined to a path separator character other than a forward slash for
platforms that use one (eg. a backslash under DOS and Windows), or
defined to a forward slash if there is no other separator character.

DEVICE_SEPARATOR
Defined to the filename device separator character (a colon for DOS and
Windows), or to zero if there are no explicit devices in paths (Unix).

Allegro can be customized at compile time to a certain extent with the
following macros:

ALLEGRO_NO_MAGIC_MAIN
If you define this prior to including Allegro headers, Allegro won't
touch the main() entry point. This effectively removes the requirement
on a program to be linked against the Allegro library when it includes
the allegro.h header file. Note that the configuration and file routines
are not guaranteed to work on Unix systems when this symbol is defined.
Moreover, on Darwin/MacOS X systems, this symbol simply prevents the
program from being linked against the Allegro library! This highly non
portable feature is primarily intended to be used under Windows.

ALLEGRO_USE_CONSOLE
If you define this prior to including Allegro headers, Allegro will be
set up for building a console application rather than the default GUI
program on some platforms (especially Windows).

ALLEGRO_NO_STD_HEADER
If you define this prior to including Allegro headers, Allegro will not
automatically include some standard headers (eg <stddef.h>) its own
headers depend upon.

ALLEGRO_NO_KEY_DEFINES
If you define this prior to including Allegro headers, Allegro will omit
the definition of the KEY_* constants, which may clash with other
headers.

ALLEGRO_NO_FIX_ALIASES
The fixed point functions used to be named with an "f" prefix instead of
"fix", eg. fixsqrt() used to be fsqrt(), but were renamed due to
conflicts with some libc implementations. So backwards compatibility
aliases are provided as static inline functions which map the old names
to the new names, eg. fsqrt() calls fixsqrt(). If you define this
symbol prior to including Allegro headers, the aliases will be turned
off.

ALLEGRO_NO_CLEAR_BITMAP_ALIAS
If you define this prior to including Allegro headers, Allegro will not
define the clear() backwards compatibility alias to clear_bitmap().

ALLEGRO_NO_COMPATIBILITY
If you define this prior to including Allegro headers, Allegro will not
include the backward compatibility layer. It is undefined by default so
old programs can still be compiled with the minimum amount of issues,
but you should define this symbol if you intend to maintain your code
up to date with the latest versions of Allegro. It automatically turns
off all backwards compatibility aliases.

Allegro also defines a number of standard macros that can be used to
insulate you from some of the differences between systems:

INLINE
Use this in place of the regular "inline" function modifier keyword, and
your code will work correctly on any of the supported compilers.

RET_VOLATILE
Use this to declare a function with a volatile return value.

ZERO_SIZE_ARRAY(type, name)
Use this to declare zero-sized arrays in terminal position inside
structures, like in the BITMAP structure. These arrays are effectively
equivalent to the flexible array members of ISO C99.

AL_CONST
Use this in place of the regular "const" object modifier keyword, and
your code will work correctly on any of the supported compilers.

AL_RAND()
On platforms that require it, this macro does a simple shift
transformation of the libc rand() function, in order to improve the
perceived randomness of the output series in the lower 16 bits.  Where
not required, it directly translates into a rand() call.


File: allegro.info,  Node: Reducing,  Next: Debugging,  Prev: Differences,  Up: Top

42 Reducing your executable size
********************************

Some people complain that Allegro produces very large executables. This
is certainly true: with the djgpp version, a simple "hello world"
program will be about 200k, although the per-executable overhead is
much less for platforms that support dynamic linking. But don't worry,
Allegro takes up a relatively fixed amount of space, and won't increase
as your program gets larger. As George Foot so succinctly put it,
anyone who is concerned about the ratio between library and program
code should just get to work and write more program code to catch up :-)

Having said that, there are several things you can do to make your
programs smaller:

   * For all platforms, you can use an executable compressor called
     UPX, which is available at http://upx.sourceforge.net/. This
     usually manages a compression ratio of about 40%.

   * When using djgpp: for starters, read the djgpp FAQ section 8.14,
     and take note of the -s switch. And don't forget to compile your
     program with optimisation enabled!

   * If a DOS program is only going to run in a limited number of
     graphics modes, you can specify which graphics drivers you would
     like to include with the code:

          BEGIN_GFX_DRIVER_LIST
             driver1
             driver2
             etc...
          END_GFX_DRIVER_LIST

     where the driver names are any of the defines:

          GFX_DRIVER_VBEAF
          GFX_DRIVER_VGA
          GFX_DRIVER_MODEX
          GFX_DRIVER_VESA3
          GFX_DRIVER_VESA2L
          GFX_DRIVER_VESA2B
          GFX_DRIVER_XTENDED
          GFX_DRIVER_VESA1

     This construct must be included in only one of your C source
     files. The ordering of the names is important, because the
     autodetection routine works down from the top of the list until it
     finds the first driver that is able to support the requested mode.
     I suggest you stick to the default ordering given above, and
     simply delete whatever entries you aren't going to use.

   * If your DOS program doesn't need to use all the possible color
     depths, you can specify which pixel formats you want to support
     with the code:

          BEGIN_COLOR_DEPTH_LIST
             depth1
             depth2
             etc...
          END_COLOR_DEPTH_LIST

     where the color depth names are any of the defines:

          COLOR_DEPTH_8
          COLOR_DEPTH_15
          COLOR_DEPTH_16
          COLOR_DEPTH_24
          COLOR_DEPTH_32

     Removing any of the color depths will save quite a bit of space,
     with the exception of the 15 and 16-bit modes: these share a great
     deal of code, so if you are including one of them, there is no
     reason not to use both. Be warned that if you try to use a color
     depth which isn't in this list, your program will crash horribly!

   * In the same way as the above, you can specify which DOS sound
     drivers you want to support with the code:

          BEGIN_DIGI_DRIVER_LIST
             driver1
             driver2
             etc...
          END_DIGI_DRIVER_LIST

     using the digital sound driver defines:

          DIGI_DRIVER_SOUNDSCAPE
          DIGI_DRIVER_AUDIODRIVE
          DIGI_DRIVER_WINSOUNDSYS
          DIGI_DRIVER_SB

     and for the MIDI music:

          BEGIN_MIDI_DRIVER_LIST
             driver1
             driver2
             etc...
          END_MIDI_DRIVER_LIST

     using the MIDI driver defines:

          MIDI_DRIVER_AWE32
          MIDI_DRIVER_DIGMID
          MIDI_DRIVER_ADLIB
          MIDI_DRIVER_MPU
          MIDI_DRIVER_SB_OUT

     If you are going to use either of these sound driver constructs,
     you must include both.

   * Likewise for the DOS joystick drivers, you can declare an
     inclusion list:

          BEGIN_JOYSTICK_DRIVER_LIST
             driver1
             driver2
             etc...
          END_JOYSTICK_DRIVER_LIST

     using the joystick driver defines:

          JOYSTICK_DRIVER_WINGWARRIOR
          JOYSTICK_DRIVER_SIDEWINDER
          JOYSTICK_DRIVER_GAMEPAD_PRO
          JOYSTICK_DRIVER_GRIP
          JOYSTICK_DRIVER_STANDARD
          JOYSTICK_DRIVER_SNESPAD
          JOYSTICK_DRIVER_PSXPAD
          JOYSTICK_DRIVER_N64PAD
          JOYSTICK_DRIVER_DB9
          JOYSTICK_DRIVER_TURBOGRAFX
          JOYSTICK_DRIVER_IFSEGA_ISA
          JOYSTICK_DRIVER_IFSEGA_PCI
          JOYSTICK_DRIVER_IFSEGA_PCI_FAST

     The standard driver includes support for the dual joysticks,
     increased numbers of buttons, Flightstick Pro, and Wingman
     Extreme, because these are all quite minor variations on the basic
     code.

   * If you are _really_ serious about this size, thing, have a look at
     the top of include/allegro/alconfig.h and you will see the lines:

          #define ALLEGRO_COLOR8
          #define ALLEGRO_COLOR16
          #define ALLEGRO_COLOR24
          #define ALLEGRO_COLOR32

     If you comment out any of these definitions and then rebuild the
     library, you will get a version without any support for the absent
     color depths, which will be even smaller than using the
     DECLARE_COLOR_DEPTH_LIST() macro.  Removing the ALLEGRO_COLOR16
     define will get rid of the support for both 15 and 16-bit hicolor
     modes, since these share a lot of the same code.

Note: the aforementioned methods for removing unused hardware drivers
only apply to statically linked versions of the library, eg. DOS. On
Windows and Unix platforms, you can build Allegro as a DLL or shared
library, which prevents these methods from working, but saves so much
space that you probably won't care about that. Removing unused color
depths from alconfig.h will work on any platform, though.

If you are distributing a copy of the setup program along with your
game, you may be able to get a dramatic size reduction by merging the
setup code into your main program, so that only one copy of the Allegro
routines will need to be linked. See setup.txt for details. In the
djgpp version, after compressing the executable, this will probably
save you about 200k compared to having two separate programs for the
setup and the game itself.


File: allegro.info,  Node: Debugging,  Next: Makefile,  Prev: Reducing,  Up: Top

43 Debugging
************

There are three versions of the Allegro library: the normal optimised
code, one with extra debugging support, and a profiling version. See
the platform specific readme files for information about how to install
and link with these alternative libs. Although you will obviously want
to use the optimised library for the final version of your program, it
can be very useful to link with the debug lib while you are working on
it, because this will make debugging much easier, and includes assert
tests that will help to locate errors in your code at an earlier stage.
Allegro also contains some debugging helper functions:

* Menu:

* al_assert::
* al_trace::
* ASSERT::
* TRACE::
* register_assert_handler::
* register_trace_handler::


File: allegro.info,  Node: al_assert,  Next: al_trace,  Prev: MIDI_*/MacOSX,  Up: Debugging

43.1 al_assert
==============

void al_assert(const char *file, int line);
     Raises an assert for an error at the specified file and line
     number. The file parameter is always given in ASCII format. If you
     have installed a custom assert handler it uses that, or if the
     environment variable ALLEGRO_ASSERT is set it writes a message
     into the file specified by the environment, otherwise it aborts
     the program with an error message. You will usually want to use
     the ASSERT() macro instead of calling this function directly.

See also:
*Note ASSERT::.
*Note al_trace::.
*Note register_assert_handler::.

File: allegro.info,  Node: al_trace,  Next: ASSERT,  Prev: al_assert,  Up: Debugging

43.2 al_trace
=============

void al_trace(const char *msg, ...);
     Outputs a debugging trace message, using a printf() format string
     given in ASCII. If you have installed a custom trace handler it
     uses that, or if the environment variable ALLEGRO_TRACE is set it
     writes into the file specified by the environment, otherwise it
     writes the message to "allegro.log" in the current directory. You
     will usually want to use the TRACE() macro instead of calling this
     function directly.

See also:
*Note TRACE::.
*Note al_assert::.
*Note register_trace_handler::.

File: allegro.info,  Node: ASSERT,  Next: TRACE,  Prev: al_trace,  Up: Debugging

43.3 ASSERT
===========

void ASSERT(condition);
     Debugging helper macro. Normally compiles away to nothing, but if
     you defined the preprocessor symbol DEBUGMODE before including
     Allegro headers, it will check the supplied condition and call
     al_assert() if it fails.

See also:
*Note al_assert::.
*Note TRACE::.
*Note register_assert_handler::.

File: allegro.info,  Node: TRACE,  Next: register_assert_handler,  Prev: ASSERT,  Up: Debugging

43.4 TRACE
==========

void TRACE(char *msg, ...);
     Debugging helper macro. Normally compiles away to nothing, but if
     you defined the preprocessor symbol DEBUGMODE before including
     Allegro headers, it passes the supplied message given in ASCII
     format to al_trace().

See also:
*Note al_trace::.
*Note ASSERT::.
*Note register_trace_handler::.

File: allegro.info,  Node: register_assert_handler,  Next: register_trace_handler,  Prev: TRACE,  Up: Debugging

43.5 register_assert_handler
============================

void register_assert_handler(int (*handler)(const char *msg));
     Supplies a custom handler function for dealing with assert
     failures. Your callback will be passed a formatted error message
     in ASCII, and should return non-zero if it has processed the
     error, or zero to continue with the default actions. You could use
     this to ignore assert failures, or to display the error messages
     on a graphics mode screen without aborting the program.

See also:
*Note al_assert::.
*Note ASSERT::.
*Note register_trace_handler::.

File: allegro.info,  Node: register_trace_handler,  Next: exhello,  Prev: register_assert_handler,  Up: Debugging

43.6 register_trace_handler
===========================

void register_trace_handler(int (*handler)(const char *msg));
     Supplies a custom handler function for dealing with trace output.
     Your callback will be passed a formatted error message in ASCII,
     and should return non-zero if it has processed the message, or
     zero to continue with the default actions. You could use this to
     ignore trace output, or to display the messages on a second
     monochrome monitor, etc.

See also:
*Note al_trace::.
*Note TRACE::.
*Note register_assert_handler::.

File: allegro.info,  Node: Makefile,  Next: Available,  Prev: Debugging,  Up: Top

44 Makefile targets
*******************

There are a number of options that you can use to control exactly how
Allegro will be compiled. On Unix platforms, you do this by passing
arguments to the configure script (run "configure -help" for a list),
but on other platforms you can set the following environment variables:

   * DEBUGMODE=1
     Selects a debug build, rather than the normal optimised version.

   * DEBUGMODE=2
     Selects a build intended to debug Allegro itself, rather than the
     normal optimised version.

   * PROFILEMODE=1
     Selects a profiling build, rather than the normal optimised
     version.

   * WARNMODE=1
     Selects strict compiler warnings. If you are planning to work on
     Allegro yourself, rather than just using it in your programs, you
     should be sure to have this mode enabled.

   * STATICLINK=1 (MinGW32, MSVC, BeOS, MacOS X only)
     Link as a static library, rather than the default dynamic library.

   * TARGET_ARCH_COMPAT=[cpu] (GCC-based platforms only)
     This option will optimize for the given processor while maintaining
     compatibility with older processors.  Example: set
     TARGET_ARCH_COMPAT=i586

   * TARGET_ARCH_EXCL=[cpu] (GCC-based platforms only)
     This option will optimize for the given processor. Please note that
     using it will cause the code to *NOT* run on older processors.
     Example: set TARGET_ARCH_EXCL=i586

   * TARGET_OPTS=[opts] (GCC-based platforms only)
     This option allows you to customize general compiler optimisations.

   * CROSSCOMPILE=1 (DJGPP, MinGW32 only)
     Allows you to build the library under Linux by using a
     cross-compiler.

   * ALLEGRO_USE_C=1 (GCC-based platforms only)
     Allows you to build the library using C drawing code instead of
     the usual asm routines. This is only really useful for testing,
     since the asm version is faster.

   * UNIX_TOOLS=1
     Instructs the build process to use Unix-like tools instead of DOS
     tools.  Note that you usually don't need to set it because the
     build proces will try to autodetect this configuration.

If you only want to recompile a specific test program or utility, you
can specify it as an argument to make, eg. "make demo" or "make
grabber". The makefiles also provide some special pseudo-targets:

   * 'info' (Unix only)
     Tells you which options this particular build of Allegro will use.
     Especially useful to verify that the required libraries were
     detected and you won't get a 'half-featured' Allegro.

   * 'default'
     The normal build process. Compiles the current library version
     (one of optimised, debugging, or profiling, selected by the above
     environment variables), builds the test and example programs, and
     converts the documentation files.

   * 'all' (non-Unix only)
     Compiles all three library versions (optimised, debugging, and
     profiling), builds the test and example programs, and converts the
     documentation files.

   * 'lib'
     Compiles the current library version (one of optimised, debugging,
     or profiling, selected by the above environment variables).

   * 'install'
     Copies the current library version (one of optimised, debugging, or
     profiling, selected by the above environment variables), into your
     compiler lib directory, recompiling it as required, and installs
     the Allegro headers.

   * 'installall' (non-Unix only)
     Copies all three library versions (optimised, debugging, and
     profiling), into your compiler lib directory, recompiling them as
     required, and installs the Allegro headers.

   * 'uninstall'
     Removes the Allegro library and headers from your compiler
     directories.

   * 'docs'
     Converts the documentation files from the ._tx sources.

   * 'chm-docs' (Windows only)
     Creates a compiled HTML file from the previously generated html
     output.  This is not a default target, since you need Microsoft's
     HTML compiler (http://go.microsoft.com/fwlink/?LinkId=14188), and
     it has to be installed somewhere in your PATH. Also, this only
     works if you use '@multiplefiles' (see the top of
     docs/src/allegro._tx).

   * 'docs-dvi' (Unix only)
     Creates the allegro.dvi device independent documentation file.
     This is not a default target, since you need the texi2dvi tool to
     create it. The generated file is especially prepared to be printed
     on paper.

   * 'docs-ps' or 'docs-gzipped-ps' or 'docs-bzipped-ps' (Unix only)
     Creates a Postcript file from the previously generated DVI file.
     This is not a default target, since you need the texi2dvi and
     dvips tools to create it. The second and third targets compress
     the generated Postscript file. The generated file is especially
     prepared to be printed on paper.

   * 'docs-pdf' (Unix only)
     Creates a PDF file. This is not a default target, since you need
     the texi2pdf tool to create it. The generated file is especially
     prepared to be printed on paper, and it also has hyperlinks.

   * 'docs-devhelp' (Unix only)
     Creates normal HTML documentation with an additional xml index
     file which can be used by tools like Devhelp
     (http://www.devhelp.net/) to show context sensitive help within
     any editor using Devhelp, like for example
     http://anjuta.sourceforge.net/. The Allegro 'book' will be created
     in docs/devhelp/allegro.devhelp, you have to install it manually.

   * 'install-man' (Unix and Mac OS X only)
     Generates Unix man pages for each Allegro function or variable and
     installs them.

   * 'install-gzipped-man' or 'install-bzipped-man' (Unix only)
     Like install-man, but also compresses the manual pages after
     installing them (run only one of these).

   * 'uninstall-man' (Unix)
     Uninstalls any man pages previously installed with 'install-man',
     'install-gzipped-man', or 'install-bzipped-man'.

   * 'install-info' or 'install-gzipped-info' or 'install-bzipped-info'
     (Unix only)
     Converts the documentation to Info format and installs it. The
     second and third targets compress the info file after installing
     it (run only one of them).

   * 'uninstall-info' (Unix only)
     Uninstalls any man pages previously installed with 'install-info',
     'install-gzipped-info', or 'install-bzipped-info'.

   * 'clean'
     Removes generated object and library files, either to recover disk
     space or to force a complete rebuild the next time you run make.
     This target is designed so that if you run a "make install"
     followed by "make clean", you will still have a functional version
     of Allegro.

   * 'distclean'
     Like "make clean", but more so. This removes all the executable
     files and the documentation, leaving you with only the same files
     that are included when you unzip a new Allegro distribution.

   * 'veryclean'
     Use with extreme caution! This target deletes absolutely all
     generated files, including some that may be non-trivial to
     recreate. After you run "make veryclean", a simple rebuild will
     not work: at the very least you will have to run "make depend",
     and perhaps also fixdll.bat if you are using the Windows library.
     These targets make use of non-standard tools like SED, so unless
     you know what you are doing and have all this stuff installed, you
     should not use them.

   * 'compress' (DJGPP, Mingw32 and MSVC only)
     Uses the DJP or UPX executable compressors (whichever you have
     installed) to compress the example executables and utility
     programs, which can recover a significant amount of disk space.

   * 'depend'
     Regenerates the dependency files (obj/*/makefile.dep). You need to
     run this after "make veryclean", or whenever you add new headers
     to the Allegro sources.


File: allegro.info,  Node: Available,  Next: Conclusion,  Prev: Makefile,  Up: Top

45 Available Allegro examples
*****************************

With Allegro comes quite a bunch of examples, which go from the simple
introductory `Hello world' to more complicated programs featuring
truecolor blending effects. This chapter describes these examples which
you can find in the allegro/examples folder. You don't have to go
through them in the same order as this documentation, but doing so you
will learn the basic functions and avoid missing any important bit of
information.

* Menu:

* exhello::
* exmem::
* expal::
* expat::
* exflame::
* exdbuf::
* exflip::
* exfixed::
* exmouse::
* extimer::
* exkeys::
* exjoy::
* exsample::
* exmidi::
* exgui::
* excustom::
* exunicod::
* exconfig::
* exbitmap::
* exscale::
* exdata::
* exsprite::
* exexedat::
* extrans::
* extruec::
* excolmap::
* exrgbhsv::
* exshade::
* exxfade::
* exblend::
* exalpha::
* exlights::
* ex3d::
* excamera::
* exquat::
* exstars::
* exscn3d::
* exzbuf::
* exscroll::
* ex3buf::
* ex12bit::
* exaccel::
* exspline::
* exupdate::
* exswitch::
* exdodgy::
* exstream::


File: allegro.info,  Node: exhello,  Next: exmem,  Prev: register_trace_handler,  Up: Available

45.1 exhello
============

Example exhello
     This is a very simple program showing how to get into graphics
     mode and draw text onto the screen.

See also:
*Note END_OF_MAIN::.
*Note acquire_screen::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_to_color::.
*Note desktop_palette::.
*Note font::.
*Note install_keyboard::.
*Note makecol::.
*Note readkey::.
*Note release_screen::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.

File: allegro.info,  Node: exmem,  Next: expal,  Prev: exhello,  Up: Available

45.2 exmem
==========

Example exmem
     This program demonstrates the use of memory bitmaps. It creates a
     small temporary bitmap in memory, draws some circles onto it, and
     then blits lots of copies of it onto the screen.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note acquire_screen::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note circle::.
*Note clear_bitmap::.
*Note create_bitmap::.
*Note desktop_palette::.
*Note destroy_bitmap::.
*Note install_keyboard::.
*Note palette_color::.
*Note readkey::.
*Note release_screen::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.

File: allegro.info,  Node: expal,  Next: expat,  Prev: exmem,  Up: Available

45.3 expal
==========

Example expal
     This program demonstrates how to manipulate the palette. It draws
     a set of concentric circles onto the screen and animates them by
     cycling the palette.

See also:
*Note END_OF_MAIN::.
*Note PALETTE::.
*Note RGB::.
*Note acquire_screen::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note black_palette::.
*Note circlefill::.
*Note install_keyboard::.
*Note keypressed::.
*Note release_screen::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.

File: allegro.info,  Node: expat,  Next: exflame,  Prev: expal,  Up: Available

45.4 expat
==========

Example expat
     This program demonstrates the use of patterned drawing and
     sub-bitmaps.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note acquire_bitmap::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note bitmap_mask_color::.
*Note clear_to_color::.
*Note create_bitmap::.
*Note create_sub_bitmap::.
*Note desktop_palette::.
*Note destroy_bitmap::.
*Note drawing_mode::.
*Note font::.
*Note install_keyboard::.
*Note makecol::.
*Note palette_color::.
*Note readkey::.
*Note rectfill::.
*Note release_bitmap::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note solid_mode::.
*Note text_height::.
*Note text_length::.

File: allegro.info,  Node: exflame,  Next: exdbuf,  Prev: expat,  Up: Available

45.5 exflame
============

Example exflame
     This program demonstrates how to write directly to video memory.
     It implements a simple fire effect, first by calling getpixel() and
     putpixel(), then by accessing video memory directly a byte at a
     time, and finally using block memory copy operations.

See also:
*Note END_OF_MAIN::.
*Note PALETTE::.
*Note acquire_screen::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_keybuf::.
*Note font::.
*Note getpixel::.
*Note install_keyboard::.
*Note keypressed::.
*Note line::.
*Note makecol::.
*Note putpixel::.
*Note release_screen::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.

File: allegro.info,  Node: exdbuf,  Next: exflip,  Prev: exflame,  Up: Available

45.6 exdbuf
===========

Example exdbuf
     This program demonstrates the use of double buffering.  It moves a
     circle across the screen, first just erasing and redrawing
     directly to the screen, then with a double buffer.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note acquire_screen::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note circlefill::.
*Note clear_to_color::.
*Note create_bitmap::.
*Note desktop_palette::.
*Note destroy_bitmap::.
*Note font::.
*Note install_timer::.
*Note makecol::.
*Note release_screen::.
*Note retrace_count::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.

File: allegro.info,  Node: exflip,  Next: exfixed,  Prev: exdbuf,  Up: Available

45.7 exflip
===========

Example exflip
     This program moves a circle across the screen, first with a double
     buffer and then using page flips.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note circlefill::.
*Note clear_to_color::.
*Note create_bitmap::.
*Note create_video_bitmap::.
*Note desktop_palette::.
*Note destroy_bitmap::.
*Note font::.
*Note install_timer::.
*Note makecol::.
*Note retrace_count::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note show_video_bitmap::.

File: allegro.info,  Node: exfixed,  Next: exmouse,  Prev: exflip,  Up: Available

45.8 exfixed
============

Example exfixed
     This program demonstrates how to use fixed point numbers.

See also:
*Note END_OF_MAIN::.
*Note allegro_init::.
*Note allegro_message::.
*Note fixdiv::.
*Note fixed::.
*Note fixmul::.
*Note fixsqrt::.
*Note fixtof::.
*Note ftofix::.
*Note itofix::.

File: allegro.info,  Node: exmouse,  Next: extimer,  Prev: exfixed,  Up: Available

45.9 exmouse
============

Example exmouse
     This program demonstrates how to get mouse input.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note acquire_screen::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note bitmap_mask_color::.
*Note circle::.
*Note clear_keybuf::.
*Note clear_to_color::.
*Note create_bitmap::.
*Note desktop_palette::.
*Note destroy_bitmap::.
*Note font::.
*Note get_mouse_mickeys::.
*Note install_keyboard::.
*Note install_mouse::.
*Note install_timer::.
*Note key::.
*Note keypressed::.
*Note makecol::.
*Note mouse_b: mouse_x.
*Note mouse_x::.
*Note mouse_y: mouse_x.
*Note mouse_z: mouse_x.
*Note palette_color::.
*Note poll_mouse::.
*Note readkey::.
*Note release_screen::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_mouse_sprite::.
*Note set_mouse_sprite_focus::.
*Note set_palette::.
*Note show_mouse::.
*Note vsync::.

File: allegro.info,  Node: extimer,  Next: exkeys,  Prev: exmouse,  Up: Available

45.10 extimer
=============

Example extimer
     This program demonstrates how to use the timer routines.  These
     can be a bit of a pain, because you have to be sure you lock all
     the memory that is used inside your interrupt handlers.

See also:
*Note END_OF_MAIN::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_to_color::.
*Note desktop_palette::.
*Note font::.
*Note install_int::.
*Note install_int_ex::.
*Note install_keyboard::.
*Note install_timer::.
*Note key::.
*Note keypressed::.
*Note makecol::.
*Note readkey::.
*Note rest::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.

File: allegro.info,  Node: exkeys,  Next: exjoy,  Prev: extimer,  Up: Available

45.11 exkeys
============

Example exkeys
     This program demonstrates how to access the keyboard.

See also:
*Note END_OF_MAIN::.
*Note acquire_screen::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_keybuf::.
*Note clear_to_color::.
*Note desktop_palette::.
*Note font::.
*Note install_keyboard::.
*Note key::.
*Note key_shifts::.
*Note makecol::.
*Note readkey::.
*Note rectfill::.
*Note release_screen::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note ureadkey::.
*Note usprintf::.

File: allegro.info,  Node: exjoy,  Next: exsample,  Prev: exkeys,  Up: Available

45.12 exjoy
===========

Example exjoy
     This program uses the Allegro library to detect and read the value
     of a joystick. The output of the program is a small target sight
     on the screen which you can move. At the same time the program will
     tell you what you are doing with the joystick (moving or firing).

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note calibrate_joystick::.
*Note calibrate_joystick_name::.
*Note circle::.
*Note clear_bitmap::.
*Note clear_keybuf::.
*Note create_bitmap::.
*Note default_palette::.
*Note destroy_bitmap::.
*Note drawing_mode::.
*Note font::.
*Note install_joystick::.
*Note install_keyboard::.
*Note joy::.
*Note key::.
*Note keypressed::.
*Note num_joysticks::.
*Note palette_color::.
*Note poll_joystick::.
*Note putpixel::.
*Note readkey::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.

File: allegro.info,  Node: exsample,  Next: exmidi,  Prev: exjoy,  Up: Available

45.13 exsample
==============

Example exsample
     This program demonstrates how to play samples.

See also:
*Note END_OF_MAIN::.
*Note SAMPLE::.
*Note adjust_sample::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_to_color::.
*Note desktop_palette::.
*Note destroy_sample::.
*Note font::.
*Note install_keyboard::.
*Note install_sound::.
*Note install_timer::.
*Note key::.
*Note load_sample::.
*Note makecol::.
*Note play_sample::.
*Note poll_keyboard::.
*Note rest::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.

File: allegro.info,  Node: exmidi,  Next: exgui,  Prev: exsample,  Up: Available

45.14 exmidi
============

Example exmidi
     This program demonstrates how to play MIDI files.

See also:
*Note END_OF_MAIN::.
*Note MIDI::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_to_color::.
*Note desktop_palette::.
*Note destroy_midi::.
*Note font::.
*Note install_keyboard::.
*Note install_sound::.
*Note install_timer::.
*Note load_midi::.
*Note makecol::.
*Note play_midi::.
*Note readkey::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.

File: allegro.info,  Node: exgui,  Next: excustom,  Prev: exmidi,  Up: Available

45.15 exgui
===========

Example exgui
     This program demonstrates how to use the GUI routines.

See also:
*Note DATAFILE::.
*Note DIALOG::.
*Note END_OF_MAIN::.
*Note MENU::.
*Note active_menu::.
*Note alert::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note d_bitmap_proc::.
*Note d_box_proc::.
*Note d_button_proc::.
*Note d_check_proc::.
*Note d_clear_proc::.
*Note d_ctext_proc: d_text_proc.
*Note d_edit_proc::.
*Note d_icon_proc::.
*Note d_keyboard_proc::.
*Note d_list_proc::.
*Note d_menu_proc::.
*Note d_radio_proc::.
*Note d_rtext_proc: d_text_proc.
*Note d_shadow_box_proc: d_box_proc.
*Note d_slider_proc::.
*Note d_text_list_proc::.
*Note d_text_proc::.
*Note d_textbox_proc::.
*Note d_yield_proc::.
*Note do_dialog::.
*Note gui_bg_color: gui_fg_color.
*Note gui_fg_color::.
*Note gui_mg_color::.
*Note install_keyboard::.
*Note install_mouse::.
*Note install_timer::.
*Note key::.
*Note load_datafile::.
*Note makecol::.
*Note position_dialog::.
*Note screen::.
*Note set_dialog_color::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note unload_datafile::.
*Note ustrtok::.
*Note ustrzcat::.
*Note ustrzcpy::.
*Note uszprintf::.

File: allegro.info,  Node: excustom,  Next: exunicod,  Prev: exgui,  Up: Available

45.16 excustom
==============

Example excustom
     This program demonstrates how to write your own GUI objects.

See also:
*Note BITMAP::.
*Note DATAFILE::.
*Note DIALOG::.
*Note END_OF_MAIN::.
*Note FONT::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note circle::.
*Note circlefill::.
*Note clear_to_color::.
*Note create_bitmap::.
*Note d_button_proc::.
*Note d_check_proc::.
*Note d_clear_proc::.
*Note d_edit_proc::.
*Note desktop_palette::.
*Note destroy_bitmap::.
*Note do_dialog::.
*Note fixcos::.
*Note fixed::.
*Note fixmul::.
*Note fixsin::.
*Note fixtoi::.
*Note font::.
*Note install_keyboard::.
*Note install_mouse::.
*Note install_timer::.
*Note itofix::.
*Note key::.
*Note line::.
*Note load_datafile::.
*Note makecol::.
*Note object_message::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note unload_datafile::.

File: allegro.info,  Node: exunicod,  Next: exconfig,  Prev: excustom,  Up: Available

45.17 exunicod
==============

Example exunicod
     This program demonstrates the use of the 16-bit Unicode text
     encoding format with Allegro.

See also:
*Note BITMAP::.
*Note DATAFILE::.
*Note END_OF_MAIN::.
*Note FONT::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_to_color::.
*Note create_system_bitmap::.
*Note destroy_bitmap::.
*Note font::.
*Note install_keyboard::.
*Note install_timer::.
*Note keypressed::.
*Note load_datafile::.
*Note makecol::.
*Note rest::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_uformat::.
*Note set_window_title::.
*Note text_height::.
*Note text_length::.
*Note uconvert_ascii::.
*Note unload_datafile::.
*Note ustrcat::.
*Note ustrcpy::.
*Note ustrsize::.
*Note ustrsizez::.

File: allegro.info,  Node: exconfig,  Next: exbitmap,  Prev: exunicod,  Up: Available

45.18 exconfig
==============

Example exconfig
     This is a very simple program showing how to use the allegro
     config (ini file) routines.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note RGB::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_bitmap::.
*Note font::.
*Note get_config_argv::.
*Note get_config_int::.
*Note install_keyboard::.
*Note line::.
*Note load_bitmap::.
*Note makecol::.
*Note pop_config_state::.
*Note push_config_state::.
*Note readkey::.
*Note screen::.
*Note set_color_depth::.
*Note set_config_file::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note ustrdup::.
*Note ustricmp::.

File: allegro.info,  Node: exbitmap,  Next: exscale,  Prev: exconfig,  Up: Available

45.19 exbitmap
==============

Example exbitmap
     This program demonstrates how to load and display a bitmap file.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note PALETTE::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note destroy_bitmap::.
*Note install_keyboard::.
*Note load_bitmap::.
*Note readkey::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.

File: allegro.info,  Node: exscale,  Next: exdata,  Prev: exbitmap,  Up: Available

45.20 exscale
=============

Example exscale
     This example demonstrates how to use pcx files, palettes and
     stretch blits. It loads a pcx file, sets its palette and does some
     random stretch_blits. Don't worry - it's VERY slowed down using
     vsync().

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note PALETTE::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note destroy_bitmap::.
*Note install_keyboard::.
*Note keypressed::.
*Note load_pcx::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note vsync::.

File: allegro.info,  Node: exdata,  Next: exsprite,  Prev: exscale,  Up: Available

45.21 exdata
============

Example exdata
     This program demonstrates how to access the contents of an Allegro
     datafile (created by the grabber utility).

See also:
*Note DATAFILE::.
*Note END_OF_MAIN::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note font::.
*Note install_keyboard::.
*Note load_datafile::.
*Note makecol::.
*Note readkey::.
*Note screen::.
*Note set_color_conversion::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note unload_datafile::.

File: allegro.info,  Node: exsprite,  Next: exexedat,  Prev: exdata,  Up: Available

45.22 exsprite
==============

Example exsprite
     This example demonstrates how to use datafiles, various sprite
     drawing routines and flicker-free animation.

     A short explanation for beginners.  Why did I do animate ()
     routine in that way?  As you probably know, VIDEO RAM is much
     slower than "normal" RAM, so it's advisable to reduce VRAM blits
     to a minimum.  So, drawing sprite on the screen (I mean in VRAM)
     and then clearing a background for him is not very fast. I've used
     a different method which is much faster, but require a bit more
     memory.  I clear a buffer (it's a normal BITMAP), then I draw
     sprite to it, and after all I blit only one time this buffer to
     the screen. So, I'm using a single VRAM blit instead of
     blitting/clearing background and drawing a sprite on it. It's a
     good method even when I have to restore.  background And of
     course, it completely remove flickering effect.  When one uses a
     big (ie. 800x600 background) and draws something on it, it's wise
     to use a copy of background somewhere in memory and restore
     background using this "virtual background". When blitting from
     VRAM in SVGA modes, it's probably, that drawing routines have to
     switch banks on video card. I think, I don't have to remind how
     slow is it.

See also:
*Note BITMAP::.
*Note DATAFILE::.
*Note END_OF_MAIN::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_bitmap::.
*Note clear_keybuf::.
*Note create_bitmap::.
*Note destroy_bitmap::.
*Note draw_sprite::.
*Note draw_sprite_h_flip: draw_sprite_v_flip.
*Note draw_sprite_v_flip::.
*Note draw_sprite_vh_flip: draw_sprite_v_flip.
*Note fixed::.
*Note font::.
*Note install_keyboard::.
*Note itofix::.
*Note key::.
*Note keypressed::.
*Note load_datafile::.
*Note palette_color::.
*Note rectfill::.
*Note rotate_sprite::.
*Note rotate_sprite_v_flip::.
*Note screen::.
*Note set_color_conversion::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note unload_datafile::.
*Note vsync::.

File: allegro.info,  Node: exexedat,  Next: extrans,  Prev: exsprite,  Up: Available

45.23 exexedat
==============

Example exexedat
     This program demonstrates how to access the contents of an Allegro
     datafile (created by the grabber utility) linked to the exe by the
     exedat tool. It is based on the exdata example.

     You may ask: how do you compile, append and exec your program?

     Answer: like this...

     1) Compile your program like normal. Use the magic filenames with
     '#' to load your data where needed.

     2) Once you compressed your program, run "exedat foo.exe data.dat"

     3) Finally run your program.

See also:
*Note DATAFILE::.
*Note END_OF_MAIN::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note font::.
*Note install_keyboard::.
*Note line::.
*Note load_datafile::.
*Note makecol::.
*Note readkey::.
*Note screen::.
*Note set_color_conversion::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note unload_datafile::.

File: allegro.info,  Node: extrans,  Next: extruec,  Prev: exexedat,  Up: Available

45.24 extrans
=============

Example extrans
     This program demonstrates how to use the lighting and translucency
     functions.

See also:
*Note BITMAP::.
*Note COLOR_MAP::.
*Note END_OF_MAIN::.
*Note PALETTE::.
*Note RGB::.
*Note RGB_MAP::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note bitmap_color_depth::.
*Note circlefill::.
*Note clear_bitmap::.
*Note clear_keybuf::.
*Note color_map::.
*Note create_bitmap::.
*Note create_bitmap_ex::.
*Note destroy_bitmap::.
*Note draw_trans_sprite::.
*Note drawing_mode::.
*Note install_keyboard::.
*Note install_mouse::.
*Note install_timer::.
*Note keypressed::.
*Note load_bitmap::.
*Note mouse_x::.
*Note mouse_y: mouse_x.
*Note poll_mouse::.
*Note rectfill::.
*Note rgb_map::.
*Note screen::.
*Note set_alpha_blender::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note set_trans_blender::.
*Note set_write_alpha_blender::.

File: allegro.info,  Node: extruec,  Next: excolmap,  Prev: extrans,  Up: Available

45.25 extruec
=============

Example extruec
     This program shows how to specify colors in the various different
     truecolor pixel formats.

See also:
*Note END_OF_MAIN::.
*Note PALETTE::.
*Note RGB::.
*Note acquire_screen::.
*Note allegro_init::.
*Note clear_to_color::.
*Note font::.
*Note generate_332_palette::.
*Note install_keyboard::.
*Note key::.
*Note makecol::.
*Note readkey::.
*Note release_screen::.
*Note screen::.
*Note set_color_depth::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note vline::.

File: allegro.info,  Node: excolmap,  Next: exrgbhsv,  Prev: extruec,  Up: Available

45.26 excolmap
==============

Example excolmap
     This program demonstrates how to create custom graphic effects with
     the create_color_table function, this time a greyscale effect.

See also:
*Note BITMAP::.
*Note COLOR_MAP::.
*Note END_OF_MAIN::.
*Note PALETTE::.
*Note RGB::.
*Note RGB_MAP::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note circlefill::.
*Note clear_keybuf::.
*Note color_map::.
*Note create_bitmap::.
*Note destroy_bitmap::.
*Note drawing_mode::.
*Note font::.
*Note generate_332_palette::.
*Note install_keyboard::.
*Note keypressed::.
*Note makecol::.
*Note rectfill::.
*Note rgb_map::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note vsync::.

File: allegro.info,  Node: exrgbhsv,  Next: exshade,  Prev: excolmap,  Up: Available

45.27 exrgbhsv
==============

Example exrgbhsv
     This program shows how to convert colors between the different
     color-space representations.

See also:
*Note BITMAP::.
*Note DIALOG::.
*Note END_OF_MAIN::.
*Note PALETTE::.
*Note RGB::.
*Note RGB_MAP::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_to_color::.
*Note create_bitmap_ex::.
*Note d_bitmap_proc::.
*Note d_box_proc::.
*Note d_slider_proc::.
*Note d_text_proc::.
*Note do_dialog::.
*Note font::.
*Note generate_332_palette::.
*Note get_color_depth::.
*Note hsv_to_rgb::.
*Note install_keyboard::.
*Note install_mouse::.
*Note install_timer::.
*Note key::.
*Note makecol::.
*Note makecol32: makecol8.
*Note makecol8::.
*Note object_message::.
*Note rgb_map::.
*Note rgb_to_hsv: hsv_to_rgb.
*Note screen::.
*Note set_color::.
*Note set_color_depth::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note vline::.
*Note vsync::.

File: allegro.info,  Node: exshade,  Next: exxfade,  Prev: exrgbhsv,  Up: Available

45.28 exshade
=============

Example exshade
     This program demonstrates how to draw gouraud shaded (lit) sprites.

See also:
*Note BITMAP::.
*Note COLOR_MAP::.
*Note END_OF_MAIN::.
*Note PALETTE::.
*Note RGB::.
*Note RGB_MAP::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_bitmap::.
*Note color_map::.
*Note create_bitmap::.
*Note destroy_bitmap::.
*Note font::.
*Note install_keyboard::.
*Note install_mouse::.
*Note keypressed::.
*Note load_bitmap::.
*Note mouse_x::.
*Note mouse_y: mouse_x.
*Note palette_color::.
*Note poll_mouse::.
*Note rgb_map::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note set_trans_blender::.
*Note show_mouse::.

File: allegro.info,  Node: exxfade,  Next: exblend,  Prev: exshade,  Up: Available

45.29 exxfade
=============

Example exxfade
     This program demonstrates how to load and display bitmap files in
     truecolor video modes, and how to crossfade between them.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note PALETTE::.
*Note allegro_error::.
*Note allegro_exit::.
*Note allegro_init::.
*Note allegro_message::.
*Note create_bitmap::.
*Note destroy_bitmap::.
*Note draw_trans_sprite::.
*Note install_keyboard::.
*Note keypressed::.
*Note line::.
*Note load_bitmap::.
*Note readkey::.
*Note screen::.
*Note set_color_conversion::.
*Note set_color_depth::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note set_trans_blender::.
*Note vsync::.

File: allegro.info,  Node: exblend,  Next: exalpha,  Prev: exxfade,  Up: Available

45.30 exblend
=============

Example exblend
     This program demonstrates how to use the translucency functions in
     truecolor video modes.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note PALETTE::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note circle::.
*Note clear_bitmap::.
*Note clear_keybuf::.
*Note create_bitmap::.
*Note destroy_bitmap::.
*Note draw_lit_sprite::.
*Note draw_trans_sprite::.
*Note fixcos::.
*Note fixsin::.
*Note fixtoi::.
*Note font::.
*Note install_keyboard::.
*Note install_timer::.
*Note itofix::.
*Note keypressed::.
*Note load_bitmap::.
*Note makecol::.
*Note retrace_count::.
*Note screen::.
*Note set_color_conversion::.
*Note set_color_depth::.
*Note set_gfx_mode::.
*Note set_trans_blender::.
*Note vsync::.

File: allegro.info,  Node: exalpha,  Next: exlights,  Prev: exblend,  Up: Available

45.31 exalpha
=============

Example exalpha
     This program demonstrates how to use the 32-bit RGBA translucency
     functions to store an alpha channel along with a bitmap graphic.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_keybuf::.
*Note create_bitmap::.
*Note destroy_bitmap::.
*Note draw_trans_sprite::.
*Note drawing_mode::.
*Note font::.
*Note getb: getr.
*Note getg: getr.
*Note getpixel::.
*Note getr::.
*Note install_keyboard::.
*Note install_mouse::.
*Note install_timer::.
*Note keypressed::.
*Note load_bitmap::.
*Note makecol::.
*Note mouse_x::.
*Note mouse_y: mouse_x.
*Note putpixel::.
*Note rectfill::.
*Note screen::.
*Note set_alpha_blender::.
*Note set_color_conversion::.
*Note set_color_depth::.
*Note set_gfx_mode::.
*Note set_multiply_blender::.
*Note set_write_alpha_blender::.
*Note solid_mode::.

File: allegro.info,  Node: exlights,  Next: ex3d,  Prev: exalpha,  Up: Available

45.32 exlights
==============

Example exlights
     This program shows one way to implement colored lighting effects
     in a hicolor video mode. Warning: it is not for the faint of heart!
     This is by no means the simplest or easiest to understand method,
     I just thought it was a cool concept that would be worth
     demonstrating.

     The basic approach is to select a 15 or 16-bit screen mode, but
     then draw onto 24-bit memory bitmaps. Since we only need the bottom
     5 bits of each 8-bit color in order to store 15-bit data within a
     24-bit location, we can fit a light level into the top 3 bits.
     The tricky bit is that these aren't actually 24-bit images at all:
     they are implemented as 8-bit memory bitmaps, and we just store the
     red level in one pixel, green in the next, and blue in the next,
     making the total image be three times wider than we really wanted.
     This allows us to use all the normal 256-color graphics routines
     for drawing onto our memory surfaces, most importantly the lookup
     table translucency, which can be used to combine the low 5 bits of
     color and the top 3 bits of light in a single drawing operation.
     Some trickery is needed to load 24-bit data into this fake 8-bit
     format, and of course it needs a custom routine to convert the
     resulting image while copying it across to the hardware screen.

     This program chugs slightly on my p133, but not significantly
     worse than any double buffering in what amounts to a 1920x640,
     256-color resolution. The light blending doesn't seem to slow it
     down too badly, so I think this technique would be quite usable on
     faster machines and in lower resolution hicolor modes. The biggest
     problem is that although you keep the full 15-bit color
     resolution, you only get 3 bits of light, ie. 8 light levels.  You
     can do some nice colored light patches, but smooth gradients
     aren't going to work too well :-)

See also:
*Note BITMAP::.
*Note COLOR_MAP::.
*Note END_OF_MAIN::.
*Note PALETTE::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note bitmap_color_depth::.
*Note circlefill::.
*Note clear_bitmap::.
*Note clear_keybuf::.
*Note color_map::.
*Note create_bitmap_ex::.
*Note destroy_bitmap::.
*Note draw_trans_sprite::.
*Note fixatan2::.
*Note fixsqrt::.
*Note fixtoi::.
*Note getb_depth: getr_depth.
*Note getg_depth: getr_depth.
*Note getpixel::.
*Note getr_depth::.
*Note hsv_to_rgb::.
*Note install_keyboard::.
*Note install_mouse::.
*Note install_timer::.
*Note itofix::.
*Note key::.
*Note keypressed::.
*Note line::.
*Note load_bitmap::.
*Note makecol::.
*Note mouse_x::.
*Note mouse_y: mouse_x.
*Note poll_mouse::.
*Note retrace_count::.
*Note screen::.
*Note select_palette::.
*Note set_color_conversion::.
*Note set_color_depth::.
*Note set_gfx_mode::.

File: allegro.info,  Node: ex3d,  Next: excamera,  Prev: exlights,  Up: Available

45.33 ex3d
==========

Example ex3d
     This program demonstrates how to use the 3d matrix functions.  It
     isn't a very elegant or efficient piece of code, but it does show
     the stuff in action. I'll leave it to you to design a proper model
     structure and rendering pipeline: after all, the best way to do
     that sort of stuff varies hugely from one game to another.

See also:
*Note BITMAP::.
*Note COLOR_MAP::.
*Note END_OF_MAIN::.
*Note MATRIX::.
*Note PALETTE::.
*Note RGB::.
*Note RGB_MAP::.
*Note V3D::.
*Note allegro_error::.
*Note allegro_exit::.
*Note allegro_init::.
*Note allegro_message::.
*Note apply_matrix::.
*Note bitmap_color_depth::.
*Note bitmap_mask_color::.
*Note clear_bitmap::.
*Note clear_to_color::.
*Note color_map::.
*Note create_bitmap::.
*Note desktop_palette::.
*Note destroy_bitmap::.
*Note fixed::.
*Note fixtoi::.
*Note font::.
*Note gfx_mode_select_ex::.
*Note install_keyboard::.
*Note install_mouse::.
*Note install_timer::.
*Note itofix::.
*Note key::.
*Note keypressed::.
*Note line::.
*Note palette_color::.
*Note persp_project::.
*Note polygon_z_normal::.
*Note quad3d::.
*Note readkey::.
*Note rect::.
*Note retrace_count::.
*Note rgb_map::.
*Note screen::.
*Note set_color_depth::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note set_projection_viewport::.
*Note set_trans_blender::.
*Note vsync::.

File: allegro.info,  Node: excamera,  Next: exquat,  Prev: ex3d,  Up: Available

45.34 excamera
==============

Example excamera
     This program demonstrates how to use the get_camera_matrix()
     function to view a 3d world from any position and angle.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note MATRIX_f::.
*Note V3D_f::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note apply_matrix_f: apply_matrix.
*Note clear_to_color::.
*Note create_bitmap::.
*Note desktop_palette::.
*Note destroy_bitmap::.
*Note font::.
*Note get_vector_rotation_matrix_f: get_vector_rotation_matrix.
*Note install_keyboard::.
*Note key::.
*Note key_shifts::.
*Note makecol::.
*Note persp_project_f: persp_project.
*Note poll_keyboard::.
*Note polygon::.
*Note polygon3d_f: polygon3d.
*Note rect::.
*Note screen::.
*Note set_clip::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note set_projection_viewport::.
*Note vsync::.

File: allegro.info,  Node: exquat,  Next: exstars,  Prev: excamera,  Up: Available

45.35 exquat
============

Example exquat
     A Comparison Between Euler Angles and Quaternions.

     Euler angles are convenient for storing and creating 3D
     orientations.  However, this program demonstrates that they are
     not good when interpolating between two different orientations.
     The problem is solved by using Allegro's quaternion operations.

     In this program, two cubes are rotated between random orientations.
     Notice that although they are have the same beginning and ending
     orientations, they do not follow the same path between
     orientations.

     One cube is being rotated by directly incrementing or decrementing
     the Euler angles from the starting point to the ending point.
     This is an intuitive notion, but it is incorrect because it does
     not cause the object to turn around a single unchanging axis of
     rotation.  The axis of rotation wobbles resulting in the object
     spinning in strange ways. The object will eventually end up in the
     orientation that the user intended, but it gets there in a way
     that is unattractive.  Imagine if this method was used to update
     the position of a camera in a game! Sometimes it would swing
     wildly and disorient the player.

     The other cube is animated using quaternions. This results in a
     much more pleasing animation because the cube turns around a
     single axis of rotation.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note MATRIX_f::.
*Note QUAT::.
*Note acquire_bitmap::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note apply_matrix_f: apply_matrix.
*Note circle::.
*Note clear_to_color::.
*Note create_bitmap::.
*Note desktop_palette::.
*Note destroy_bitmap::.
*Note font::.
*Note get_rotation_matrix::.
*Note get_rotation_matrix_f: get_rotation_matrix.
*Note get_rotation_quat::.
*Note install_keyboard::.
*Note line::.
*Note matrix_mul_f: matrix_mul.
*Note palette_color::.
*Note persp_project_f: persp_project.
*Note quat_interpolate::.
*Note quat_to_matrix::.
*Note readkey::.
*Note release_bitmap::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note set_projection_viewport::.
*Note vsync::.

File: allegro.info,  Node: exstars,  Next: exscn3d,  Prev: exquat,  Up: Available

45.36 exstars
=============

Example exstars
     This program draws a 3D starfield (depth-cued) and a polygon
     starship (controllable), using the Allegro math functions.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note MATRIX::.
*Note PALETTE::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note apply_matrix::.
*Note clear_bitmap::.
*Note create_bitmap::.
*Note cross_product::.
*Note destroy_bitmap::.
*Note dot_product::.
*Note fixed::.
*Note fixmul::.
*Note fixtof::.
*Note fixtoi::.
*Note font::.
*Note get_rotation_matrix::.
*Note get_translation_matrix::.
*Note install_keyboard::.
*Note install_timer::.
*Note itofix::.
*Note key::.
*Note normalize_vector::.
*Note palette_color::.
*Note persp_project::.
*Note poll_keyboard::.
*Note putpixel::.
*Note rectfill::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note set_projection_viewport::.
*Note triangle::.
*Note vsync::.

File: allegro.info,  Node: exscn3d,  Next: exzbuf,  Prev: exstars,  Up: Available

45.37 exscn3d
=============

Example exscn3d
     This program demonstrates how to use scanline sorting algo in
     Allegro (create_scene, clear_scene, ... functions). It also
     provides an example of how to use the 3D clipping function.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note MATRIX_f::.
*Note PALETTE::.
*Note V3D_f::.
*Note allegro_error::.
*Note allegro_exit::.
*Note allegro_init::.
*Note allegro_message::.
*Note apply_matrix_f: apply_matrix.
*Note bitmap_color_depth::.
*Note clear_bitmap::.
*Note clear_scene::.
*Note create_bitmap::.
*Note create_scene::.
*Note desktop_palette::.
*Note destroy_bitmap::.
*Note destroy_scene::.
*Note font::.
*Note get_rotation_matrix_f: get_rotation_matrix.
*Note get_translation_matrix_f: get_translation_matrix.
*Note gfx_mode_select_ex::.
*Note install_int::.
*Note install_keyboard::.
*Note install_mouse::.
*Note install_timer::.
*Note key::.
*Note matrix_mul_f: matrix_mul.
*Note palette_color::.
*Note persp_project_f: persp_project.
*Note polygon_z_normal_f: polygon_z_normal.
*Note render_scene::.
*Note scene_polygon3d_f: scene_polygon3d.
*Note screen::.
*Note set_color_depth::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note set_projection_viewport::.

File: allegro.info,  Node: exzbuf,  Next: exscroll,  Prev: exscn3d,  Up: Available

45.38 exzbuf
============

Example exzbuf
     This program demonstrates how to use Z-buffered polygons and
     floating point 3D math routines. It also provides a simple way to
     compute fps (frames per second) using the interrupt handler.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note MATRIX_f::.
*Note PALETTE::.
*Note V3D_f::.
*Note ZBUFFER::.
*Note allegro_error::.
*Note allegro_exit::.
*Note allegro_init::.
*Note allegro_message::.
*Note apply_matrix_f: apply_matrix.
*Note bitmap_color_depth::.
*Note clear_bitmap::.
*Note clear_zbuffer::.
*Note create_bitmap::.
*Note create_zbuffer::.
*Note desktop_palette::.
*Note destroy_bitmap::.
*Note destroy_zbuffer::.
*Note font::.
*Note gfx_mode_select_ex::.
*Note install_int::.
*Note install_keyboard::.
*Note install_mouse::.
*Note install_timer::.
*Note keypressed::.
*Note palette_color::.
*Note persp_project_f: persp_project.
*Note polygon_z_normal_f: polygon_z_normal.
*Note quad3d_f: quad3d.
*Note readkey::.
*Note screen::.
*Note set_color_depth::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note set_projection_viewport::.
*Note set_zbuffer::.
*Note vsync::.

File: allegro.info,  Node: exscroll,  Next: ex3buf,  Prev: exzbuf,  Up: Available

45.39 exscroll
==============

Example exscroll
     This program demonstrates how to use hardware scrolling and split
     screens in mode-X. The split screen part only works on DOS and
     Linux console platforms, but the scrolling should work on anything
     that supports large virtual screens.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note RGB::.
*Note acquire_bitmap::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_keybuf::.
*Note create_sub_bitmap::.
*Note desktop_palette::.
*Note destroy_bitmap::.
*Note font::.
*Note install_keyboard::.
*Note keypressed::.
*Note line::.
*Note rectfill::.
*Note release_bitmap::.
*Note screen::.
*Note scroll_screen::.
*Note set_color::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note split_modex_screen::.
*Note vline::.

File: allegro.info,  Node: ex3buf,  Next: ex12bit,  Prev: exscroll,  Up: Available

45.40 ex3buf
============

Example ex3buf
     This program demonstrates the use of triple buffering and vertical
     retrace interrupt simulation.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note RGB::.
*Note _set_color::.
*Note acquire_bitmap::.
*Note alert::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_bitmap::.
*Note clear_keybuf::.
*Note create_video_bitmap::.
*Note desktop_palette::.
*Note destroy_bitmap::.
*Note enable_triple_buffer::.
*Note fixcos::.
*Note fixed::.
*Note fixmul::.
*Note fixsin::.
*Note fixtoi::.
*Note font::.
*Note gfx_capabilities::.
*Note install_keyboard::.
*Note install_mouse::.
*Note install_timer::.
*Note itofix::.
*Note keypressed::.
*Note poll_scroll::.
*Note release_bitmap::.
*Note request_video_bitmap::.
*Note retrace_proc::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note timer_can_simulate_retrace::.
*Note timer_simulate_retrace::.
*Note triangle::.

File: allegro.info,  Node: ex12bit,  Next: exaccel,  Prev: ex3buf,  Up: Available

45.41 ex12bit
=============

Example ex12bit
     or "How to get a 12-bit mode on an 8-bit card"

     This program sets up a 12-bit mode on any 8-bit card, by setting up
     a 256-colour palette that will fool the eye into grouping two 8-bit
     pixels into one 12-bit pixel.

     It's quite simple (sort of). You make your 256-colour palette with
     all the combinations of blue and green, assuming green ranges from
     0-15 and blue from 0-14. This takes up 16x15=240 colours. This
     leaves 16 colours to use as red (red ranges from 0-15).

     Then you put your green/blue in one pixel, and your red in the
     pixel next to it. The eye gets fooled into thinking it's all one
     pixel.

     It's all very simple really. Honest.

     To start with, you set a normal 256-color VESA mode, and construct
     a special palette for it. But then comes the trick: you need to
     write to a set of two adjacent pixels to form a single 12-bit dot.
     Two eight bit pixels is the same as one 16-bit pixel, so after
     setting the video mode you need to hack the screen bitmap about,
     halving the width and changing it to use the 16-bit drawing code.
     Then, once you have packed a color into the correct format (using
     the makecol12() function below), any of the normal Allegro drawing
     functions can be used with this 12-bit display!

     Things to note:

     The horizontal width is halved, so you get resolutions like
     320x480, 400x600, and 512x768.

     Because each dot is spread over two actual pixels, the display will
     be darker than in a normal video mode.

     Any bitmap data will obviously need converting to the correct 12
     bit format: regular 15 or 16-bit images won't display correctly...

     Although this works like a truecolor mode, it is actually using a
     256-color palette, so palette fades are still possible!

     Note: This code only works in linear screen modes (don't try
     Mode-X).

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note MATRIX::.
*Note PALETTE::.
*Note RGB::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note apply_matrix::.
*Note circle::.
*Note clear_bitmap::.
*Note clear_keybuf::.
*Note clear_to_color::.
*Note create_bitmap::.
*Note create_bitmap_ex::.
*Note destroy_bitmap::.
*Note ellipsefill::.
*Note fade_out::.
*Note fixcos::.
*Note fixed::.
*Note fixsin::.
*Note fixtoi::.
*Note font::.
*Note get_rotation_matrix::.
*Note getpixel::.
*Note install_keyboard::.
*Note itofix::.
*Note keypressed::.
*Note line::.
*Note makecol::.
*Note putpixel::.
*Note screen::.
*Note set_clip::.
*Note set_color::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note text_height::.
*Note text_length::.

File: allegro.info,  Node: exaccel,  Next: exspline,  Prev: ex12bit,  Up: Available

45.42 exaccel
=============

Example exaccel
     This program demonstrates how to use an offscreen part of the
     video memory to store source graphics for a hardware accelerated
     graphics driver.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note PALETTE::.
*Note acquire_bitmap::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_bitmap::.
*Note create_video_bitmap::.
*Note destroy_bitmap::.
*Note font::.
*Note gfx_capabilities::.
*Note install_keyboard::.
*Note install_timer::.
*Note keypressed::.
*Note load_bitmap::.
*Note readkey::.
*Note release_bitmap::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note show_video_bitmap::.

File: allegro.info,  Node: exspline,  Next: exupdate,  Prev: exaccel,  Up: Available

45.43 exspline
==============

Example exspline
     This program demonstrates the use of spline curves to create smooth
     paths connecting a number of node points. This can be useful for
     constructing realistic motion and animations.

     The technique is to connect the series of guide points p1..p(n)
     with spline curves from p1-p2, p2-p3, etc. Each spline must pass
     though both of its guide points, so they must be used as the first
     and fourth of the spline control points. The fun bit is coming up
     with sensible values for the second and third spline control
     points, such that the spline segments will have equal gradients
     where they meet. I came up with the following solution:

     For each guide point p(n), calculate the desired tangent to the
     curve at that point. I took this to be the vector p(n-1) ->
     p(n+1), which can easily be calculated with the inverse tangent
     function, and gives decent looking results. One implication of
     this is that two dummy guide points are needed at each end of the
     curve, which are used in the tangent calculations but not
     connected to the set of splines.

     Having got these tangents, it becomes fairly easy to calculate the
     spline control points. For a spline between guide points p(a) and
     p(b), the second control point should lie along the positive
     tangent from p(a), and the third control point should lie along
     the negative tangent from p(b). How far they are placed along
     these tangents controls the shape of the curve: I found that
     applying a 'curviness' scaling factor to the distance between p(a)
     and p(b) works well.

     One thing to note about splines is that the generated points are
     not all equidistant. Instead they tend to bunch up nearer to the
     ends of the spline, which means you will need to apply some fudges
     to get an object to move at a constant speed. On the other hand,
     in situations where the curve has a noticable change of direction
     at each guide point, the effect can be quite nice because it makes
     the object slow down for the curve.

See also:
*Note END_OF_MAIN::.
*Note acquire_screen::.
*Note alert::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note calc_spline::.
*Note circlefill::.
*Note clear_keybuf::.
*Note clear_to_color::.
*Note desktop_palette::.
*Note fixatan2::.
*Note fixcos::.
*Note fixed::.
*Note fixmul::.
*Note fixsin::.
*Note fixsqrt::.
*Note fixtof::.
*Note fixtoi::.
*Note font::.
*Note ftofix::.
*Note install_keyboard::.
*Note install_mouse::.
*Note install_timer::.
*Note itofix::.
*Note key::.
*Note keypressed::.
*Note line::.
*Note makecol::.
*Note mouse_b: mouse_x.
*Note mouse_x::.
*Note mouse_y: mouse_x.
*Note palette_color::.
*Note poll_mouse::.
*Note readkey::.
*Note release_screen::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note show_mouse::.
*Note spline::.
*Note vsync::.
*Note xor_mode::.

File: allegro.info,  Node: exupdate,  Next: exswitch,  Prev: exspline,  Up: Available

45.44 exupdate
==============

Example exupdate
     This program demonstrates how to support double buffering, page
     flipping, and triple buffering as options within a single program,
     and how to make things run at a constant rate no matter what the
     speed of your computer.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note PALETTE::.
*Note acquire_bitmap::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note bitmap_color_depth::.
*Note clear_bitmap::.
*Note create_bitmap::.
*Note create_system_bitmap::.
*Note create_video_bitmap::.
*Note desktop_palette::.
*Note destroy_bitmap::.
*Note enable_triple_buffer::.
*Note fixcos::.
*Note fixed::.
*Note fixmul::.
*Note fixsin::.
*Note fixtoi::.
*Note font::.
*Note ftofix::.
*Note generate_332_palette::.
*Note gfx_capabilities::.
*Note gfx_mode_select_ex::.
*Note install_int_ex::.
*Note install_keyboard::.
*Note install_mouse::.
*Note install_timer::.
*Note keypressed::.
*Note line::.
*Note makecol::.
*Note poll_scroll::.
*Note release_bitmap::.
*Note request_video_bitmap::.
*Note screen::.
*Note set_color_depth::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note show_video_bitmap::.
*Note triangle::.
*Note vsync::.
*Note xor_mode::.

File: allegro.info,  Node: exswitch,  Next: exdodgy,  Prev: exupdate,  Up: Available

45.45 exswitch
==============

Example exswitch
     This program shows how to control the console switching mode, and
     let your program run in the background. These functions don't apply
     to every platform, for example you can't control the switching mode
     from a DOS program.

     Yes, I know the fractal drawing is very slow: that's the point!
     This is so you can easily check whether it goes on working in the
     background after you switch away from the app.

See also:
*Note BITMAP::.
*Note END_OF_MAIN::.
*Note PALETTE::.
*Note acquire_bitmap::.
*Note acquire_screen::.
*Note allegro_error::.
*Note allegro_exit::.
*Note allegro_init::.
*Note allegro_message::.
*Note bitmap_color_depth::.
*Note clear_to_color::.
*Note create_sub_bitmap::.
*Note desktop_palette::.
*Note destroy_bitmap::.
*Note font::.
*Note get_display_switch_mode::.
*Note gfx_mode_select_ex::.
*Note install_int::.
*Note install_keyboard::.
*Note install_mouse::.
*Note install_timer::.
*Note keypressed::.
*Note makecol::.
*Note palette_color::.
*Note putpixel::.
*Note readkey::.
*Note rectfill::.
*Note release_bitmap::.
*Note release_screen::.
*Note screen::.
*Note set_color_depth::.
*Note set_display_switch_callback::.
*Note set_display_switch_mode::.
*Note set_gfx_mode::.
*Note set_palette::.

File: allegro.info,  Node: exdodgy,  Next: exstream,  Prev: exswitch,  Up: Available

45.46 exdodgy
=============

Example exdodgy
     Plays MIDI files in the background. A dodgy trick, and not really
     useful for anything, but I think it is pretty cool!

See also:
*Note END_OF_MAIN::.
*Note MIDI::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note destroy_midi::.
*Note install_sound::.
*Note install_timer::.
*Note load_midi::.
*Note os_multitasking::.
*Note play_midi::.
*Note remove_sound::.

File: allegro.info,  Node: exstream,  Prev: exdodgy,  Up: Available

45.47 exstream
==============

Example exstream
     This program shows how to use the audio stream functions to
     transfer large blocks of sample data to the soundcard.

See also:
*Note AUDIOSTREAM::.
*Note END_OF_MAIN::.
*Note allegro_error::.
*Note allegro_init::.
*Note allegro_message::.
*Note clear_to_color::.
*Note desktop_palette::.
*Note font::.
*Note free_audio_stream_buffer::.
*Note get_audio_stream_buffer::.
*Note install_keyboard::.
*Note install_sound::.
*Note install_timer::.
*Note keypressed::.
*Note makecol::.
*Note play_audio_stream::.
*Note readkey::.
*Note screen::.
*Note set_gfx_mode::.
*Note set_palette::.
*Note stop_audio_stream::.
*Note voice_start::.
*Note voice_stop::.

File: allegro.info,  Node: Conclusion,  Next: Index,  Prev: Available,  Up: Top

46 Conclusion
*************

All good things must come to an end. Writing documentation is not a good
thing, though, and that means it goes on for ever. There is always
something I've forgotten to explain, or some essential detail I've left
out, but for now you will have to make do with this. Feel free to ask
if you can't figure something out.

Enjoy. I hope you find some of this stuff useful.

By Shawn Hargreaves.

http://alleg.sourceforge.net/


File: allegro.info,  Node: Index,  Prev: Conclusion,  Up: Top

47 Index
********

* Menu:

* 256-color transparency::
* _getpixel::
* _putpixel::
* _set_color::
* _ustrdup::
* acquire_bitmap::
* acquire_screen::
* active_dialog::
* active_menu::
* adjust_sample::
* al_assert::
* al_ffblk::
* al_findclose::
* al_findfirst::
* al_findnext::
* al_trace::
* alert::
* alert3::
* allegro_404_char::
* allegro_error::
* allegro_exit::
* allegro_id::
* allegro_init::
* allegro_message::
* allocate_voice::
* append_filename::
* apply_matrix::
* apply_quat::
* arc::
* ASSERT::
* AUDIOSTREAM::
* bestfit_color::
* BITMAP::
* bitmap_color_depth::
* bitmap_mask_color::
* black_palette::
* blit::
* blit_from_hdc::
* blit_to_hdc::
* broadcast_dialog_message::
* calc_spline::
* calibrate_joystick::
* calibrate_joystick_name::
* canonicalize_filename::
* centre_dialog::
* check_cpu::
* circle::
* circlefill::
* clear_bitmap::
* clear_keybuf::
* clear_scene::
* clear_to_color::
* clear_zbuffer::
* clip3d::
* clip3d_f::
* close_fli::
* COLOR_MAP::
* color_map::
* COMPILED_SPRITE::
* config_is_hooked::
* convert_bitmap_to_hbitmap::
* convert_hbitmap_to_bitmap::
* convert_hpalette_to_palette::
* convert_palette_to_hpalette::
* cpu_capabilities::
* cpu_family::
* cpu_model::
* cpu_vendor::
* create_bitmap::
* create_bitmap_ex::
* create_blender_table::
* create_color_table::
* create_light_table::
* create_rgb_table::
* create_sample::
* create_scene::
* create_sub_bitmap::
* create_sub_zbuffer::
* create_system_bitmap::
* create_trans_table::
* create_video_bitmap::
* create_zbuffer::
* cross_product::
* d_bitmap_proc::
* d_box_proc::
* d_button_proc::
* d_check_proc::
* d_clear_proc::
* d_edit_proc::
* d_icon_proc::
* d_keyboard_proc::
* d_list_proc::
* d_menu_proc::
* d_radio_proc::
* d_slider_proc::
* d_text_list_proc::
* d_text_proc::
* d_textbox_proc::
* d_yield_proc::
* DATAFILE::
* deallocate_voice::
* default_palette::
* delete_file::
* desktop_color_depth::
* desktop_palette::
* destroy_bitmap::
* destroy_compiled_sprite::
* destroy_font::
* destroy_gfx_mode_list::
* destroy_midi::
* destroy_rle_sprite::
* destroy_sample::
* destroy_scene::
* destroy_zbuffer::
* detect_digi_driver::
* detect_midi_driver::
* DIALOG::
* dialog_message::
* DIALOG_PLAYER::
* DIGI_*/BeOS::
* DIGI_*/DOS::
* DIGI_*/MacOSX::
* DIGI_*/QNX::
* DIGI_*/Unix::
* DIGI_*/Windows::
* digi_recorder::
* do_arc::
* do_circle::
* do_dialog::
* do_ellipse::
* do_line::
* do_menu::
* do_uconvert::
* dot_product::
* draw_character_ex::
* draw_compiled_sprite::
* draw_gouraud_sprite::
* draw_lit_rle_sprite::
* draw_lit_sprite::
* draw_rle_sprite::
* draw_sprite::
* draw_sprite_v_flip::
* draw_to_hdc::
* draw_trans_rle_sprite::
* draw_trans_sprite::
* drawing_mode::
* ellipse::
* ellipsefill::
* empty_string::
* enable_triple_buffer::
* END_OF_MAIN::
* ex12bit::
* ex3buf::
* ex3d::
* exaccel::
* exalpha::
* exbitmap::
* exblend::
* excamera::
* excolmap::
* exconfig::
* excustom::
* exdata::
* exdbuf::
* exdodgy::
* exexedat::
* exfixed::
* exflame::
* exflip::
* exgui::
* exhello::
* exists::
* exjoy::
* exkeys::
* exlights::
* exmem::
* exmidi::
* exmouse::
* expal::
* expat::
* exquat::
* exrgbhsv::
* exsample::
* exscale::
* exscn3d::
* exscroll::
* exshade::
* exspline::
* exsprite::
* exstars::
* exstream::
* exswitch::
* extimer::
* extrans::
* extruec::
* exunicod::
* exupdate::
* exxfade::
* exzbuf::
* fade_from::
* fade_from_range::
* fade_in::
* fade_in_range::
* fade_interpolate::
* fade_out::
* fade_out_range::
* file_exists::
* file_select_ex::
* file_size::
* file_time::
* find_allegro_resource::
* find_datafile_object::
* find_dialog_focus::
* Fix class::
* fix_filename_case::
* fix_filename_slashes::
* fixacos::
* fixadd::
* fixasin::
* fixatan::
* fixatan2::
* fixceil::
* fixcos::
* fixdiv::
* fixed::
* Fixed point trig::
* fixfloor::
* fixhypot::
* fixmul::
* fixsin::
* fixsqrt::
* fixsub::
* fixtan::
* fixtof::
* fixtoi::
* fixtorad_r::
* fixup_datafile::
* fli_bitmap::
* fli_bmp_dirty_from::
* fli_frame::
* fli_pal_dirty_from::
* fli_palette::
* fli_timer::
* floodfill::
* flush_config_file::
* FONT::
* font::
* for_each_file_ex::
* free_audio_stream_buffer::
* freeze_mouse_flag::
* ftofix::
* GDI routines::
* generate_332_palette::
* generate_optimized_palette::
* get_align_matrix::
* get_align_matrix_f::
* get_audio_stream_buffer::
* get_camera_matrix::
* get_camera_matrix_f::
* get_color::
* get_color_conversion::
* get_color_depth::
* get_compiled_sprite::
* get_config_argv::
* get_config_float::
* get_config_hex::
* get_config_id::
* get_config_int::
* get_config_string::
* get_config_text::
* get_datafile_property::
* get_desktop_resolution::
* get_display_switch_mode::
* get_executable_name::
* get_extension::
* get_filename::
* get_gfx_mode_list::
* get_mouse_mickeys::
* get_palette::
* get_palette_range::
* get_refresh_rate::
* get_rle_sprite::
* get_rotation_matrix::
* get_rotation_quat::
* get_scaling_matrix::
* get_sound_input_cap_bits::
* get_sound_input_cap_parm::
* get_sound_input_cap_rate::
* get_sound_input_cap_stereo::
* get_transformation_matrix::
* get_transformation_matrix_f::
* get_translation_matrix::
* get_uformat::
* get_vector_rotation_matrix::
* get_vector_rotation_quat::
* get_x_rotate_matrix::
* get_x_rotate_quat::
* get_y_rotate_matrix::
* get_z_rotate_matrix::
* geta32::
* getpixel::
* getr::
* getr8::
* getr_depth::
* GFX_*/BeOS::
* GFX_*/DOS::
* GFX_*/Linux::
* GFX_*/MacOSX::
* GFX_*/QNX::
* GFX_*/Windows::
* GFX_*/X::
* gfx_capabilities::
* GFX_MODE::
* GFX_MODE_LIST::
* gfx_mode_select::
* gfx_mode_select_ex::
* gfx_mode_select_filter::
* GUI font::
* GUI menus::
* gui_fg_color::
* gui_font_baseline::
* gui_menu_draw_menu::
* gui_mg_color::
* gui_mouse_focus::
* gui_mouse_x::
* gui_shadow_box_proc::
* gui_strlen::
* gui_textout_ex::
* hline::
* hook_config_section::
* hsv_to_rgb::
* i_love_bill::
* identity_matrix::
* identity_quat::
* init_dialog::
* init_menu::
* initialise_joystick::
* install_allegro::
* install_int::
* install_int_ex::
* install_joystick::
* install_keyboard::
* install_keyboard_hooks::
* install_mouse::
* install_param_int::
* install_param_int_ex::
* install_sound::
* install_sound_input::
* install_timer::
* is_linear_bitmap::
* is_memory_bitmap::
* is_planar_bitmap::
* is_relative_filename::
* is_same_bitmap::
* is_screen_bitmap::
* is_sub_bitmap::
* is_system_bitmap::
* is_video_bitmap::
* itofix::
* joy::
* JOY_TYPE_*/DOS::
* JOYSTIC_AXIS_INFO::
* JOYSTICK_BUTTON_INFO::
* JOYSTICK_INFO::
* JOYSTICK_STICK_INFO::
* key::
* key_led_flag::
* key_shifts::
* keyboard_callback::
* keyboard_lowlevel_callback::
* keyboard_needs_poll::
* keyboard_ucallback::
* keypressed::
* line::
* load_bitmap::
* load_bmp::
* load_datafile::
* load_datafile_callback::
* load_datafile_object::
* load_ibk::
* load_joystick_data::
* load_lbm::
* load_midi::
* load_midi_patches::
* load_pcx::
* load_sample::
* load_tga::
* load_voc::
* load_wav::
* lock_bitmap::
* lock_midi::
* lock_sample::
* make_absolute_filename::
* make_relative_filename::
* makeacol::
* makeacol32::
* makecol::
* makecol15_dither::
* makecol8::
* makecol_depth::
* MASK_COLOR_8::
* masked_blit::
* masked_stretch_blit::
* MATRIX::
* MATRIX_f::
* matrix_mul::
* matrix_to_quat::
* MENU::
* MENU_PLAYER::
* MIDI::
* MIDI_*/BeOS::
* MIDI_*/DOS::
* MIDI_*/MacOSX::
* MIDI_*/QNX::
* MIDI_*/Unix::
* MIDI_*/Windows::
* midi_loop_start::
* midi_msg_callback::
* midi_out::
* midi_pause::
* midi_pos::
* midi_recorder::
* midi_resume::
* midi_seek::
* mouse_callback::
* mouse_needs_poll::
* mouse_sprite::
* mouse_x::
* need_uconvert::
* next_fli_frame::
* normalize_vector::
* num_joysticks::
* object_message::
* offer_focus::
* open_fli::
* os_multitasking::
* os_type::
* os_version::
* override_config_data::
* override_config_file::
* pack_fclose::
* pack_fclose_chunk::
* pack_feof::
* pack_ferror::
* pack_fgets::
* pack_fopen::
* pack_fopen_chunk::
* pack_fputs::
* pack_fread::
* pack_fseek::
* pack_fwrite::
* pack_getc::
* pack_igetl::
* pack_igetw::
* pack_iputl::
* pack_iputw::
* pack_mgetl::
* pack_mgetw::
* pack_mputl::
* pack_mputw::
* pack_putc::
* PACKFILE::
* packfile_password::
* PALETTE::
* palette_color::
* persp_project::
* pivot_scaled_sprite::
* pivot_scaled_sprite_v_flip::
* pivot_sprite::
* pivot_sprite_v_flip::
* play_audio_stream::
* play_fli::
* play_looped_midi::
* play_memory_fli::
* play_midi::
* play_sample::
* poll_joystick::
* poll_keyboard::
* poll_mouse::
* poll_scroll::
* polygon::
* polygon3d::
* polygon_z_normal::
* pop_config_state::
* popup_dialog::
* position_dialog::
* position_mouse::
* position_mouse_z::
* push_config_state::
* put_backslash::
* putpixel::
* qnx_get_window::
* qscale_matrix::
* qtranslate_matrix::
* quad3d::
* QUAT::
* quat_interpolate::
* quat_mul::
* quat_slerp::
* quat_to_matrix::
* radtofix_r::
* read_sound_input::
* readkey::
* reallocate_voice::
* rect::
* rectfill::
* register_assert_handler::
* register_bitmap_file_type::
* register_datafile_object::
* register_sample_file_type::
* register_trace_handler::
* register_uformat::
* release_bitmap::
* release_screen::
* release_voice::
* reload_config_texts::
* remove_display_switch_callback::
* remove_int::
* remove_joystick::
* remove_keyboard::
* remove_mouse::
* remove_param_int::
* remove_sound::
* remove_sound_input::
* remove_timer::
* render_scene::
* replace_extension::
* replace_filename::
* request_refresh_rate::
* request_scroll::
* request_video_bitmap::
* reserve_voices::
* reset_fli_variables::
* rest::
* rest_callback::
* retrace_count::
* retrace_proc::
* RGB::
* rgb_map::
* RGB_MAP::
* RLE_SPRITE::
* rotate_scaled_sprite::
* rotate_scaled_sprite_v_flip::
* rotate_sprite::
* rotate_sprite_v_flip::
* SAMPLE::
* save_bitmap::
* save_bmp::
* save_joystick_data::
* save_pcx::
* save_sample::
* save_tga::
* scancode_to_ascii::
* scare_mouse::
* scare_mouse_area::
* Scene rendering::
* scene_gap::
* scene_polygon3d::
* screen::
* scroll_screen::
* select_palette::
* set_add_blender::
* set_alpha_blender::
* set_blender_mode::
* set_blender_mode_ex::
* set_burn_blender::
* set_clip::
* set_close_button_callback::
* set_color::
* set_color_blender::
* set_color_conversion::
* set_color_depth::
* set_config_data::
* set_config_file::
* set_config_float::
* set_config_hex::
* set_config_id::
* set_config_int::
* set_config_string::
* set_dialog_color::
* set_difference_blender::
* set_display_switch_callback::
* set_display_switch_mode::
* set_dissolve_blender::
* set_dodge_blender::
* set_gdi_color_format::
* set_gfx_mode::
* set_hue_blender::
* set_invert_blender::
* set_keyboard_rate::
* set_leds::
* set_luminance_blender::
* set_mouse_range::
* set_mouse_speed::
* set_mouse_sprite::
* set_mouse_sprite_focus::
* set_multiply_blender::
* set_palette::
* set_palette_range::
* set_palette_to_hdc::
* set_projection_viewport::
* set_saturation_blender::
* set_screen_blender::
* set_sound_input_source::
* set_trans_blender::
* set_ucodepage::
* set_uformat::
* set_volume::
* set_volume_per_voice::
* set_window_title::
* set_write_alpha_blender::
* set_zbuffer::
* show_mouse::
* show_video_bitmap::
* shutdown_dialog::
* shutdown_menu::
* simulate_keypress::
* simulate_ukeypress::
* solid_mode::
* spline::
* split_modex_screen::
* Standard config variables::
* start_sound_input::
* stop_audio_stream::
* stop_midi::
* stop_sample::
* stop_sound_input::
* stretch_blit::
* stretch_blit_from_hdc::
* stretch_blit_to_hdc::
* stretch_sprite::
* text_height::
* text_length::
* textout_centre_ex::
* textout_ex::
* textout_justify_ex::
* textout_right_ex::
* textprintf_centre_ex::
* textprintf_ex::
* textprintf_justify_ex::
* textprintf_right_ex::
* three_finger_flag::
* timer_can_simulate_retrace::
* timer_is_using_retrace::
* timer_simulate_retrace::
* TRACE::
* triangle::
* triangle3d::
* Truecolor transparency::
* uatof::
* uconvert::
* uconvert_ascii::
* uconvert_size::
* uconvert_toascii::
* ucwidth::
* ugetat::
* ugetc::
* ugetx::
* uinsert::
* uisdigit::
* uisok::
* uisspace::
* unload_datafile::
* unload_datafile_object::
* unscare_mouse::
* unselect_palette::
* uoffset::
* update_dialog::
* update_menu::
* ureadkey::
* uremove::
* usetat::
* usetc::
* Using datafiles::
* usprintf::
* ustrcat::
* ustrchr::
* ustrcmp::
* ustrcpy::
* ustrdup::
* ustrerror::
* ustricmp::
* ustrlen::
* ustrlwr::
* ustrncat::
* ustrncmp::
* ustrncpy::
* ustrnicmp::
* ustrpbrk::
* ustrrchr::
* ustrsize::
* ustrsizez::
* ustrstr::
* ustrtod::
* ustrtok::
* ustrtok_r::
* ustrtol::
* ustrupr::
* ustrzcat::
* ustrzcpy::
* ustrzncat::
* ustrzncpy::
* uszprintf::
* utolower::
* utoupper::
* uvsprintf::
* uvszprintf::
* uwidth::
* uwidth_max::
* V3D::
* V3D_f::
* vector_length::
* vline::
* Voice control::
* voice_check::
* voice_get_frequency::
* voice_get_pan::
* voice_get_position::
* voice_get_volume::
* voice_ramp_volume::
* voice_set_echo::
* voice_set_frequency::
* voice_set_pan::
* voice_set_playmode::
* voice_set_position::
* voice_set_priority::
* voice_set_tremolo::
* voice_set_vibrato::
* voice_set_volume::
* voice_start::
* voice_stop::
* voice_stop_frequency_sweep::
* voice_stop_pan_sweep::
* voice_stop_volumeramp::
* voice_sweep_frequency::
* voice_sweep_pan::
* vsync::
* win_get_dc::
* win_get_window::
* win_release_dc::
* win_set_window::
* win_set_wnd_create_proc::
* xor_mode::
* xwin_set_window_name::
* yield_timeslice::
* ZBUFFER::
* Zbuffered rendering::



Tag Table:
Node: Top307
Node: Using3559
Node: install_allegro4177
Node: allegro_init5926
Node: allegro_exit6330
Node: END_OF_MAIN7415
Node: allegro_id8312
Node: allegro_error8587
Node: os_type9067
Node: os_version10275
Node: os_multitasking10852
Node: allegro_message11210
Node: set_window_title12186
Node: set_close_button_callback12676
Node: desktop_color_depth13909
Node: get_desktop_resolution15025
Node: yield_timeslice16377
Node: check_cpu17108
Node: cpu_vendor17528
Node: cpu_family17999
Node: cpu_model18479
Node: cpu_capabilities19354
Node: Structures21062
Node: fixed22226
Node: BITMAP22766
Node: RLE_SPRITE24435
Node: COMPILED_SPRITE25166
Node: JOYSTICK_INFO25924
Node: JOYSTICK_BUTTON_INFO26654
Node: JOYSTICK_STICK_INFO27200
Node: JOYSTIC_AXIS_INFO27983
Node: GFX_MODE_LIST28540
Node: GFX_MODE28918
Node: PALETTE29205
Node: RGB29519
Node: V3D30000
Node: V3D_f30520
Node: COLOR_MAP30967
Node: RGB_MAP31462
Node: al_ffblk31932
Node: DATAFILE32411
Node: MATRIX33045
Node: MATRIX_f33551
Node: QUAT34079
Node: DIALOG34410
Node: MENU35321
Node: DIALOG_PLAYER35990
Node: MENU_PLAYER36428
Node: FONT36846
Node: ZBUFFER37159
Node: SAMPLE37638
Node: MIDI38343
Node: AUDIOSTREAM38703
Node: PACKFILE39084
Node: Unicode39688
Node: set_uformat43406
Node: get_uformat44916
Node: register_uformat45718
Node: set_ucodepage46633
Node: need_uconvert47814
Node: uconvert_size48896
Node: do_uconvert49721
Node: uconvert50680
Node: uconvert_ascii52333
Node: uconvert_toascii52727
Node: empty_string53115
Node: ugetc53544
Node: ugetx53979
Node: usetc54734
Node: uwidth55203
Node: ucwidth55634
Node: uisok56063
Node: uoffset56664
Node: ugetat57381
Node: usetat58045
Node: uinsert58829
Node: uremove59408
Node: ustrsize60059
Node: ustrsizez60378
Node: uwidth_max60698
Node: utolower61191
Node: utoupper61538
Node: uisspace61883
Node: uisdigit62453
Node: ustrdup62930
Node: _ustrdup63672
Node: ustrcpy64037
Node: ustrzcpy64532
Node: ustrcat65406
Node: ustrzcat65872
Node: ustrlen66716
Node: ustrcmp67052
Node: ustrncpy67528
Node: ustrzncpy68163
Node: ustrncat69140
Node: ustrzncat70033
Node: ustrncmp70692
Node: ustricmp71353
Node: ustrnicmp72007
Node: ustrlwr72698
Node: ustrupr73132
Node: ustrchr73564
Node: ustrrchr74138
Node: ustrstr74629
Node: ustrpbrk75100
Node: ustrtok75594
Node: ustrtok_r76756
Node: uatof77676
Node: ustrtol78120
Node: ustrtod79123
Node: ustrerror79810
Node: usprintf80475
Node: uszprintf81086
Node: uvsprintf81849
Node: uvszprintf82555
Node: Configuration83787
Node: set_config_file85844
Node: set_config_data86696
Node: override_config_file87409
Node: override_config_data88311
Node: push_config_state88722
Node: pop_config_state89481
Node: flush_config_file89848
Node: reload_config_texts90273
Node: hook_config_section91224
Node: config_is_hooked92124
Node: get_config_string92440
Node: get_config_int93253
Node: get_config_hex93789
Node: get_config_float94329
Node: get_config_id94861
Node: get_config_argv95385
Node: get_config_text96254
Node: set_config_string97548
Node: set_config_int98910
Node: set_config_hex99403
Node: set_config_float99918
Node: set_config_id100423
Node: Standard config variables100932
Node: Mouse118616
Node: install_mouse119104
Node: remove_mouse119721
Node: poll_mouse120057
Node: mouse_needs_poll121150
Node: mouse_x121463
Node: mouse_sprite123134
Node: show_mouse123631
Node: scare_mouse124737
Node: scare_mouse_area125362
Node: unscare_mouse125869
Node: freeze_mouse_flag126220
Node: position_mouse126708
Node: position_mouse_z127127
Node: set_mouse_range127434
Node: set_mouse_speed127954
Node: set_mouse_sprite128360
Node: set_mouse_sprite_focus129110
Node: get_mouse_mickeys129650
Node: mouse_callback130208
Node: Timer130911
Node: install_timer132241
Node: remove_timer132902
Node: install_int133332
Node: install_int_ex134119
Node: remove_int137740
Node: install_param_int138123
Node: install_param_int_ex138651
Node: remove_param_int139197
Node: timer_can_simulate_retrace139832
Node: timer_simulate_retrace140437
Node: timer_is_using_retrace143242
Node: retrace_count143647
Node: retrace_proc144682
Node: rest146008
Node: rest_callback146430
Node: Keyboard146782
Node: install_keyboard147755
Node: remove_keyboard148944
Node: install_keyboard_hooks149365
Node: poll_keyboard150208
Node: keyboard_needs_poll151530
Node: key151862
Node: key_shifts153863
Node: keypressed154863
Node: readkey155322
Node: ureadkey156836
Node: scancode_to_ascii157498
Node: simulate_keypress157920
Node: simulate_ukeypress158367
Node: keyboard_callback158832
Node: keyboard_ucallback159616
Node: keyboard_lowlevel_callback160487
Node: set_leds161172
Node: set_keyboard_rate161624
Node: clear_keybuf162013
Node: three_finger_flag162352
Node: key_led_flag163035
Node: Joystick163564
Node: install_joystick163904
Node: remove_joystick165084
Node: poll_joystick165447
Node: num_joysticks165956
Node: joy166312
Node: calibrate_joystick_name171918
Node: calibrate_joystick172407
Node: save_joystick_data173588
Node: load_joystick_data174308
Node: initialise_joystick175064
Node: Graphics175344
Node: set_color_depth175900
Node: get_color_depth176446
Node: request_refresh_rate176721
Node: get_refresh_rate177629
Node: get_gfx_mode_list178015
Node: destroy_gfx_mode_list179125
Node: set_gfx_mode179525
Node: set_display_switch_mode185805
Node: set_display_switch_callback188929
Node: remove_display_switch_callback189865
Node: get_display_switch_mode190389
Node: gfx_capabilities190784
Node: enable_triple_buffer198134
Node: scroll_screen198867
Node: request_scroll200656
Node: poll_scroll201883
Node: show_video_bitmap202396
Node: request_video_bitmap203249
Node: vsync204204
Node: Bitmap205084
Node: screen208946
Node: create_bitmap210217
Node: create_bitmap_ex211086
Node: create_sub_bitmap211652
Node: create_video_bitmap212497
Node: create_system_bitmap213707
Node: destroy_bitmap214269
Node: lock_bitmap214796
Node: bitmap_color_depth215154
Node: bitmap_mask_color215627
Node: is_same_bitmap216206
Node: is_planar_bitmap216654
Node: is_linear_bitmap217005
Node: is_memory_bitmap217746
Node: is_screen_bitmap218288
Node: is_video_bitmap218632
Node: is_system_bitmap219021
Node: is_sub_bitmap219374
Node: acquire_bitmap219648
Node: release_bitmap221009
Node: acquire_screen221622
Node: release_screen222090
Node: set_clip222552
Node: Loading223667
Node: load_bitmap224214
Node: load_bmp225938
Node: load_lbm226237
Node: load_pcx226506
Node: load_tga226803
Node: save_bitmap227132
Node: save_bmp228426
Node: save_pcx228739
Node: save_tga229049
Node: register_bitmap_file_type229423
Node: set_color_conversion230027
Node: get_color_conversion235087
Node: Palette235371
Node: set_color237303
Node: _set_color237840
Node: set_palette238492
Node: set_palette_range239052
Node: get_color239553
Node: get_palette239827
Node: get_palette_range240206
Node: fade_interpolate240604
Node: fade_from_range241368
Node: fade_in_range241926
Node: fade_out_range242452
Node: fade_from242940
Node: fade_in243380
Node: fade_out243784
Node: select_palette244176
Node: unselect_palette244903
Node: generate_332_palette245220
Node: generate_optimized_palette245842
Node: default_palette246679
Node: black_palette247078
Node: desktop_palette247421
Node: Truecolor247988
Node: makecol8248994
Node: makeacol32249933
Node: makecol250657
Node: makecol_depth251248
Node: makeacol251738
Node: makecol15_dither252635
Node: getr8253423
Node: geta32254075
Node: getr254335
Node: getr_depth254928
Node: palette_color255566
Node: MASK_COLOR_8256197
Node: Drawing256829
Node: putpixel257391
Node: _putpixel257886
Node: getpixel258648
Node: _getpixel259044
Node: vline259617
Node: hline259992
Node: do_line260314
Node: line260900
Node: triangle261279
Node: polygon261649
Node: rect262118
Node: rectfill262471
Node: do_circle262983
Node: circle263610
Node: circlefill264079
Node: do_ellipse264576
Node: ellipse265226
Node: ellipsefill265593
Node: do_arc265978
Node: arc266957
Node: calc_spline267602
Node: spline268791
Node: floodfill269146
Node: Blitting269463
Node: clear_bitmap270129
Node: clear_to_color270431
Node: blit270755
Node: stretch_blit273351
Node: masked_blit274278
Node: masked_stretch_blit275552
Node: draw_sprite276311
Node: stretch_sprite278231
Node: draw_sprite_v_flip278803
Node: draw_trans_sprite279559
Node: draw_lit_sprite281173
Node: draw_gouraud_sprite282465
Node: draw_character_ex283120
Node: rotate_sprite283923
Node: rotate_sprite_v_flip284953
Node: rotate_scaled_sprite285626
Node: rotate_scaled_sprite_v_flip286175
Node: pivot_sprite286707
Node: pivot_sprite_v_flip287224
Node: pivot_scaled_sprite287760
Node: pivot_scaled_sprite_v_flip288370
Node: RLE289033
Node: get_rle_sprite291046
Node: destroy_rle_sprite291443
Node: draw_rle_sprite291782
Node: draw_trans_rle_sprite292288
Node: draw_lit_rle_sprite293233
Node: Compiled293919
Node: get_compiled_sprite295034
Node: destroy_compiled_sprite295843
Node: draw_compiled_sprite296241
Node: Text297176
Node: font298029
Node: allegro_404_char298604
Node: text_length298976
Node: text_height299325
Node: destroy_font299640
Node: textout_ex299867
Node: textout_centre_ex300716
Node: textout_right_ex301161
Node: textout_justify_ex301609
Node: textprintf_ex302141
Node: textprintf_centre_ex302896
Node: textprintf_right_ex303442
Node: textprintf_justify_ex303991
Node: Polygon304509
Node: polygon3d304950
Node: triangle3d313589
Node: quad3d314366
Node: clip3d_f314931
Node: clip3d316168
Node: Zbuffered rendering316720
Node: create_zbuffer318660
Node: create_sub_zbuffer319244
Node: set_zbuffer320590
Node: clear_zbuffer320997
Node: destroy_zbuffer321624
Node: Scene rendering321982
Node: create_scene325058
Node: clear_scene325832
Node: destroy_scene326241
Node: scene_polygon3d326604
Node: render_scene328404
Node: scene_gap329228
Node: Transparency330576
Node: drawing_mode331356
Node: xor_mode335413
Node: solid_mode335879
Node: 256-color transparency336238
Node: color_map337381
Node: create_trans_table338072
Node: create_light_table339325
Node: create_color_table340504
Node: create_blender_table341796
Node: Truecolor transparency342784
Node: set_trans_blender344622
Node: set_alpha_blender345564
Node: set_write_alpha_blender346582
Node: set_add_blender347517
Node: set_burn_blender347888
Node: set_color_blender348390
Node: set_difference_blender348912
Node: set_dissolve_blender349426
Node: set_dodge_blender350048
Node: set_hue_blender350551
Node: set_invert_blender350972
Node: set_luminance_blender351431
Node: set_multiply_blender351934
Node: set_saturation_blender352561
Node: set_screen_blender353028
Node: set_blender_mode353607
Node: set_blender_mode_ex354225
Node: Converting355094
Node: bestfit_color356922
Node: rgb_map357548
Node: create_rgb_table358379
Node: hsv_to_rgb358908
Node: Direct359398
Node: FLIC365798
Node: play_fli367899
Node: play_memory_fli368303
Node: open_fli369167
Node: close_fli369667
Node: next_fli_frame369900
Node: fli_bitmap370542
Node: fli_palette370855
Node: fli_bmp_dirty_from371156
Node: fli_pal_dirty_from371875
Node: reset_fli_variables372606
Node: fli_frame373039
Node: fli_timer373549
Node: Sound374101
Node: detect_digi_driver374373
Node: detect_midi_driver375000
Node: reserve_voices375986
Node: set_volume_per_voice377122
Node: install_sound380659
Node: remove_sound382246
Node: set_volume382627
Node: Digital383218
Node: load_sample384125
Node: load_wav384781
Node: load_voc385065
Node: save_sample385358
Node: create_sample385925
Node: destroy_sample386384
Node: lock_sample386815
Node: register_sample_file_type387233
Node: play_sample387779
Node: adjust_sample388711
Node: stop_sample389424
Node: Voice control389820
Node: allocate_voice391210
Node: deallocate_voice391918
Node: reallocate_voice392269
Node: release_voice392784
Node: voice_start393374
Node: voice_stop393728
Node: voice_set_priority394114
Node: voice_check394535
Node: voice_get_position395092
Node: voice_set_position395452
Node: voice_set_playmode395812
Node: voice_get_volume397560
Node: voice_set_volume397872
Node: voice_ramp_volume398212
Node: voice_stop_volumeramp398644
Node: voice_get_frequency398939
Node: voice_set_frequency399265
Node: voice_sweep_frequency399627
Node: voice_stop_frequency_sweep400070
Node: voice_get_pan400391
Node: voice_set_pan400703
Node: voice_sweep_pan401036
Node: voice_stop_pan_sweep401455
Node: voice_set_echo401735
Node: voice_set_tremolo402054
Node: voice_set_vibrato402383
Node: Music402707
Node: load_midi403086
Node: destroy_midi403479
Node: lock_midi403905
Node: play_midi404250
Node: play_looped_midi405211
Node: stop_midi405812
Node: midi_pause406118
Node: midi_resume406379
Node: midi_seek406601
Node: midi_out407352
Node: load_midi_patches407789
Node: midi_pos408373
Node: midi_loop_start408848
Node: midi_msg_callback409576
Node: load_ibk410494
Node: Audio411238
Node: play_audio_stream411767
Node: stop_audio_stream413100
Node: get_audio_stream_buffer413448
Node: free_audio_stream_buffer414590
Node: Recording415120
Node: install_sound_input415544
Node: remove_sound_input416520
Node: get_sound_input_cap_bits416988
Node: get_sound_input_cap_stereo417691
Node: get_sound_input_cap_rate418157
Node: get_sound_input_cap_parm418691
Node: set_sound_input_source419580
Node: start_sound_input420103
Node: stop_sound_input420829
Node: read_sound_input421139
Node: digi_recorder422291
Node: midi_recorder422972
Node: File423463
Node: get_executable_name426149
Node: fix_filename_case426589
Node: fix_filename_slashes427004
Node: canonicalize_filename427453
Node: make_absolute_filename427982
Node: make_relative_filename428505
Node: is_relative_filename429078
Node: replace_filename429451
Node: replace_extension429946
Node: append_filename430419
Node: get_filename430865
Node: get_extension431291
Node: put_backslash431679
Node: file_exists432171
Node: exists432699
Node: file_size433099
Node: file_time433467
Node: delete_file433898
Node: for_each_file_ex434107
Node: al_findfirst435453
Node: al_findnext436585
Node: al_findclose437040
Node: find_allegro_resource437362
Node: packfile_password438315
Node: pack_fopen440485
Node: pack_fclose443832
Node: pack_fseek444493
Node: pack_feof445220
Node: pack_ferror445900
Node: pack_getc446622
Node: pack_putc446951
Node: pack_igetw447269
Node: pack_iputw447613
Node: pack_igetl447964
Node: pack_iputl448310
Node: pack_mgetw448663
Node: pack_mputw449012
Node: pack_mgetl449362
Node: pack_mputl449712
Node: pack_fread450064
Node: pack_fwrite450569
Node: pack_fgets451051
Node: pack_fputs451975
Node: pack_fopen_chunk452626
Node: pack_fclose_chunk455065
Node: Datafile455408
Node: load_datafile456298
Node: load_datafile_callback457248
Node: unload_datafile457919
Node: load_datafile_object458317
Node: unload_datafile_object458979
Node: find_datafile_object459331
Node: get_datafile_property459897
Node: register_datafile_object460323
Node: fixup_datafile460840
Node: Using datafiles461950
Node: Fixed464239
Node: itofix465347
Node: fixtoi465804
Node: fixfloor466253
Node: fixceil466551
Node: ftofix466844
Node: fixtof467153
Node: fixmul467452
Node: fixdiv468250
Node: fixadd468533
Node: fixsub469115
Node: Fixed point trig469396
Node: fixtorad_r470110
Node: radtofix_r470592
Node: fixsin471065
Node: fixcos471378
Node: fixtan471689
Node: fixasin471898
Node: fixacos472116
Node: fixatan472337
Node: fixatan2472559
Node: fixsqrt472849
Node: fixhypot473121
Node: Fix class473391
Node: 3D474099
Node: identity_matrix478190
Node: get_translation_matrix478561
Node: get_scaling_matrix479233
Node: get_x_rotate_matrix479874
Node: get_y_rotate_matrix480526
Node: get_z_rotate_matrix481179
Node: get_rotation_matrix481832
Node: get_align_matrix482617
Node: get_align_matrix_f483228
Node: get_vector_rotation_matrix483587
Node: get_transformation_matrix484260
Node: get_transformation_matrix_f485014
Node: get_camera_matrix485427
Node: get_camera_matrix_f486719
Node: qtranslate_matrix487103
Node: qscale_matrix487687
Node: matrix_mul488204
Node: vector_length489057
Node: normalize_vector489444
Node: dot_product489952
Node: cross_product490368
Node: polygon_z_normal491003
Node: apply_matrix491820
Node: set_projection_viewport492363
Node: persp_project492927
Node: Quaternion494184
Node: identity_quat495544
Node: get_x_rotate_quat495863
Node: get_rotation_quat496398
Node: get_vector_rotation_quat496831
Node: quat_to_matrix497263
Node: matrix_to_quat497583
Node: quat_mul498032
Node: apply_quat498613
Node: quat_interpolate499150
Node: quat_slerp499815
Node: GUI500555
Node: d_clear_proc510927
Node: d_box_proc511256
Node: d_bitmap_proc511602
Node: d_text_proc511931
Node: d_button_proc512771
Node: d_check_proc513389
Node: d_radio_proc514083
Node: d_icon_proc514611
Node: d_keyboard_proc515415
Node: d_edit_proc516196
Node: d_list_proc517001
Node: d_text_list_proc518312
Node: d_textbox_proc518758
Node: d_slider_proc519533
Node: d_menu_proc520370
Node: d_yield_proc521548
Node: gui_mouse_focus522157
Node: gui_fg_color522451
Node: gui_mg_color522852
Node: gui_font_baseline523203
Node: gui_mouse_x523526
Node: GUI font524094
Node: gui_textout_ex524506
Node: gui_strlen524997
Node: position_dialog525318
Node: centre_dialog525703
Node: set_dialog_color526042
Node: find_dialog_focus526441
Node: offer_focus527071
Node: object_message527643
Node: dialog_message528436
Node: broadcast_dialog_message528944
Node: do_dialog529381
Node: popup_dialog530295
Node: init_dialog530820
Node: update_dialog531704
Node: shutdown_dialog532297
Node: active_dialog532716
Node: GUI menus533136
Node: do_menu534699
Node: init_menu535377
Node: update_menu536210
Node: shutdown_menu536701
Node: active_menu537166
Node: gui_menu_draw_menu537558
Node: alert538412
Node: alert3539194
Node: file_select_ex539496
Node: gfx_mode_select541840
Node: gfx_mode_select_ex542422
Node: gfx_mode_select_filter543184
Node: gui_shadow_box_proc544148
Node: DOS545040
Node: JOY_TYPE_*/DOS545259
Node: GFX_*/DOS552356
Node: DIGI_*/DOS559993
Node: MIDI_*/DOS560992
Node: split_modex_screen562013
Node: i_love_bill562974
Node: Windows564042
Node: GFX_*/Windows567718
Node: DIGI_*/Windows571936
Node: MIDI_*/Windows572761
Node: win_get_window573616
Node: win_set_window574017
Node: win_set_wnd_create_proc575507
Node: win_get_dc576485
Node: win_release_dc576762
Node: GDI routines577074
Node: set_gdi_color_format578560
Node: set_palette_to_hdc579026
Node: convert_palette_to_hpalette579352
Node: convert_hpalette_to_palette579823
Node: convert_bitmap_to_hbitmap580216
Node: convert_hbitmap_to_bitmap580810
Node: draw_to_hdc581170
Node: blit_to_hdc581598
Node: stretch_blit_to_hdc582041
Node: blit_from_hdc582540
Node: stretch_blit_from_hdc583032
Node: Unix583771
Node: GFX_*/Linux584528
Node: GFX_*/X586747
Node: DIGI_*/Unix589206
Node: MIDI_*/Unix589866
Node: xwin_set_window_name590477
Node: BeOS591185
Node: GFX_*/BeOS591349
Node: DIGI_*/BeOS593192
Node: MIDI_*/BeOS593679
Node: QNX594225
Node: GFX_*/QNX594404
Node: DIGI_*/QNX596242
Node: MIDI_*/QNX596719
Node: qnx_get_window597476
Node: MacOS597873
Node: GFX_*/MacOSX598057
Node: DIGI_*/MacOSX599341
Node: MIDI_*/MacOSX599944
Node: Differences600611
Node: Reducing607430
Node: Debugging613701
Node: al_assert614547
Node: al_trace615274
Node: ASSERT615952
Node: TRACE616400
Node: register_assert_handler616861
Node: register_trace_handler617579
Node: Makefile618266
Node: Available626204
Node: exhello627350
Node: exmem627933
Node: expal628649
Node: expat629261
Node: exflame630036
Node: exdbuf630808
Node: exflip631542
Node: exfixed632203
Node: exmouse632585
Node: extimer633560
Node: exkeys634289
Node: exjoy634914
Node: exsample635931
Node: exmidi636583
Node: exgui637168
Node: excustom638426
Node: exunicod639387
Node: exconfig640237
Node: exbitmap640958
Node: exscale641446
Node: exdata642095
Node: exsprite642674
Node: exexedat644821
Node: extrans645816
Node: extruec646808
Node: excolmap647413
Node: exrgbhsv648220
Node: exshade649235
Node: exxfade650023
Node: exblend650773
Node: exalpha651641
Node: exlights652642
Node: ex3d655602
Node: excamera657045
Node: exquat657988
Node: exstars660265
Node: exscn3d661283
Node: exzbuf662596
Node: exscroll663818
Node: ex3buf664694
Node: ex12bit665740
Node: exaccel668545
Node: exspline669327
Node: exupdate672399
Node: exswitch673723
Node: exdodgy675110
Node: exstream675640
Node: Conclusion676417
Node: Index676951

End Tag Table
