Drawing Images Slowly

The time has come to explain the statements from the previous graphics programs, which were introduced without any explanation.

The first statement in our programs was:

    if (allegro_init()!=0) return 1;

You might have some slight problems if you attempt to debug programs that use the Allegro library. If you start the debbugger by the step into command (F10), it will not break the program at the first line of the function main, but at some strange place instead.

We suggest that you start the debbuging by using the run-to-cursor command (Ctrl-F10) instead. Also, while the program is paused, it will not display any image in the output window.

It prepares the Allegro library for use. It is not allowed to call most functions from Allegro library before this function[*] is called. allegro_init will return the value 0 when everything goes OK. Thus, if it returns another value, then something went very wrong. In such a case, we will abort the execution of the function main by using the return keyword. This will also abort the execution of the entire program.

It is common to make programs return the value 0 when everything goes OK, and another value when an error happens. But this is not obligatory, just a common practice.

The next statement was:

    set_color_depth(32);

It will make the program use 32-bit colors. If you were to omit this statement, then the default setting would be used. In the Allegro library the default setting is the 8-bit color mode, which uses just 256 colors. In such a case, your OS might also be forced to change the graphics mode of the desktop, as most today's OS desktop environments run in 32-bit color mode.

The next statement opens a window having a display surface of size 800 by 600 pixels. If the OS cannot do that, the function set_gfx_mode will return a non-zero value. In such a case, the return statement will make the program quit with a code 2.

if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0)!=0) return 2;

The create_bitmap function will create a new drawing surface, and the parameters of this function describe the size of the surface. We could have just used the numbers 800 and 600, but we used the values SCREEN_W and SCREEN_H instead. Those two names are assigned the width and height of the display surface by Allegro while processing the previous statement.

    BITMAP* surface = create_bitmap(SCREEN_W, SCREEN_H);

In our future programs, we will be avoiding the use of literal[*] number values. Literal number values are commonly called magic numbers because it might be unclear to the reader of the program what those numbers are intended to represent. If we were to write the literal value 800 instead of SCREEN_W in this statement, a reader of the program would have no way of knowing that it is the width of the display surface. Using a name for this number, like SCREEN_W, makes the program easier to understand.

The intention of using named values is even more practical in the statement above: the intention is to set the size of drawing surface to be the same size as the display surface. In this case, if we ever need to change the size of the display surface, we have to make a change only at a single place in the program. This is made even simpler by the Allegro library automatically setting up the values SCREEN_W and SCREEN_H.

Here we repeat the core advice again: avoid using magic numbers!

To get back to our program: in the statement given above the function create_bitmap will create a new drawing surface, which is then assigned to the variable surface. Therefore, the variable surface represents the drawing surface. The surfaces in the Allegro library are of the type BITMAP*.

The next statement is:

    install_keyboard();

It makes the Allegro library start processing the messages from keyboard, for example, what keys are being pressed and similar.

After that statement, our programs so far would do some drawing to the drawing surface, named surface. After the entire image is drawn, this statement would follow:

    blit(surface, screen, 0,0, 0,0, SCREEN_W,SCREEN_H);

It copies the content of the surface surface into the surface screen. The surface surface contains our drawing, and the surface screen is the display surface, set up by Allegro. The display surface is continuously being displayed on the display device. Therefore, the effect of this statement is to display our drawing on the screen.

This statement can also be used to copy only a part of one surface into another, so the programmer has to specify which part he wants to be copied. In our case, we want the rectangular box starting at coordinates (0,0) of the surface surface and having the size SCREEN_W by SCREEN_H to be copied to the surface screen at coordinates (0,0). That amounts to copying the entire drawing surface to the display surface.

You might be wondering where the variable screen comes from. It is created and set by Allegro after the set_gfx_mode statement. The computer will then, usually 60 times per second[*], send the numbers that make up the surface screen to your display device, which will then display it. In this case, we will say that the connection to the display device is digital[*].

The statement

    while (!keypressed())
        rest(20);

As you might have noticed, the convention of using a capital letter for the first letter of function and type names is not nearly universal. For example, the Allegro library uses all lower case letters for function names, and so does the C++ Standard Library.

will repeat the statement rest(20) until a key is pressed. The statement rest(20);, provided by Allegro, will make a program do nothing for the duration of about 20 milliseconds. A millisecond is a thousandth part of a second. This amazing ability of making a program do absolutely nothing is now a part your knowledge, too. It usually makes the computer fan spin somewhat slower and slightly reduces your electricity bill.

When using the Allegro library, the function main has to end with:

    return 0;

That is due to Allegro renaming your function main to something like _mangled_main. Therefore, this function needs to end with a return statement because only the true function main can have a return statement omitted.

After the function main (which actually is not the function main), the Allegro requires this line to follow:

END_OF_MAIN()

It should not have the semicolon at the end of the line.