Chapter 2

2. Preparing our game

2.1 What do we need?

A game consists of many components, like graphics, sound, input device management, data file management, etc. Allegro can deal with all of these. But it can't deal with the design; you must have a good design before you can use Allegro to create games. In this tutorial, we are going to make a helicopter game, where we control a helicopter on a mission to bomb beyond known reality every tank that dares to show its ugly warhead on the game screen.

Let's begin with the backdrop. For simplicity, we will have a static unmovable backdrop. However, to show how to use Allegro drawing functions, we will generate it from within our main program, using some cool shades.

First, we need the cool shades. That is, we need to have a game palette first. (In this tutorial, we will be working in 256-color modes.) We can create a palette using any appropriate sprite editor or paint program. The palette I will use is within the Allegro datafile below. Use the Allegro Grabber utility to see it.

Download the tutorial datafile

2.2 The Grabber

GRABBER.EXE resides in the TOOLS subdirectory of your Allegro directory. To make it easier to use, either put this directory into your PATH in AUTOEXEC.BAT, or copy GRABBER.EXE into somewhere that is already in the PATH, like your DJGPP BIN directory. This will make it easier for you to start the Grabber from your project directory.

When you have downloaded the tutorial datafile and placed it into your project directory, start Grabber. From the File menu, select Load, and load TUTORIAL.DAT. (You could also have specified the datafile on the command line.) The datafile elements of our game is now listed. You may look through them now, and note the convenience of having everything in one datafile, but for more details about how the Grabber works, consult its help system. For now, though, we just need it to generate the header file tutorial.h. From the File menu, choose Save. Once saved, close the Grabber by choosing Quit.

2.3 The Datafile

As you have now seen, all the data objects we need, like graphics and sounds, are contained in the datafile. The Grabber also created a header file (tutorial.h) that our main program can use to reference specific objects within the datafile whenever it needs to use them.

But how is it actually used? To see how, we'll write some more code. Start RHIDE again. Note that RHIDE will this time automatically load your project, since it's the only project existing in the directory. (This may cause troubles if you use the Save Options feature improperly, since options are saved in a project file, but that's another matter.)

Now change your program to read:

#include <allegro.h>
#include "tutorial.h"

DATAFILE* data;

int main()
{
 allegro_init();
 install_keyboard();

 data=load_datafile("tutorial.dat");

 set_gfx_mode(GFX_VGA,320,200,0,0);

 set_palette((RGB*)data[TUT_GAMEPAL].dat);

 textout_centre(screen,font,"Ready. Beep.",160,100,255);
 readkey();
 return 0;
}
Let's go through this program and see what it actually does. First, obviously, is the #include directives, that loads the definitions we need. tutorial.h, the one Grabber created, contains the TUT_GAMEPAL definition. Then we define a global variable, data, that is a pointer to DATAFILE entries. In the main program, we initialize Allegro with allegro_init(), install Allegro's keyboard subsystem with install_keyboard(), then load the datafile into memory, and assigns it to our global variable data. load_datafile() takes care of everything necessary to load it, including allocating memory, decompressing, and converting, and returns a pointer to the loaded and ready-to-use datafile.

If you are used to real-mode compilers, remember that DJGPP is a 32-bit protected-mode compiler, so we are working in a flat address space, with virtual memory and all, so there is no need to worry about exhausting memory by keeping the entire datafile loaded (unless your datafile is approaching something like 50 megabytes, of course).

After we have entered VGA 320x200 256-color graphics mode (mode 13h) with set_gfx_mode(), we then sets the palette from the datafile. As you can see, data points to an array of DATAFILE structures, of which the dat field points to the actual data. Since dat is a void * pointer, we need to explicitly cast it to the appropriate data type, otherwise the compiler will complain that ANSI C++ forbids implicit casting. set_palette() expects an argument of type RGB *.

Then we output the usual text at the center of the screen and waits for a key, as before.

We can now proceed to the next chapter