Tricks of the Windows Game Programming Gurus:Advanced DirectDraw and Bitmapped Graphics

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

After you’ve created all the lights you want, you can call the function with all `NULL`s except for the command, which is `BLINKER_RUN`. You do this for each frame of your game loop. For example, let’s say you have a game that runs at 30fps, and you want a red light to blink with a 50-50 duty cycle—one second on, one second off—along with a green light with a 50-50 duty cycle of two seconds on and two seconds off. Furthermore, you want to use palette entries 250 and 251 for the red and green light, respectively. Here’s the code you need:

    BLINKER temp; // used to hold temp info

    PALETTEENTRY red   = {255,0,0,PC_NOCOLLAPSE};

    PALETTEENTRY green = {0,255,0,PC_NOCOLLAPSE};

    PALETTEENTRY black = {0,0,0,PC_NOCOLLAPSE};

    // add red light

    temp.color_index = 250;

    temp.on_color    = red;

    temp.off_color   = black;

    temp.on_time     = 30; // 30 cycles at 30fps = 1 sec

    temp.off_time    = 30;

    // make call

    int red_id = Blink_Colors(BLINKER_ADD, &temp, 0);

    // now create green light

    temp.color_index = 251;

    temp.on_color    = green;

    temp.off_color   = black;

    temp.on_time     = 60; // 30 cycles at 30fps = 2 secs

    temp.off_time    = 60;

    // make call

    int green_id = Blink_Colors(BLINKER_ADD, &temp, 0);

Now you’re ready to rock and roll! In the main part of your game loop, you would make a call to `Blink_Colors()` each cycle, something like this:

    // enter main event loop

    while(TRUE)

            {

        // test if there is a message in queue, if so get it

            if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))

               {

               // test if this is a quit

           if (msg.message == WM_QUIT)

               break;

               // translate any accelerator keys

               TranslateMessage(&msg);

               // send the message to the window proc

               DispatchMessage(&msg);

               } // end if

           // main game processing goes here

           Game_Main();

           // blink all the colors

           // could put this into Game_Main() also – better idea

           Blink_Colors(BLINKER_RUN, NULL, 0);

            } // end while

Of course, you can delete a blinker with its ID at any time, and it won’t be processed anymore. For example, if you want to kill the red light:

    Blink_Colors(BLINKER_DELETE, NULL, red_id);

It’s as simple as that. And of course, you can update a blinker’s on/off time and color values by setting up another `BLINKER` structure and then making the call with `BLINKER_UPDATE`. For example, if you want to alter the green blinker’s parameters:

    // set new parms

    temp.on_time   = 100;

    temp_off_time  = 200;

    temp.on_color  = {255,255,0,PC_NOCOLLAPSE};

    temp.off_color = {0,0,0,PC_NOCOLLAPSE};

    // update blinker

    Blink_Colors(BLINKER_UPDATE, temp, green_id);

That’s enough of that! Check out `DEMO7_15.CPP|EXE`, which uses the `Blink_Colors()` function to make some of the lights on the starship image blink.

#### Color Rotation in 256-Color Modes

The next interesting color animation effect is called color rotation or color shifting. Basically, it’s the process of taking a collection of adjacent color entries or registers and shifting them in a circular manner, as shown in Figure 7.37. Using this technique, you can make objects seem as if they’re moving or shifting without writing a single pixel to the screen. It’s great for simulating water or the motion of fluids. In addition, you can draw a number of images at different positions, each with a different color index. Then, if you rotate the colors, it will look like the object is moving. Great 3D Star Wars trenches can be created like this.

Figure 7.37 Color rotation.

The code for color rotation is fairly trivial. Algorithmically, to rotate `color[c1]` to `color[c2]`, use the following code:

    temp = color[c1];

    for (int index = c1; index < c2; index++)

        color[c1] = color[c1+1];

    // finish the cycle, close the loop

    color[index] = temp;

Here’s a function that implements the algorithm that I’m using for our library:

    int Rotate_Colors(int start_index, int end_index)

    {

    // this function rotates the color between start and end

    int colors = end_index - start_index + 1;

    PALETTEENTRY work_pal[MAX_COLORS_PALETTE]; // working palette

    // get the color palette

    lpddpal->GetEntries(0,start_index,colors,work_pal);

    // shift the colors

    lpddpal->SetEntries(0,start_index+1,colors-1,work_pal);

    // fix up the last color

    lpddpal->SetEntries(0,start_index,1,&work_pal[colors - 1]);

    // update shadow palette

    lpddpal->GetEntries(0,0,MAX_COLORS_PALETTE,palette);

    // return success

    return(1);

    } // end Rotate_Colors

Basically, the algorithm takes the starting and ending color index that you want to rotate and performs the rotation. Don’t worry about the “shadow palettes” stuff; this is a library thing, so just focus on the logic. The interesting thing is how the algorithm works. It does the same thing as the `FOR` loop version, but in a different way. This is possible via an in-place shift. Anyway, for a demo of the function, take a look at `DEMO7_16.CPP|EXE`. It uses the function to create a moving stream of acid—water is for wimps!

#### Tricks with RGB Modes

The problem with RGB modes is that there isn’t any color indirection. In other words, every pixel on the screen has its own RGB values, so there’s no way to make a single change that affects the entire image. However, there are two ways to perform color-related processing:

  • Using manual color transformations or lookup tables.

Gamma correction deals with the nonlinear response of a computer monitor to the input drive. In most cases, gamma correction allows you to modify the intensity or the brightness of the video signal. However, gamma correction can be performed separately on each red, green, and blue channel to obtain interesting effects.

  • Using the new DirectX color and gamma correction subsystems that perform real-time color manipulation on the primary surface.

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.