Python bindings to the Allegro game programming library Version 0.1.5, 2007-04-29. COPYRIGHT AND PERMISSION NOTICE Copyright (c) 2001-2005 Juha-Matti Tapio Alberto Griggio Copyright (c) 2005-2007 Grzegorz Adam Hankiewicz All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, provided that the above copyright notice(s) and this permission notice appear in all copies of the Software and that both the above copyright notice(s) and this permission notice appear in supporting documentation. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization of the copyright holder. ------------------------------------------------------------------------------ NOTE: Most of the documentation here is an adaptation of the Allegro C API documentation, which comes with Allegro and is also online at http://alleg.sourceforge.net/api.html. If something is not clear, you may have luck checking that version. You can also make questions to the pyallegro mailing list, at http://lists.sourceforge.net/lists/listinfo/pyallegro-general. ------------------------------------------------------------------------------ Index ----- 1 Installation and generic routines 1.1 class AlpyException 1.2 functions 2 Unicode routines 3 Mouse routines 4 Keyboard routines 4.1 objects 4.2 functions 5 Timer routines 5.1 basic functions 5.2 timer handlers 6 Graphics modes routines 7 Bitmap objects 7.1 screen variable 7.2 class Bitmap 7.3 Bitmaps and the Python Imaging Library (PIL) 7.4 functions 8 RleSprite objects 8.1 class RleSprite 9 CompiledSprite objects 9.1 class CompiledSprite 10 Font objects 10.1 font variable 10.2 class Font 11 Drawing functions 12 Palette objects 12.1 class Rgb 12.2 class Palette 12.3 functions 12.4 module variables 13 Truecolor routines 13.1 functions 13.2 objects 14 Pattern drawing and color mapping 14.1 functions 14.2 class ColorMap 14.3 class RgbMap 15 Sound objects and routines 15.1 class Sample 15.2 class Midi 15.3 functions 16 Basic FLIC routines 17 Datafiles 17.1 class Datafile 17.2 functions 1 Installation and generic routines ----------------------------------- 1.1 class AlpyException Exception raised every time something goes wrong. A description of the problem can be obtained with the get_allegro_error function. 1.2 functions * install_allegro(system_id) -> None Initialises the Allegro library. You must call either this or allegro_init() before doing anything. Functions that can be called before this one will be marked explicitly in the documentation. Raises AlpyException on error. 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. Example: import alpy alpy.install_allegro(alpy.SYSTEM_AUTODETECT) * init(keyboard = 1, mouse = 1, timer = 1) -> None Handy shortcut which calls allegro_init() and then depending on the boolean parameters install_keyboard(), install_mouse() and install_timer() respectively (by default all are called). * allegro_init() -> None Initialises the Allegro library. This is the same thing as calling install_allegro(SYSTEM_AUTODETECT). Raises AlpyException on failure. * allegro_exit() -> None 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 it is automatically called when your program exits. * get_allegro_error() -> string Returns the last error message generated by Allegro. Note that this is not the same as the message generated by AlpyException, it is the internal error string generated by the C library. * get_allegro_id(): tuple of strings: the first element is equal to the C version allegro_id char array, while the second refers to the python wrapper. * get_os_type() -> int Returns an integer describing the operating system. Possible values are: OSTYPE_BEOS, OSTYPE_DOSEMU, OSTYPE_FREEBSD, OSTYPE_LINUX, OSTYPE_MACOS, OSTYPE_OPENDOS, OSTYPE_OS2, OSTYPE_QNX, OSTYPE_UNIX, OSTYPE_UNKNOWN, OSTYPE_WARP, OSTYPE_WIN2000, OSTYPE_WIN3, OSTYPE_WIN95, OSTYPE_WIN98, OSTYPE_WINME, OSTYPE_WINNT, OSTYPE_WINXP. * desktop_color_depth() -> int 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. Returns the color depth or zero on platforms where this information is not available or does not apply. * yield_timeslice() -> None On systems that support this, gives up the rest of the current scheduler timeslice. Also known as the "play nice with multitasking" option. * set_window_title(string) -> None On platforms that are capable of it, this routine alters the window title for your Allegro program. * set_config_file(string) -> None 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 and the usual platform-specific paths for configuration files. For example it will look for `/etc/allegro.cfg' under Unix. All pointers returned by previous calls to get_config_string() and other related functions are invalidated when you call this function! You can call this function before install_allegro() to change the configuration file, but after set_uformat() if you want to use a text encoding format other than the default. * set_config_data(string) -> None 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. * override_config_file(string) -> None 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. The override config file will not only take precedence when reading, but will also be used for storing values. When you are done with using the override config file, you can call override_config_file with an empty string, so config data will be directly read from the current config file again. Note: The override file is completely independent from the current configuration. You can e.g. call set_config_file, and the override file will still be active. Also the flush_config_file function will only affect the current config file (which can be changed with set_config_file), never the overriding one specified with this function. The modified override config is written back to disk whenever you call override_config_file. Note that this function and override_config_data() are mutually exclusive, i.e. calling one will cancel the effects of the other. * override_config_data(string) -> None Version of override_config_file() which uses a block of data that has already been read into memory. Example: # Force German as system language, Spanish keyboard map. override_data = """[system] language=DE keyboard=ES""" alpy.override_config_data(override_data) Note that this function and override_config_file() are mutually exclusive, i.e. calling one will cancel the effects of the other. * get_config_var(name, def, section = "", type = "str"]) -> var This single function replaces the various get_config_xxx of the C version. The first parameter is the name of the variable you want to retrieve. The second is its default value, which will be returned if the variable is not found. The third parameter indicates the section where this configuration variable is stored. Finally, since Allegro config files aren't typed, you may have to specify the type of the value you want to be returned: * str: the value is a string. This is the default. * tokens: the value is a list of strings. * int: treat the variable as an integer. * float: floating point value. The def parameter will be converted to the type you specify. * set_config_var(name, value, section = "") -> None This single function replaces the various set_config_xxx of the C version. The first parameter is the name of the variable you want to set. The second is the value associated to the variable, which will be converted to a string. The third optional parameter indicates the section where this configuration variable is stored. Examples: alpy.set_config_var("number_five", 5, "general") alpy.set_config_var("float_five_and_half", 5.5, "general") alpy.set_config_var("name_string", "Allegro", "general") * get_gfx_info() -> (id, name, description, ascii_name) Returns a tuple with four elements about the current graphics driver. The first is the driver ID, the second is the name, the third a description, and the fourth is the name in ASCII. Raises AlpyException if no graphics mode is set. * get_mouse_info() -> (id, name, description, ascii_name) Returns a tuple with four elements about the current mouse driver. The first is the driver ID, the second is the name, the third a description, and the fourth is the name in ASCII. Raises AlpyException if no mouse is installed. * get_keyboard_info() -> (id, name, description, ascii_name) Returns a tuple with four elements about the current keyboard driver. The first is the driver ID, the second is the name, the third a description, and the fourth is the name in ASCII. Raises AlpyException if no keyboard is installed. * get_timer_info() -> (id, name, description, ascii_name) Returns a tuple with four elements about the current timer driver. The first is the driver ID, the second is the name, the third a description, and the fourth is the name in ASCII. Raises AlpyException if no timer driver are installed. * get_system_info() -> (id, name, description, ascii_name) Returns a tuple with four elements about the current system driver. The first is the driver ID, the second is the name, the third a description, and the fourth is the name in ASCII. Raises AlpyException if allegro has not been initialised yet. 2 Unicode routines ------------------ The C version of Allegro implements most (if not all) of libc's string functionality with functions that allow programmers to mix ascii strings, 8-bit aware strings (think of codepages), utf8 and unicode16 strings with the basic char* type. While it could be "good" to have Python wrappers around all these string functions for the sake of being able to port C source code directly into Python, that would be a bad idea, especially because C is aimed at modifying strings in place, while Python considers strings inmutable. On top of that, Python's string facilities are much easier to use, better, without memory leaks, and work with Unicode strings (at least in Python 2.x and above). For this reason, Alpy doesn't expose at all any of the Allegro C unicode functions. Instead, as a Python programmer you are meant to work with strings just like you would in any other script. At the time when you pass a string to Allegro, you can do two things: * Pass a plain ascii string. * Pass a unicode string. The first case may fail if your string contains characters using the 8th bit. The second should work everywhere with any string content. With regards to the current implementation, unicode text output is supported graphically, demonstrated by the exunicode_* examples. However, filesystem IO interaction is still unicode unaware due to a bug in Allegro: http://sourceforge.net/mailarchive/forum.php?thread_id=10913067&forum_id=34598 Which means that until that is fixed, trying to load a bitmap from a file with non ascii characters in the filename will not work. If you are an addon developer, you may want to know that Alpy explicitly calls set_uformat(U_UTF8) during initialisation and from that moment on expects all C strings to be in utf8. If you have unicode problems with some Alpy function not accepting unicode, a first start may be to debug what is being converted in the C binding as passed from the Python level, and then check what Allegro is actually expecting. Or just report the bug on the alpy mailing list. 3 Mouse routines ---------------- * install_mouse() -> int Installs the Allegro mouse handler. You must do this before using any other mouse functions. Returns -1 on failure, zero if the mouse handler is already installed (in which case this function does nothing) and the number of buttons on the mouse if the mouse handler has successfully been installed (ie. this is the first time a handler is installed or you have removed the previous one). Note that the number of mouse buttons returned by this function is more an indication than a physical reality. With most devices there is no way of telling how many buttons there are, and any user can override the number of mouse buttons returned by this function with a custom configuration file and the variable num_buttons. Even if this value is overriden by the user, the global mouse variables will still report whatever the hardware is sending. * remove_mouse() -> None Removes the mouse handler. You don't normally need to bother calling this, because allegro_exit() will do it for you. * poll_mouse() -> None 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. * mouse_needs_poll() -> int Returns True if the current mouse driver is operating in polling mode. * get_mouse_pos() -> (mouse_x, mouse_y, mouse_z, mouse_b) This function returns four integers in a tuple specifying the state of the mouse. 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. Additional non standard mouse buttons might be available as higher bits in this variable. Usage example: m_x, m_y, m_z, m_b = alpy.get_mouse_pos() print "Mouse X coordinate %d" % m_x print "Mouse Y coordinate %d" % m_y print "Wheel Z at position %d" % m_z print "State of left button %d" % (m_b & 1) print "State of right button %d" % (m_b & 2) print "State of middle button %d" % (m_b & 4) 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 before retrieving their value. Otherwise you would always get the same return values. * show_mouse(bitmap?) -> None 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). If you don't specify any parameter at all, it will be as if you specified `screen' manually. 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 graphics drawing 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. This is not needed if you are using a hardware cursor. If the parameter you pass is not a bitmap object, the function will raise AlpyException. * position_mouse(x, y, z?) -> None Moves the mouse to the specified position. It is safe to call even when a mouse pointer is being displayed. If the optional parameter z is passed, the wheelmouse position will be set too. * set_mouse_range(x1, y1, x2, y2) -> None 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). * set_mouse_speed(speed_x, speed_y) -> None This function, which expects to integer parameters, sets the mouse speed. Larger values of speed_x and speed_y represent slower mouse movement: the default for both is 2. * set_mouse_sprite(bitmap) -> None You don't like Allegro's mouse pointer? No problem. Use this function to supply an alternative of your own. If you change the pointer and then want to get Allegro's lovely arrow back again, call set_mouse_sprite(None). As a bonus, set_mouse_sprite(None) 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(None). If the parameter you pass is not valid, AlpyException will be raised. * set_mouse_sprite_focus(int, int) -> None 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. * get_mouse_mickeys() -> (diff_x, diff_y) 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. 4 Keyboard routines ------------------- 4.1 objects * key: list of flags indicating the state of each key. See the Allegro docs for details. 4.2 functions * install_keyboard() -> int 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. This function is called by default by alpy.init(). Note that on some platforms the keyboard won't work unless you have set a graphics mode, even if this function returns a success value before calling set_gfx_mode. This can happen in environments with graphic windowed modes, since Allegro usually reads the keyboard through the graphical window (which appears after the set_gfx_call). Example: alpy.install_allegro(alpy.SYSTEM_AUTODETECT) alpy.install_timer() alpy.install_keyboard() # We are not 100% we can read the keyboard yet! alpy.set_gfx_mode(alpy.GFX_AUTODETECT, 640, 480) # Now we are guaranteed to be able to read the keyboard. alpy.readkey() 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). * remove_keyboard() -> None 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. However, you might want to call this during runtime if you want to change the keyboard mapping on those platforms were keyboard mappings are needed. You would first modify the configuration variable holding the keyboard mapping and then reinstall the keyboard handler. Example: alpy.remove_keyboard() # Switch to Spanish keyboard mapping. alpy.set_config_var("keyboard", "es", "system") alpy.install_keyboard() * poll_keyboard() -> int 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). * keyboard_needs_poll() -> int Returns TRUE if the current keyboard driver is operating in polling mode. * get_key_shifts() -> int 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 Example: if alpy.key(alpy.KEY_W): if alpy.get_key_shifts() & alpy.KB_SHIFT_FLAG: # User is pressing shift + W. ... else: # Hmmm... lower case W then. ... * keypressed() -> int Returns TRUE if there are keypresses waiting in the input buffer. You can use this to see if the next call to readkey() is going to block or to simply wait for the user to press a key while you still update the screen possibly drawing some animation. Example: while not alpy.keypressed(): # Show cool animated logo. # So the user skipped our title screen. * readkey() -> int Returns the next character from the keyboard buffer, in ASCII format. If the buffer is empty, it waits until a key is pressed. You can see if there are queued keypresses with keypressed(). 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: val = alpy.readkey() if (val & 0xff) == ord("d"): # by ASCII code print "You pressed 'd'" if (val >> 8) == KEY_SPACE: # by scancode print "You pressed Space" if (val & 0xff) == 3: # ctrl+letter print "You pressed Control+C" if val == (KEY_X << 8): # alt+letter print "You pressed Alt+X" This function cannot return character values greater than 255. If you need to read Unicode input, use ureadkey() instead. * scancode_to_ascii(scancode) -> int Converts the given scancode to an ASCII character for that key (mangling Unicode values), 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. The lookup cannot be done for keys like the F1-F12 keys or the cursor keys, and some drivers will only return approximate values. Generally, if you want to display the name of a key to the user, you should use the scancode_to_name function (only available in 4.1.x). Example: ascii = alpy.scancode_to_ascii(scancode) print "You pressed '%c'" % ascii * simulate_keypress(int) -> None 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(). Example: alpy.simulate_keypress(alpy.KEY_SPACE >> 8) if alpy.readkey() == (alpy.KEY_SPACE >> 8): print "You simulated Alt+Space" * simulate_keypress(int) -> None 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(). Example: alpy.simulate_keypress(alpy.KEY_SPACE >> 8) if alpy.readkey() == (alpy.KEY_SPACE >> 8): print "You simulated Alt+Space" * set_leds(int) -> None 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. Example: # Cycle led indicators. alpy.set_leds(alpy.KB_SCROLOCK_FLAG) alpy.rest(1000) alpy.set_leds(alpy.KB_CAPSLOCK_FLAG) alpy.rest(1000) alpy.set_leds(alpy.KB_NUMLOCK_FLAG) alpy.rest(1000) alpy.set_leds(-1) Note that the led behaviour cannot be guaranteed on some platforms, some leds might not react, or none at all. Therefore you shouldn't rely only on them to communicate information to the user, just in case it doesn't get through. * set_keyboard_rate(delay, repeat) -> None Sets the keyboard repeat rate. Times are given in milliseconds. Passing zero times will disable the key repeat. * clear_keybuf() -> None Empties the keyboard buffer. Usually you want to use this in your program before reading keys to avoid previously buffered keys to be returned by calls to readkey() or ureadkey(). * get_flags() -> (three_finger_flag, key_led_flag) Retrieves the status of Allegro's global variables three_finger_flag and key_led_flag. Use set_flags() to modify their value. * set_flags(three_finger_flag, key_led_flag) -> None Sets the status of Allegro's global variables three_finger_flag and key_led_flag. Use get_flags() to retrieve their value. 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 the three_finger_flag to FALSE. 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. 5 Timer routines ---------------- 5.1 basic functions * install_timer() -> int 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). * remove_timer() -> None 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. * rest(int) -> None This function waits for the specified number of milliseconds. Passing 0 as parameter will not wait, but just yield. This can be useful in order to "play nice" with other processes. Other values will cause CPU time to be dropped on most platforms. This will look better to users, and also does things like saving battery power and making fans less noisy. Note that calling this inside your active game loop is a bad idea, as you never know when the OS will give you the CPU back, so you could end up missing the vertical retrace and skipping frames. On the other hand, on multitasking operating systems it is good form to give up the CPU for a while if you will not be using it. * get_retrace_count() -> int This function returns the value of the C global variable 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 way of controlling the speed of your program without installing user timer functions. 5.2 timer handlers This is the part of the library which differs most from the C version. With standard Allegro, you can install a number timer handler routines which can perform a variery of different actions, although very simple and quick: these routines are called every given time by the Allegro interrupt handler, and the fact that they are called in an interrupt context is the reason why they cannot perform complex actions such as using system calls or C library functions and others (see Allegro documentation for a detailed description: I'm not a guru of low-level and sytem programming - actually I'm not a guru at all ;-) -, so I don't know much about this topic). This makes impossible to write a timer handler in Python, because it would imply setting up a complex C function which would have to call the Python one. It seems then that we cannot use timers with AlPy: this is only partially true. In fact, we have a simpler but certainly useful option, that is the possibility of setting up counters, i.e. variables incremented every given interval, and setters, that are functions which set the value of a given integer variable; as the most common timer handlers do nothing but incrementing some variables and setting some flags, on most situations our counters and setters will be appropriate. Here are the functions provided: * register_counter(name [, speed [, value [, step]]]) -> int Sets up a counter variable called `name'. This variable will be initialized to `value' and will be incremented with `step' at the provided `speed', measured in hardware clock ticks (you can use the *_TO_TIMER set of functions to convert from other time formats). Speed defaults to one second, value to zero and step to one. After calling this function, the variable is available as an attribute of the global counters object. Example. Suppose you want to create a variable named score which has to be incremented by 10 every 2 seconds, starting from a value of 1000. You can write: alpy.register_counter('score', alpy.SECS_TO_TIMER(2), 1000, 10) Now you can access the variable with counters.score: print 'Your score is: %d' % alpy.counters.score # player killed an enemy: increment score alpy.counters.score += 100 Returns zero on success, or a negative number if there is no room to add a new user counters. You have up to 10 counters and setters. * remove_counter(name) -> None Removes a previously created counter. * register_setter(name [, speed [, value]]) -> int Installs a timer handler which will set the counters attribute name to value with the given speed. If value is a string, the function will search for a counter or setter which name is value, and if found will use such variable's value, otherwise NameError is raised. Returns zero on success, or a negative number if there is no room to add a new user setter. You have up to 10 counters and setters. * remove_setter(name) -> None Removes a previously registered setter. * install_fps() -> int Installs a timer for the purpose of counting the number of frames per second your program is generating. Once installed, you can use incr_frame_count() and get_fps(). Returns zero on success, non zero on error. * remove_fps() -> None Removes the timer counter installed by install_fps(). You can call this even if you haven't called install_fps() before. * get_fps() -> int Returns the number of times incr_frame_count() was called during the last second. * incr_frame_count() -> None Call this after you have displayed a new frame in your program. The number of frames will be acummulated, and every second this value is moved to another variable which is returned by get_fps(). The result is that you can know how many times you were able to show a frame during the last second. 6 Graphics modes routines ------------------------- * set_color_depth(number) -> None 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. Example: alpy.set_color_depth(32); try: alpy.set_gfx_mode(alpy.GFX_AUTODETECT, 640, 480) catch alpy.AlpyException: print "Couldn't set a 32 bit color resolution" Note that the screen color depth won't change until the next successful call to set_gfx_mode(). * get_refresh_rate() -> int Returns the current refresh rate, if known (not all drivers are able to report this information). Returns zero if the actual rate is unknown. * set_gfx_mode(card, w, h, v_w = 0, v_h = 0) -> None 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 color depth of the graphic mode has to be specified before calling this function with set_color_depth(). 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. 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). After you select a graphics mode, the global variables SCREEN_W, SCREEN_H, VIRTUAL_W, and VIRTUAL_H will tell you the real and virtual screen size. This function will raise alpy.AlpyException if the requested graphic mode cannot be set. Example: try: alpy.set_gfx_mode(alpy.GFX_AUTODETECT, 320, 200) except alpy.AlpyException: # Couldn't set graphic mode, abort! sys.exit(1) * get_screen_size() -> width, height, virtual_w, virtual_h This function returns the values which in the Allegro C version would be obtained through the SCREEN_W, SCREEN_H, VIRTUAL_W and VIRTUAL_H macros. All the values are integers. * set_display_switch_mode(mode) -> int Sets how the program should handle being switched into the background, if the user tabs away from it. Not all of the possible modes will be supported by every graphics driver on every platform. 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 switch 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. Returns zero on success, invalidating at the same time all callbacks previously registered with set_display_switch_callback(). Returns -1 if the requested mode is not currently possible. 6 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 objects 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 two bytes per pixel, in 24-bit modes 3 bytes per pixel and in 32-bit modes 4 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. 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(), so you should never attempt to destroy it yourself. * 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 alpy.Bitmap(), load_bitmap(), or by loading a grabber datafile. * Sub-bitmaps. These share image memory with a parent bitmap (which can be the screen, a video or system bitmap, 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). Warning: Make sure not to destroy a bitmap before all of its sub-bitmaps, otherwise bad things will happen when you try to access one of these sub-bitmaps. * Video memory bitmaps. TODO. * System bitmaps. TODO. 7.1 screen variable There is a module screen variable (alpy.screen) which is a global 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. For example, to draw a pixel onto the screen you would write: alpy.screen.putpixel(x, y, color) Or to implement a double-buffered system: # Make a bitmap in RAM. bmp = alpy.Bitmap(320, 200) # Clean the memory bitmap. bmp.clear() # Draw onto the memory bitmap. bmp.putpixel(x, y, color) # Copy it to the screen. bmp.blit() 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). And never try to destroy it with destroy_bitmap(). 7.2 class Bitmap A Python Bitmap object represents a wrapper around the BITMAP struct of the Allegro C version. The most interesting attributes in a Bitmap object are: * w: integer containing the width in pixel of the BITMAP. * h: integer containing the height of the BITMAP. * clip: 4-tuple of integers containing the clipping bounds of the BITMAP if clipping is active, None otherwise. You can access these attributes as usual. Example: print "Width of the bitmap is %d" % some_bitmap.w Constructor: * Bitmap(width, height, **kwds) -> Bitmap This constructor replaces the create_*_bitmap functions of the Allegro C version. The first two parameters are the dimensions of the new Bitmap. The content of the optional parameter kwds depends on the type of the Bitmap you want to create: * type: string which explicitly specifies the kind of the bitmap. It can have the following values: * mem: plain memory bitmap (default if you don't say type) * sub: sub bitmap of another bitmap. * ex: as returned by create_bitmap_ex from Allegro C. * video: video bitmap. * sys: system bitmap. For the 'ex' bitmap type you can specify the color depth of the new bitmap with the keyword 'depth', which can be 8, 15, 16, 24 or 32. For the 'sub' bitmap type you have to specify the parent Bitmap with the keyword 'parent'. This keyword is mandatory and must not be None. Optionally you can use the keywords 'x' and 'y' to specify the starting coordinates inside the parent Bitmap. TODO: Document other types and put examples. This constructor tries to guess which kind of bitmap to create, and raises an exception if the argument list is ambiguous. Bitmap methods: * acquire() -> None Locks the 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! Note that if you are using hardware accelerated VRAM->VRAM blits, you should not call acquire_bitmap(). * arc(x, y, float ang1, ang2, int r, int color) -> None 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 Allegro's binary angle 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. Example: # Draw a black arc from 4 to 1 o'clock. bitmap.arc(bitmap.w/2, bitmap.h/2, -21, 43, 50, alpy.makecol(0, 0, 0)) * blit(dest, self_x, self_y, dest_x, dest_y, width, height, mask) -> None This function replaces the C versions of blit() and masked_blit(). Copies a rectangular area of the source bitmap to the destination bitmap. The self_x and self_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. Example: # Blit the bitmap on the screen. bitmap.blit(alpy.screen, 0, 0, 0, 0, self.w, self.h) # Now copy a chunk to a corner, slightly outside. bitmap.blit(alpy.screen, 100, 100, -10, -10, 25, 30) mask is a boolean parameter, if true, pixels using the mask color of the bitmap's color depth will not be copied over. All of these parameters have a default value: * dest: the screen * self_x and self_y: 0 * dest_x and dest_y: 0 * width: self.w * height: self.h * mask: 0 This means that for the most common situation, which is blitting to the screen from a memory bitmap used for double buffering, this method can be called without arguments. 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. (self_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. In this case, the behavior is affected by the COLORCONV_KEEP_TRANS and COLORCONV_DITHER* flags of the current color conversion mode: see set_color_conversion() for more information. * circle(x, y, radius, color, fill) -> None Draws a circle with the specified centre and radius. The optional parameter fill (defaults to zero) is a boolean. If true, the circle will be filled, otherwise just the outline will be drawn. * clear(color) -> None Clears the bitmap to the optionally specified color. By default color is zero. * depth() -> int Returns the color depth of the bitmap (8, 15, 16, 24, or 32). * draw(dest, x, y, mode, color | colors) -> None Replacement for the various draw_xxx functions of the C library. Please refer to the C documentation for information. Mode can be one of the following: * 'normal': default, simply draws the bitmap onto the given dest * 'trans': draws the bitmap with a translucency effect * 'lit': lightning effect; you must provide a color * 'gouraud': gouraud shading effect; the colors argument must be a 4-tuple of integers * 'character': same as the draw_character function of the C version Note that color and colors are mutually exclusive, i. e. you shouldn't pass both. The only way to do so is to explicitly specify the parameters passed, for example: bitmap.draw(alpy.screen, 0, 0, mode='lit', color='42') * ellipse(x, y, rx, ry, color, fill) -> None Draws an ellipse with the specified centre and radius. The optional parameter fill (defaults to zero) is a boolean. If true, the ellipse will be filled, otherwise just the outline will be drawn. * flip(dest, x, y, direction = 0) -> None Replaces the various draw_sprite_*_flip functions of the C library. direction is an integer which can be zero for a vertical flip, one for a horizontal flip, and two for a diagonal flip. * floodfill(x, y, color) -> None Floodfills an enclosed area, starting at point (x, y), with the specified color. * get(x, y) -> int This method is the most similar thing to accessing the Bitmap's line pointers in the C version of Allegro. They don't do bound checking and just read whatever value your coordinates point at, so be careful! They also work only with memory bitmaps. Operation on other type of bitmap is undefined. Example: # This would be like `val = bmp->line[y][x];' in C. pixel_value = bitmap.get(x, y) * get_compiled() -> CompiledSprite Returns a CompiledSprite object based on this bitmap. * get_mask() -> int 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). A frequent use of this function is to clear a bitmap with the mask color so you can later use this bitmap with masked_blit() or draw_sprite() after drawing other stuff on it. Example: # Replace mask color with another color. mask_color = bmp.get_mask() for y in range(bmp.h): for x in range(bmp.w): if bmp.getpixel(x, y) == mask_color: bmp.putpixel(x, y, another_color) * getpixel(x, y) -> int Reads a pixel from point (x, y) in the bitmap. Returns -1 if the point lies outside the bitmap (ignoring the clipping rectangle), otherwise the value of the pixel in the color format of the bitmap. Warning: -1 is also a valid value for pixels contained in 32-bit bitmaps with alpha channel (when R,G,B,A are all equal to 255) so you can't use the test against -1 as a predicate for such bitmaps. In this cases, the only reliable predicate is is_inside_bitmap(). * get_rle() -> RleSprite Returns an RleSprite object based on this bitmap. * line(x1, y1, x2, y2, color) -> None Draws a line onto the bitmap, from point (x1, y1) to (x2, y2) with the color as an integer value. Example: # Draw diagonal red line. red_color = alpy.makecol(255, 0, 0) bitmap.line(0, 0, bitmap.w, bitmap.h, red_color) * polygon(list_of_coordinates, color) -> None Draws a filled polygon with an arbitrary number of corners. Pass as the first parameter a list of pairs containing x/y coordinates. Example: # Set up some variables. points = [(50, 50), (100, 100), (100, 150), (50, 200), (0, 150), (0, 100)] white = alpy.makecol(255, 255, 255) black = alpy.makecol(0, 0, 0) # Draw a black shape on a white background. alpy.screen.clear(white) alpy.screen.polygon(points, black) * putpixel(x, y, int) -> None Writes a pixel to the specified position in the bitmap, using the current drawing mode and the bitmap's clipping rectangle. Example: alpy.screen.putpixel(10, 30, some_color) * rect(x1, y1, x2, y2, color, fill) -> None Draws rectangle with the two points as its opposite corners. The optional parameter fill (defaults to zero) is a boolean. If true, the rectangle will be filled, otherwise just the outline will be drawn. * release() -> None 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. * rotate(dest, x, y, angle, cx, cy, scale) -> None Draws the bitmap on test placing its top left corner at the specified position, then rotating by the specified angle around the center coordinates (which default to zero). The angle is specified in Allegro's binary circle format, with 256 equal to a full circle, 64 a right angle, etc. The scale parameter defaults to one. This rotation function can draw between any two bitmaps, even screen bitmaps or bitmaps of different color depth. Positive increments of the angle will make the sprite rotate clockwise on the screen, as demonstrated by the Allegro example. * save(filename, palette, type]) -> int Writes a bitmap into a file, using the specified palette The output format is determined from the filename extension: at present this function supports BMP, PCX and TGA formats. If the type cannot be determined from the filename extension, you can provide it explicitly: "bmp", "pcx" or "tga". 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: sub_bitmap = alpy.Bitmap(alpy.screen.w, alpy.screen.h, x = 0, y = 0, parent = alpy.screen) sub_bitmap.save("dump.pcx", alpy.get_palette()) Returns non-zero on error. * set(x, y, color) This method is the most similar thing to accessing the Bitmap's line pointers in the C version of Allegro. They don't do bound checking and just write whatever value you pass, so be careful! They also work only with memory bitmaps. Operation on other type of bitmap is undefined. Example: # This would be like `bmp->line[y][x] = 12;' in C. bitmap.set(x, y, 12) * set_clip(x1, y1, x2, y2) -> None Each bitmap has an associated clipping rectangle, which is the area of the image that it is ok to draw onto. Nothing will be drawn to positions outside this space. This function sets the clipping rectangle. Pass the coordinates of the top-left and bottom-right corners of the clipping rectangle in this order; these are both inclusive, i.e. set_clip(16, 16, 32, 32) will allow drawing to (16, 16) and (32, 32), but not to (15, 15) and (33, 33). Drawing operations will be performed (at least partially) on the bitmap as long as the first coordinates of its clipping rectangle are not greater than the second coordinates and its intersection with the actual image is non-empty. If either condition is not fulfilled, drawing will be turned off for the bitmap, e.g. set_clip_rect(0, 0, -1, -1) # disable drawing on bmp Note that passing "out-of-bitmap" coordinates is allowed, but they are likely to be altered (and so the coordinates returned by get_clip() will be different). However, such modifications are guaranteed to preserve the external effect of the clipping rectangle, that is not to modify the actual area of the image that it is ok to draw onto. * spline(points, color) -> None Draws a bezier spline using the four control points specified in the points list. Each point should be a 2 int pair. You can generate such input with alpy.calc_spline(). * stretch(dest, x, y, w, h) -> None Stretches the current bitmap to the specified width and height on dest, using the coordinates x, y. The source and dest images have to be of the same color depth. Moreover, the source image must be a memory bitmap. * stretch_blit(dest, self_x, self_y, self_width, self_height, dest_x, dest_y, dest_width, dest_height, mask) -> None 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. The default values for each parameter are: * dest: the screen * self_x, self_y: 0 * self_width, self_height: self.w, self.h * dest_x, dest_y: 0 * dest_width, dest_height: self.w, self.h * mask: 0 * textout(font, text, x, y, color [, align [, x2 [, diff]]]) -> None Writes the string `s' onto the bitmap at position x, y, using the specified font and foreground color. 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. For high and true color fonts, the foreground color is ignored and always treated as -1. The align, x2 and diff parameters are optional. Align can have the following values: * left: this is the default * center * right * justify When the alignment is justify, textout will draw 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. Examples: # Write a blue hello string. alpy.screen.textout(alpy.font, "hello", 10, 10, alpy.makecol(0, 0, 255)) 7.3 Bitmaps and the Python Imaging Library The Python Imaging Library (PIL, http://www.pythonware.com/products/pil/) adds image processing capabilities to Python. It supports many file formats, and provides powerful image processing and graphics capabilities. On top of the Bitmap methods listed in the previous section, there are other methods which perform conversions from/to PIL, thus allowing exchange of graphical data between libraries. * fromstring(mode, w, h, s, stride) -> alpy.Bitmap() This is a static method which creates a Bitmap from a string of raw color data. The mode parameter should be one of the strings 'RGB', 'RGBA', 'ARGB', 'BGR', 'BGRA' or 'ABGR'. w and h are integers specifying the size of the raw image, and s is the string containing the source raw image. By default, it is assumed that rows are packed in without any extra padding; to change this, supply the stride argument, which specifies the size in bytes of each row. * frompil(Image.Image) -> alpy.Bitmap This is a static method which creates an alpy Bitmap from a Python Imaging Library (PIL) Image.Image instance. The conversion is done in RGB format, so any alpha channel will be lost. To call this method, it is required that PIL be installed, otherwise ImportError will be raised. * tostring(mode, stride) -> str Converts the bitmap into a string of color data specified by the mode parameter. By default mode is the string 'RGB', but you can pass also 'RGBA', 'ARGB', 'BGR', 'ABGR' or 'BGRA' for different types of conversion. The stride parameter is by default -1, which assumes that rows are packed without any extra padding. If you need to change this, provide as the stride parameter the size of each row in bytes. * topil() -> Image.Image Converts the bitmap to a Python Imaging Library Image.Image instance. The conversion is done in RGB format, so any alpha channel will be lost. This method will raise an ImportError exception if PIL is not installed. 7.4 functions * load_bitmap(filename, type) -> (alpy.Bitmap, alpy.Palette) Loads the specified filename. If you don't provide a type, Allegro will try to figure it out by the extension of the filename. If type is provided, it can be one of the following: bmp, pcx, tga, lbm. 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 function returns a tuple with the bitmap and its palette and raises AlpyException if there was some problem. Example: try: bmp, pal = alpy.load_bitmap("image.pcx") catch alpy.AlpyException: print "Couldn't load image.pcx" 8. RleSprite objects -------------------- Because bitmaps can be used in so many different ways, the Bitmap object 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 an RleSprite or CompiledSprite object 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() method. There is no RleSprite constructor, but you can convert a Bitmap into RleSprite at runtime, or you can create RleSprite objects structures in grabber datafiles by making a new object of type 'RLE sprite'. 8.1 class RleSprite A Python RleSprite object represents a wrapper around the RLE_SPRITE struct of the Allegro C version. The most interesting attributes of an RleSprite object are: * w: integer containing the width in pixels of the sprite. * h: integer containing the height of the sprite. Note that RleSprite objects don't have a constructor because they can't be created directly. You must obtain them with the get_rle() method of a Bitmap object or by a datafile access. RleSprite methods: * draw(self, dest, x, y [, mode [, color]]): Draws the sprite onto the Bitmap dest with the top left corner at position (x,y). The optional mode can be one of the following: * 'normal': this is the default. * 'trans': skips transparent pixels. * 'lit': uses a lightning effect; you must provide a color. 9. CompiledSprite objects ------------------------- 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'. 9.1 class CompiledSprite A Python CompiledSprite object represents a wrapper around the COMPILED_SPRITE struct of the Allegro C version. The most interesting attributes of a CompiledSprite Object are: * w: integer containing the width in pixels of the sprite. * h: integer containing the height of the sprite. Note that CompiledSprites objects don't have a constructor because they can't be created directly. You must obtain them with the get_compiled() method of a Bitmap object or by a datafile access. CompiledSprite methods: * draw(self, dest, x, y): Draws the sprite onto the Bitmap dest with the top left corner at position (x,y). 10. Font objects --------------- Allegro provides routines for loading fonts directly from GRX format .fnt files, 8x8 or 8x16 BIOS format .fnt files, from bitmap images, from datafiles or you can import a multiple-range Unicode font by writing a .txt script that specifies a number of different source files for each range of characters. By default, Allegro can only use bitmapped (non-scalable) fonts. If you want to use TrueType fonts, you will need to use an add-on library which allows you to load them on the fly (like AllegTTF or Glyph Keeper, listed among others at http://www.allegro.cc/) and render them directly, or generate a bitmapped version of a TrueType font with tools like TTF2PCX (http://www.talula.demon.co.uk/ttf2pcx/index.html). 10.1 font variable There is a module font variable (alpy.font) which is a simple 8x8 fixed size font (the mode 13h BIOS default). 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. You can use this global font for text output if you don't have your own. 10.2 class Font A Font object represents a wrapper around the FONT struct of the Allegro C version. There are no interesting attribtues in a Font object. There is a method, though. You don't go around creating fonts at runtime, you usually have to load them from a bitmap or datafile. Font methods: * size(string = "") -> (width, height) Returns the width and height in pixels of the string displayed with this font. If no string is provided, an empty string is used by default. 12 Drawing functions -------------------- Most of the Allegro C drawing functions (like line(), ellipse(), spline(), etc) are implemented in this Python wrapper as Bitmap methods, because they all operate on bitmaps and it's the most natural place to put them. Here are those functions which don't directly relate to a Bitmap object, and can be thus used without creating one before. * calc_spline([(x, y), ...4], npts) -> [(x, y), ...npts] Calculates a series of npts values along a bezier spline, returning them as a list of pairs. The bezier curve is specified by the four x/y control points in the input list: pair 1 contains the coordinates of the first control point, pair 2 is 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.py. Example: points = [(0, 0), (0, 100), (100, 100), (100, 0)] bezier_points = alpy.calc_spline(points, 5) # Coordinates of the bezier curve's tip. print bezier_points[2] * text_mode(int) -> int Sets the default background color in which text will be drawn (with Bitmap.textout()). If you pass a negative value, text will be drawn transparently (ie. the background will not be altered). The default is a value of zero. 12 Palette objects ------------------ 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 object, which contains red, green and blue intensities in the VGA hardware format, ranging from 0-63. For example: black = alpy.Rgb(0, 0, 0 ) white = alpy.Rgb(63, 63, 63) green = alpy.Rgb(0, 63, 0 ) grey = alpy.Rgb(32, 32, 32) A Palette object is a sequence of 256 Rgb objects. 12.1 class Rgb An Rgb object wraps around the individual RGB C triplet of Allegro. There are no useful methods in this object, because it just holds three values, which you can access through the attributes r, g and b. Example: red = rgb_object.r green = rgb_object.g blue = rgb_object.b Constructor: * Rgb(red = 0, green = 0, blue = 0) -> Rgb This constructor builds a new Rgb object with the specified color values, ranging from 0 to 63, and which default to 0. Example: black = alpy.Rgb() white = alpy.Rgb(63, 63, 63) 12.2 class Palette Palette objects are sequences of 256 Rgb objects. You can access them as if they were a list, but you can't modify them in place, because each read access creates a different Rgb object. If you want to modify a Palette entry, you have to create an Rgb object and assign it to the Palette entry. Example: palette = alpy.Palette() entry = palette[0] entry.r = 0 palette[0] = entry Constructor: * Palette() -> Palette Constructs a Palette object, which is a sequence of 256 Rgb objects. 12.3 functions * vsync() -> None 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. * get_palette(from = 0, to = 255) -> alpy.Palette Retrieves the entire palette of 256 colors currently used. If you specify any of the default parameters, entries outside of the specified range will contain random values. Example: palette = alpy.get_palette() * set_palette(palette_object, from, to, vsync) -> None Provide a Palette object to set the palette. Optionally you can provide the parameters from, to and vsync, all of them integers. The from and to parameters specify only a range of the palette. If vsync is not zero, the function will wait for the vertical retrace before setting the palette to avoid flickering. * set_color(palette_index, rgb_object) -> None Sets the specified palette entry to the specified RGB object. Unlike the other palette functions this doesn't do any retrace synchronisation, so you should call vsync() before it to prevent snow problems. Example: alpy.vsync() alpy.set_color(192, alpy.Rgb(23, 23, 23)) * get_color(palette_index) -> alpy.Rgb Returns the specified palette entry. Example: color = alpy.get_color(11) * fade_interpolate(pal_source, pal_dest, pos, from, to) -> alpy.Palette Calculates a temporary palette part way between source and dest, and returns it. The position between the two extremes is specified by the pos value: 0 returns an exact copy of pal_source, 64 returns pal_dest, 32 returns a palette half way between the two, etc. This routine only affects colors between `from' and `to' inclusive. Both `from' and `to' are optional parameters, which default to 0 and 255. Examples: pal = alpy.fade_interpolate(pal_a, pal_b, 32) pal = alpy.fade_interpolate(pal_a, pal_b, 48, 10) pal = alpy.fade_interpolate(pal_a, pal_b, 11, 100, 250) * fade_from(pal_source, pal_dest, speed, from, to) -> None Fades gradually 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. Both `from' and `to' are optional parameters, which default to 0 and 255. Example: current = alpy.get_palette() alpy.fade_from(current, alpy.desktop_palette, 1) Note that this function will block your game while the fade is in effect, and it won't work right visually if you are not in an 8 bit color depth resolution. * fade_in(alpy.Palette, speed, from, to) -> None Fades gradually 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. Both `from' and `to' are optional parameters, which default to 0 and 255. Example: alpy.fade_in(alpy.desktop_palette, 1) Note that this function will block your game while the fade is in effect, and it won't work right visually if you are not in an 8 bit color depth resolution. * fade_out(alpy.Palette, speed, from, to) -> None Fades gradually 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. Both `from' and `to' are optional parameters, which default to 0 and 255. Example: alpy.fade_out(2, 126) Note that this function will block your game while the fade is in effect, and it won't work right visually if you are not in an 8 bit color depth resolution. * generate_332_palette() -> alpy.Palette Constructs a fake truecolor palette, using three bits for red and green and two for the blue. The bitmap loading function returns this as the palette element of its tuple if the file does not contain a palette itself (ie. you are reading a truecolor bitmap). * set_color_conversion(flags) -> None 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. 12.4 objects * default_palette A module variable Palette object, which contains the default IBM BIOS palette. This will be automatically selected whenever you set a new graphics mode. The palette contains 16 basic colors plus many gradients between them. If you want to see the values, you can write a small Allegro program which saves a screenshot with this palette, or open the grabber tool provided with Allegro and create a new palette object, which will use this palette by default. * black_palette A palette containing solid black colors, used by the fade routines. * 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 :-) The contents of this palette are 16 colors repeated 16 times. Color entry zero is equal to color entry 16, which is equal to color entry 24, etc. Index Color RGB values 0 White 63 63 63 1 Red 63 0 0 2 Green 0 63 0 3 Yellow 63 63 0 4 Blue 0 0 63 5 Pink 63 0 63 6 Cyan 0 63 63 7 Grey 16 16 16 8 Light grey 31 31 31 9 Light red 63 31 31 10 Light green 31 63 31 11 Light yellow 63 63 31 12 Light blue 31 31 63 13 Light pink 63 31 63 14 Light cyan 31 63 63 15 Black 0 0 0 13 Truecolor routines --------------------- 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! 13.1 functions * makecol(r, g, b, alpha, depth) -> int Converts colors from a hardware independant format (red, green, blue and alpha, values ranging from 0 to 255) to the pixel format specified by depth. Both alpha and depth are optional parameters and can be ommited. If no depth is specified the returned integer will be for the currently set color depth. Examples col = makecol(255, 128, 233) col = makecol(255, 128, 233, 128) col = makecol(255, 128, 233, 255, 8) * getr(color, depth) -> int Returns the red component part of the given color. The parameter depth is optional. If not specified, the function assumes that the color is in the format used by the current video mode. * getg(color, depth) -> int Returns the green component part of the given color. The parameter depth is optional. If not specified, the function assumes that the color is in the format used by the current video mode. * getb(color, depth) -> int Returns the blue component part of the given color. The parameter depth is optional. If not specified, the function assumes that the color is in the format used by the current video mode. * geta(color, depth) -> int Returns the alpha component part of the given color. The parameter depth is optional. If not specified, the function assumes that the color is in the format used by the current video mode. 13.2 objects * palette_color This is a list of 256 Rgb objects indexing 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. Example: alpy.set_color_depth(32); ... alpy.set_palette(alpy.desktop_palette); # Put a pixel with the color 2 (green) of the palette. alpy.screen.putpixel(100, 100, alpy.palette_color[2]) 14 Pattern drawing and color mapping ------------------------------------ 14.1 functions * drawing_mode(mode, pattern, x_anchor, y_anchor) -> None Sets the graphics drawing mode witha constant. The pattern, x_anchor and y_anchor are all optional parameters. pattern should be a Bitmap object (defaults to None) and x_anchor and y_anchor integer values (which default to zero). This function 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. * xor_mode(bool) -> None This is a shortcut for toggling xor drawing mode on and off. Calling xor_mode(True) is equivalent to drawing_mode(DRAW_MODE_XOR, None, 0, 0). Calling xor_mode(False) is equivalent to drawing_mode(DRAW_MODE_SOLID, None, 0, 0). * solid_mode() -> None This is a shortcut for selecting solid drawing mode. It is equivalent to calling drawing_mode(DRAW_MODE_SOLID, None, 0, 0). * set_color_map(color_map) -> None Sets the global color mapping table which will be used by any translucent or lit drawing functions in 256 color video modes. Example: c = alpy.ColorMap() # Here, modify 'c' to suit your needs. alpy.set_color_map(c) * create_color_map(palette, colors_or_blend [, callback [, type]]) -> ColorMap This single function replaces the three color map creation functions of the Allegro C version: create_light_table, create_trans_table and create_color_table. The meaning of colors_or_blend depends on the kind of color map you want to build: if you want a light or trans table, it must be a 3-tuple of integers in the range 0-63, while if you want a custom effect, it must be a callable object accepting 3 arguments: a Palette and two integers, and returning a Rgb object (again, see Allegro documentation for details). Type is a string which actually determines the kind of effect, and it can be: "blend", "trans", "light". If it is missing, the function tries to guess the effect by checking if colors_or_blend is callable: if so, it will be used to fill the returned color map, otherwise a light table will be created. callback is an optional parameter which, if present, will be called 256 times during the calculation, allowing you to display a progress indicator. * create_light_table(pal, r, g, b, callback = None) -> table Creates and returns a 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 None, it will be called 256 times during the calculation, allowing you to display a progress indicator. This callback function will be passed a parameter indicating the position of the process as an integer from 0 to 255. This is the same as calling: create_color_map(pal, (r, g, b), callback, type="light"). * create_trans_table(pal, r, g, b, callback = None) -> table Creates and returns a 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 None, it will be called 256 times during the calculation, allowing you to display a progress indicator. This callback function will be passed a parameter indicating the position of the process as an integer from 0 to 255. This is the same as calling: create_color_map(pal, (r, g, b), callback, type="trans"). * create_color_table(pal, blend, callback = None) -> table Creates and returns a 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. If the callback function is not None, it will be called 256 times during the calculation, allowing you to display a progress indicator. This callback function will be passed a parameter indicating the position of the process as an integer from 0 to 255. This is the same as calling: create_color_map(pal, (r, g, b), callback, type="blend"). * set_blender(type, r, g, b, a) -> None Sets the given blender mode. The meaning of r, g, b and a depends on the chosen type, which is one of: * TRANS: translucent * ADD: additive * BURN * COLOR * DIFFERENCE * DISSOLVE * DODGE * HUE * INVERT * LUMINANCE * MULTIPLY * SATURATION * SCREEN For details of the various blender modes, see the documentation of the different set_*_blender functions. * set_trans_blender(int r, int g, int b, int a) -> None Enables a linear interpolator blender mode for combining translucent or lit truecolor pixels. This is the same as calling set_blender(TRANS, ...). * set_alpha_blender(bool_mode) -> None If the boolean parameter is zero (the default value), 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. If the boolean parameter is non zero, 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. * set_write_alpha_blender() -> None Shortcut which calls set_alpha_blender(1). * set_add_blender(int r, int g, int b, int a) -> None Enables an additive blender mode for combining translucent or lit truecolor pixels. This is the same as calling set_blender(ADD, ...). * set_burn_blender(int r, int g, int b, int a) -> None 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. This is the same as calling set_blender(BURN, ...). * set_color_blender(int r, int g, int b, int a) -> None 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. This is the same as calling set_blender(COLOR, ...). * set_difference_blender(int r, int g, int b, int a) -> None 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. This is the same as calling set_blender(DIFFERENCE, ...). * set_dissolve_blender(int r, int g, int b, int a) -> None 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 :). This is the same as calling set_blender(DISSOLVE, ...). * set_dodge_blender(int r, int g, int b, int a) -> None 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. This is the same as calling set_blender(DODGE, ...). * set_hue_blender(int r, int g, int b, int a) -> None Enables a hue blender mode for combining translucent or lit truecolor pixels. This applies the hue of the source to the destination. This is the same as calling set_blender(HUE, ...). * set_invert_blender(int r, int g, int b, int a) -> None Enables an invert blender mode for combining translucent or lit truecolor pixels. Blends the inverse (or negative) colour of the source with the destination. This is the same as calling set_blender(INVERT, ...). * set_luminance_blender(int r, int g, int b, int a) -> None 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. This is the same as calling set_blender(LUMINANCE, ...). * set_multiply_blender(int r, int g, int b, int a) -> None 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. This is the same as calling set_blender(MULTIPLY, ...). * set_saturation_blender(int r, int g, int b, int a) -> None Enables a saturation blender mode for combining translucent or lit truecolor pixels. Applies the saturation of the source to the destination image. This is the same as calling set_blender(SATURATION, ...). * set_screen_blender(int r, int g, int b, int a) -> None 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. This is the same as calling set_blender(SCREEN, ...). * create_blender_table(palette, callback) -> ColorMap Returns a color mapping table with lookup data for doing a paletted equivalent of whatever truecolor blender mode is currently selected. After calling set_trans_blender() or set_blender(), 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. callback is an optional parameter which, if present, will be called 256 times during the calculation, allowing you to display a progress indicator. * set_rgb_map(RgbMap) -> None 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() and some create_*_table() functions. RGB tables can be precalculated with the rgbmap utility, or generated at runtime with create_rgb_table(). * create_rgb_table(palette, callback) -> RgbMap Creates an rgb mapping table with lookup data for the given palette. callback is an optional parameter which, if present, will be called 256 times during the calculation, allowing you to display a progress indicator. Example: pal = alpy.get_palette() table = alpy.create_rgb_table(pal) * hsv_to_rgb(hue, saturation, value) -> (red, green, blue) Converts color values from HSV to RGB colorspace. The RGB values range from 0 to 255, hue is from 0 to 360, and saturation and value are from 0 to 1. Example: h, s, v = alpy.rgb_to_hsv(255, 0, 128) r, g, b = alpy.hsv_to_rgb(h, s, v) # Verify everything was converted correctly. assert r == 255 assert g == 0 assert b = 128 * rgb_to_hsv(red, green, blue) -> (hue, saturation, value) Converts color values from RGB to HSV colorspace. The RGB values range from 0 to 255, hue is from 0 to 360, and saturation and value are from 0 to 1. Example: h, s, v = alpy.rgb_to_hsv(255, 0, 128) r, g, b = alpy.hsv_to_rgb(h, s, v) # Verify everything was converted correctly. assert r == 255 assert g == 0 assert b = 128 14.2 class ColorMap 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. A ColorMap objects contains such a 64k lookup table, which you can set with alpy.set_color_map(). Use ColorMap set/get methods to modify it. Constructor: * ColorMap() -> ColorMap Constructs a ColorMap object. These represent lookup tables necessary to achieve lighting or translucency effects. Methods: * get(write_color, read_color) -> final_color Returns the color map entry which Allegro will use when painting pixels of write_color over pixels of read_color. Remember that these values are indices to the currently active palette. * set(write_color, read_color, final_color) -> None Sets the color map entry which Allegro will use when painting pixels of write_color over pixels of read_color. Remember that these values are indices to the currently active palette. 14.3 class RgbMap An RgbMap object is used to speed up reducing RGB values to 8-bit paletted colors. You might want to use the RgbMap constructor to fill the values yourself, or alpy.create_rgb_table to generate an RgbMap from an existing Palette. Constructor: * RgbMap() -> RgbMap Constructs an RgbMap object. These are used to speed up reducing RGB values to 8-bit paletted colors. Methods: * get(x, y, z) -> int Retrieves the color and the specified entry. * set(x, y, z, color) -> None Sets the specified entry to the given color. 15 Sound objects and routines ----------------------------- 15.1 class Sample A Python Sample object represents a wrapper around the SAMPLE struct of the Allegro C version. The most interesting attributes in a Sample are: * bits: integer with the value 8 or 16. * freq: integer containing the frequency. * stereo: integer, non zero for stereo files. * len: length in samples. * loop: 2-tuple containing loop start and loop end position. You have to consider all of these fields as read only variables, unlike the C struct. Constructor: * Sample(filename) -> Sample Constructs a Sample object from a file on disk. Example: sound = alpy.Sample("bell.voc") Allegro can by default load mono and stereo WAV and mono VOC files, in 8 or 16-bit formats. Raises AlpyException on error. Methods: * play(vol, pan, freq, loop) -> int Triggers a sample at the specified volume, pan position, and frequency. All the parameters are optional and have default values. vol is the volume, ranging from 0 to 255 (min/max) with 255 being the default value. pan is the panning, ranging from 0 to 255 (left/rigth) with 128 being the default value. freq is a relative frequency: 1000 (the default) represents the frequency that the sample was recorded at, 2000 is twice this, etc. Loop is by default set to zero. If not zero, the sample will repeat until you call stop(), and can be manipulated while it is playing by calling adjust_sample(). Example: scream = alpy.Sample("scream.wav") # Shout loud from the left speaker, twice the freq. scream.play(255, 0, 2000) Returns the voice number that was allocated for the sample or negative if no voices were available. * adjust(vol, pan, freq, loop) -> None 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. The values of the parameters are just like those of Sample.play(). 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. * stop() -> None 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. 15.2 class Midi Constructor: * Midi(filename) -> Midi Constructs a Midi object from a file on disk. Raises AlpyException on error. Example: music = alpy.Sample("wagner.mid") Methods: * play(loop, loop_start, loop_end) -> None Playes the MIDI. All the parameters are optional. If loop is set, the file will be repeated continuously. loop_start and loop_end are by default the begin and end positions, but you can provide other values. 15.3 functions * detect_digi_driver(driver_id) -> voices Detects whether the specified digital sound device is available. This function must be called _before_ install_sound(). Returns the maximum number of voices that the driver can provide, or zero if the hardware is not present. Example: print alpy.detect_digi_driver(alpy.DIGI_ESD) => 0 print alpy.detect_digi_driver(alpy.DIGI_ALSA) => 64 * detect_midi_driver(driver_id) -> voices Detects whether the specified MIDI sound device is available. This function must be called _before_ install_sound(). 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. print alpy.detect_midi_driver(alpy.MIDI_OSS) => 0 * reserve_voices(digi_voices, midi_voices) -> None 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. * install_sound(digi_driver, midi_driver) -> None Initialises the sound module. If you don't specify any driver (both parameters are optional), Allegro will use internally DIGI_AUTODETECT and MIDI_AUTODETECt, 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 function raises an exception if there is a problem. * remove_sound() -> None 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. * set_volume(digi, midi) -> None 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. Values bigger than 255 will be reduced to 255. This routine will not alter the volume of the hardware mixer if it exists (i.e. only your application will be affected). * stop_midi() -> None Stops whatever music is currently playing. * midi_pause() -> None Pauses the midi player. * midi_pause() -> None Resumes playback of a paused MIDI file. * midi_seek(target) -> int 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. * get_midi_pos() -> int Returns the current position (beat number) in the MIDI file, or 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. * get_midi_loop() -> (start, end) Returns a tuple with the loop start and end points, set by the midi_object->play() method. * set_midi_loop(start, end) Sets the loop start and end points. These may safely be altered while the music is playing, but you should be sure they are always set to sensible values (start < end). Setting these values to -1 represents the start and end of the file respectively. 16 Basic FLIC routines ---------------------- * play_fli(filename_or_data, bmp, loop, callback) -> int Plays an Autodesk Animator FLI or FLC animation file on the specified BITMAP, reading the data from disk as it is required. If the first argument is a string, it will be considered a filename; otherwise, it will be considered a memory location into which a FLI/FLC animation is stored. If the optional parameter `loop' is not zero, 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 optional `callback' parameter is a function, 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 and FLI_ERROR if something went wrong. 17 Datafiles ------------ Datafiles are created by the grabber utility (see grabber.txt in the Allegro documentation for more information), 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. You could distribute your bitmaps and samples in a myriad of separate files, but packing them in a few `.dat' binaries has a few advantages: * On some platforms loading a single big datafile at once is faster than loading individual resources one by one. * Instead of several loops for your resources, you can write a single line of code with just a single point of failure to take care of. * You can potentially reduce the size of your data by enabling compression on your datafiles. Less download time for your end users, less wait during loading screens! * If you don't need to load the whole datafile at once, you can still enable individual file compression. It is slightly worse than global compression, but it is very fast with loading times because Allegro can easily seek inside the datafile to find a specific object. * Even without encryption, most end users of your application won't be able to look at or modify the resources for your game. A missing sound file or a modified bitmap could potentially crash the game if you haven't considered this in your loading code! * It looks much more professional and convenient to distribute levels! For example, if you found a bug in a level of your game, just distribute your new `level4.dat' and tell users to overwrite their old version. Allegro allows you to load datafiles once and forget about them. But if you have many levels it can be wise to load only the resources required for the current level. You can accomplish the later by separating levels in different datafiles, or using functions like load_datafile_object() to avoid loading everything at once. The C version of Allegro allows you to attach datafiles to your binary. It is not yet clear if this could be done for Alpy, since there is no binary per se to attach your datafiles to. You could, theoretically, create a C binary linked against python, which would startup alpy inside of it, and maybe then it would work. Remember that with Allegro truecolor images can only be loaded after you have set a graphics mode. This is true for datafiles too. Load all your data after you have set the graphics mode, otherwise the pixel format (RGB or BGR) will not be known and the datafile may be converted wrongly. Oh, and read carefully the warning of fixup_datafile() if you plan on switching resolutions during runtime. Note: even though Allegro datafiles provide encryption, you should consider it weak, so don't plan on hiding there the plans for a Death Star or something. Determinate knowledgeable users will be able to rip your resources no matter how hard you try to hide them! Use the encryption only as a slight deterrent towards unwanted tampering of your data. How to crack an encrypted datafile is left as an exercise to the reader, though. Using datafiles once they are loaded is quite simple in the C version of Allegro: you access the elements of the DATAFILE as a normal array once you have generated a .h header file with grabber. To get the same functionality in python, just use the script 'h2py.py' (you can find it in the Tools/scripts subdir of your python distribution) to convert such header into a python module, and then import it. Read chapter "Using datafiles" in the Allegro documentation for more information about header generation. 17.1 class Datafile A Datafile object represents a wrapper around the DATAFILE struct of the Allegro C version. The most interesting attributes in a Datafile object are: * dat: reference to the object stored in the Datafile. * type: type of the dat object. It can be one of the following: * DAT_FILE: the content is a sub-datafile * DAT_FONT * DAT_BITMAP * DAT_RLE_SPRITE * DAT_C_SPRITE * DAT_PALETTE * DAT_FLI: dat is a FLI/FLC animation * DAT_SAMPLE * DAT_MIDI Constructor: * Datafile(filename, obj_name = None) -> Datafile or [Datafile, ...] Constructor for datafiles. When the obj_name parameter is none, the whole datafile will be loaded, returning a list of Datafile objects. If you pass a valid obj_name, only a single Datafile object will be returned. The function will raise AlpyException if there are problems. 17.2 functions * load_datafile(filename) -> [Datafile, ...] Loads a datafile returning a list of Datatafile objects. Raises AlpyException on failure. Consider using alpy.Datafile() instead, which is a convenience wrapper on top of this function. Example: # These two lines both do the same. data = alpy.load_datafile("data.dat") data = alpy.Datafile("data.dat") * unload_datafile([Datafile, ...]) -> None Frees the memory used by the list of Datafile objects. You don't need to call this function because the memory is automatically freed when there are no more references to the list. Example: # These two lines both do the same. alpy.unload_datafile(data_list) del data_list * load_datafile_object(dat_filename, obj_filename) -> Datafile Loads a single object from the datafile and returns it as a Datafile object. Raises AlpyException on failure. Consider using alpy.Datafile() instead, which is a convenience wrapper on top of this function. Example: # These two lines both do the same. alpy.load_datafile_object("data.dat", "ASTEROID01") alpy.Datafile("data.dat", "ASTEROID01") * unload_datafile_object(Datafile) -> None Frees the memory used by a Datafile object. You don't need to call this function because the memory is automatically freed when there are no more references to the object. Example: # These two lines both do the same. alpy.unload_datafile_object(object) del object * fixup_datafile([Datafile, ...]) -> None 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). Note that you can only call this once and expect it to work correctly, because after the call the DATAFILE you fixed up is permanently converted to whatever is the current component ordering for your screen mode. If you call fixup_datafile again, the function assumes you have a freshly loaded datafile. It cannot "undo" the previous conversion. If your program supports changing resolution and/or color depth during runtime, you have two choices: either call fixup_datafile() just once and hope that the component ordering and bit depth doesn't change when the screen mode changes (unlikely). Or, you can reload your datafiles when the screen mode changes. Example: data = alpy.Datafile("data.dat") alpy.fixup_datafile(data)