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.
allegro_init
is actually a macro, not a function. Many macros do look like functions.
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.
See the chapter 'First Programs' if you have forgotten what literal values are.
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[*].
This frequency is the refresh rate of the common display devices.
As opposed to analog, which is the case when the display device uses the VGA connector. In that case the graphics digital-to-analog converter circuit has to convert the numbers into electrical signal amplitude before sending it to the display device.
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.