Graphics modes

Graphics modes are the common denominator for most Allegro programs. While it is possible to write platform specific programs using Allegro which don't set a graphic mode through the routines provided in this chapter, these are not very common.

The first thing to note is that due to the wide range of supported platforms, a graphic mode is the only way to safely communicate with the user. When Allegro was a DOS only library (versions 3.x and previous), it was frequent for programmers to use functions from the C standard library to communicate with the user, like calling printf() before setting a graphic mode or maybe scanf() to read the user's input. However, what would happen for such a game running under Windows where there is no default console output or it may be hidden from the user? Even if the game compiled successfully, it would be unplayable, especially if there was vital information for the user in those text only messages.

Allegro provides the allegro_message() function to deal with this problem, but this is not a very user friendly method of communicating with the user and its main purpose is displaying small error like messages when no graphic mode is available. Therefore, the first thing your Allegro program should do is set a graphic mode, and from there on, use Allegro's text output routines to display messages to the user, just like `allegro/examples/exhello.c' does.

Setting a graphic mode involves deciding how to allocate the memory of the video card for your program. On some platforms this means creating a virtual screen bigger than the physical resolution to do hardware scrolling or page flipping. Virtual screens can cause a lot of confusion, but they are really quite simple. Warning: patronising explanation coming up, so you may wish to skip the rest of this paragraph. Think of video memory as a rectangular piece of paper which is being viewed through a small hole (your monitor) in a bit of cardboard. Since the paper is bigger than the hole you can only see part of it at any one time, but by sliding the cardboard around you can alter which portion of the image is visible. You could just leave the hole in one position and ignore the parts of video memory that aren't visible, but you can get all sorts of useful effects by sliding the screen window around, or by drawing images in a hidden part of video memory and then flipping across to display them.

For example, you could select a 640x480 mode in which the monitor acts as a window onto a 1024x1024 virtual screen, and then move the visible screen around in this larger area (hardware scrolling). Initially, with the visible screen positioned at the top left corner of video memory, this setup would look like:
      (0,0)------------(640,0)----(1024,0)
	|                  |           |
	|  visible screen  |           |
	|                  |           |
      (0,480)----------(640,480)       |
	|                              |
	|   the rest of video memory   |
	|                              |
      (0,1024)--------------------(1024,1024)
With a virtual screen bigger than the visible screen you can perform smooth CPU inexpensive scrolling: you draw your graphics once, and then only tell the video card to show a different portion of the screen. However, virtual screens are not supported on all platforms, and on some they might be emulated through software, losing any performance. On top of that, many video cards only allow horizontal scrolling in steps of 32 bytes. This is not a problem if your game runs in 24 or 32 bit, but it tends to mean jerky scrolling for other color depths.

The other reason you could use virtual screens for is page flipping. This means showing one portion of the virtual screen while your program draws to the hidden one. When you finish, you show the part you have been drawing to and repeat the process with the area now hidden. The result is a perfectly smooth screen update without flickering or other graphical artifacts.

Scrolling manually to one part of the video memory is one non portable way to accomplish this. The portable way is to use functions like create_system_bitmap(), create_video_bitmap(), show_video_bitmap(), etc. These functions divide the memory of the video card in areas and switch between them, a feature supported on all platforms and video cards (given that they have enough memory for the screen resolutions you asked for).

The last thing you need to know about setting a graphic mode are drivers. Each platform has a number of graphic drivers wich support a different range of hardware or behave in different ways. To avoid cluttering your own code with #ifdefs and dealing with drivers added after you release your program, Allegro provides several so called magic drivers. These magic drivers don't really exists, they wrap around a specific kind of functionality.

The magic drivers you can use are: