Tricks of the Windows Game Programming Gurus:Journey into the Abbys

All ITKnowledge Source Code Search Tips Advanced Search |

| Tricks of the Windows Game Programming Gurus by Andre LaMothe Sams, Macmillan Computer Publishing ISBN: 0672313618 Pub Date: 09/27/99

Search this book:

Previous | Table of Contents | Next

### An Example: FreakOut

Before we both lose our minds with all this talk about Windows, DirectX, and 3D graphics, I would like to take a pause and show you a complete game—albeit a simple one, but a game nonetheless. This way you can see a real game loop and some graphics calls, and take a shot at compilation. Sound good? Alrighty, then!

The problem is, we’re only on Chapter 1. It’s not like I can use stuff from later chapters… that would be cheating, right? So what I’ve decided to do is get you used to using black box APIs for game programming. Based on that requirement, I asked, “What are the absolute minimum requirements for creating a 2D Breakout-like game?” All we really need is the following functionality:

  • Change into any graphics mode.
  • Draw colored rectangles on the screen.
  • Get the keyboard input.
  • Synchronize the game loop using some timing functions.
  • Draw a string of colored text on the screen.

So I created a library called `BLACKBOX.CPP|H`. Within it is a DirectX (DirectDraw only) set of functions, along with support code that implements the required functionality. The beauty is, you don’t need to look at the code; you just have to use the functions, based on their prototypes, and make sure to link with `BLACKBOX.CPP|H` to make an `.EXE`.

Based on the `BLACKBOX` library, I wrote a game called FreakOut that demonstrates a number of the concepts that we have discussed in this chapter. FreakOut contains all the major components of a real game, including a game loop, scoring, levels, and even a little baby physics model for the ball. And I do mean baby! Figure 1.9 is a screenshot of the game in action. Granted, it’s not Arkanoid, but it’s not bad for four hours of work!

Figure 1.9 A screen shot of FreakOut.

Before I show you the source code to the game, I want you to take a look at how the project and its various components fit together. Refer to Figure 1.10.

Figure 1.10 The structure of FreakOut.

As you can see from the figure, the game is composed of the following files:

  `FREAKOUT.CPP`—The main game logic that uses `BLACKBOX.CPP` and creates a minimum Win32 application.
  `BLACKBOX.CPP`—The game library (don’t peek).
  `BLACKBOX.H`—The header file for the game library.
  `DDRAW.LIB`—The DirectDraw import library needed to build the application. This doesn’t contain the real DirectX code. It’s more of an intermediary library that you make calls to, which in turn loads the `DDRAW.DLL` dynamic link library that does the real work. You can find this in the DirectX SDK installation under `<LIB>`.
  `DDRAW.DLL`—The run-time DirectDraw library that actually contains the COM implementation of the DirectDraw interface functions that are called through the `DDRAW.LIB` import library. You don’t need to worry about this per se; you just need to make sure that the DirectX run-time files are installed.

Now that we have that all straight, let’s take a look at the `BLACKOUT.H` header file and see what the functions are within it.

Listing 1.2 `BLACKOUT.H` Header File

    // BLACKBOX.H - Header file for demo game engine library

    // watch for multiple inclusions

    #ifndef BLACKBOX

    #define BLACKBOX

    // DEFINES ////////////////////////////////////////////////////

    // default screen size

    #define SCREEN_WIDTH    640  // size of screen

    #define SCREEN_HEIGHT   480

    #define SCREEN_BPP      8    // bits per pixel

    #define MAX_COLORS      256  // maximum colors

    // MACROS /////////////////////////////////////////////////////

    // these read the keyboard asynchronously

    #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)

    #define KEY_UP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

    // initializes a direct draw struct

    #define DD_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct));

    ddstruct.dwSize=sizeof(ddstruct); }

    // TYPES //////////////////////////////////////////////////////

    // basic unsigned types

    typedef unsigned short USHORT;

    typedef unsigned short WORD;

    typedef unsigned char  UCHAR;

    typedef unsigned char  BYTE;

    // EXTERNALS //////////////////////////////////////////////////

    extern LPDIRECTDRAW4         lpdd;           // dd object

    extern LPDIRECTDRAWSURFACE4  lpddsprimary;   // dd primary surface

    extern LPDIRECTDRAWSURFACE4  lpddsback;      // dd back surface

    extern LPDIRECTDRAWPALETTE   lpddpal;        // a pointer to palette

    extern LPDIRECTDRAWCLIPPER   lpddclipper;    // dd clipper

    extern PALETTEENTRY   palette[256];   // color palette

    extern PALETTEENTRY   save_palette[256]; // used to save palettes

    extern DDSURFACEDESC2 ddsd;     // dd surface description struct

    extern DDBLTFX        ddbltfx;  // used to fill

    extern DDSCAPS2       ddscaps;  // dd surface capabilities struct

    extern HRESULT        ddrval;   // result back from dd calls

    extern DWORD          start_clock_count;    // used for timing

    // these defined the general clipping rectangle

    extern int min_clip_x,  // clipping rectangle

               max_clip_x,

               min_clip_y,

               max_clip_y;

    // these are overwritten globally by DD_Init()

    extern int screen_width,    // width of screen

               screen_height,   // height of screen

               screen_bpp;      // bits per pixel

    // PROTOTYPES /////////////////////////////////////////////////

    // DirectDraw functions

    int DD_Init(int width, int height, int bpp);

    int DD_Shutdown(void);

    LPDIRECTDRAWCLIPPER DD_Attach_Clipper(LPDIRECTDRAWSURFACE4 lpdds,

                               int num_rects, LPRECT clip_list);

    int DD_Flip(void);

    int DD_Fill_Surface(LPDIRECTDRAWSURFACE4 lpdds,int color);

    // general utility functions

    DWORD Start_Clock(void);

    DWORD Get_Clock(void);

    DWORD Wait_Clock(DWORD count);

    // graphics functions

    int Draw_Rectangle(int x1, int y1,

                       int x2, int y2,

                       int color,

                       LPDIRECTDRAWSURFACE4 lpdds=lpddsback);

    // gdi functions

    int Draw_Text_GDI(char *text, int x,int y,COLORREF color,

                      LPDIRECTDRAWSURFACE4 lpdds=lpddsback);

    int Draw_Text_GDI(char *text, int x,int y,int color,

                      LPDIRECTDRAWSURFACE4 lpdds=lpddsback);

    #endif

Previous | Table of Contents | Next

Copyright © Macmillan Computer Publishing, Inc.

Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.