Tricks of the Windows Game Programming Gurus:First Contact: DirectDraw

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

In 99.9 percent of all cases, you will set only the first field, `dwCaps`. `dwCaps2` is for 3D stuff, and the remaining fields, `dwCaps3` and `dwCaps4`, are future expansion and unused. In any case, a partial list of the possible flag settings for the `dwCaps` are shown in Table 6.6. For a complete listing, take a look at the DirectX SDK.

For example, when creating a primary surface you would set `ddsd.ddsCaps` like this:

    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

I know this may seem overly complex, and in some ways it is. Having doubly nested control flags is a bit of a pain, but oh well...

Table 6.6 Capabilities Control Settings for DirectDraw Surfaces

Value | Description
--- | ---

`DDSCAPS_BACKBUFFER` | Indicates that this surface is the back buffer of a surface flipping structure.
`DDSCAPS_COMPLEX` | Indicates that a complex surface is being described. A complex surface is a surface with a primary surface and one or more back buffers to create a flipping chain.
`DDSCAPS_FLIP` | Indicates that this surface is a part of a surface flipping structure. When this capability is passed to the `CreateSurface()` method, a front buffer and one or more back buffers are created.
`DDSCAPS_LOCALVIDMEM` | Indicates that this surface exists in true, local video memory rather than non-local video memory. If this flag is specified, `DDSCAPS_VIDEOMEMORY` must be specified as well.
`DDSCAPS_MODEX` | Indicates that this surface is a 320×200 or 320×240 Mode X surface.
`DDSCAPS_NONLOCALVIDMEM` | Indicates that this surface exists in non-local video memory rather than true, local video memory. If this flag is specified, `DDSCAPS_VIDEOMEMORY` flag must be specified as well.
`DDSCAPS_OFFSCREENPLAIN` | Indicates that this surface is an offscreen surface that is not a special surface such as an overlay, texture, z-buffer, front-buffer, back-buffer, or alpha surface. Usually used for sprites.
`DDSCAPS_OWNDC` | Indicates that this surface will have a device context association for a long period.
`DDSCAPS_PRIMARYSURFACE` | Indicates that this surface is the primary surface. It represents what is visible to the user at the moment.
`DDSCAPS_STANDARDVGAMODE` | Indicates that this surface is a standard VGA mode surface, and not a Mode X surface. This flag cannot be used in combination with the `DDSCAPS_MODEX` flag.
`DDSCAPS_SYSTEMMEMORY` | Indicates that this surface memory was allocated in system memory.
`DDSCAPS_VIDEOMEMORY` | Indicates that this surface exists in display memory.

Now that you have an idea of the complexity and power that DirectDraw gives you when you’re creating surfaces, let’s put the knowledge to work and create a simple primary surface that’s the same size and color depth as the display mode (default behavior). Here’s the code to create a primary surface:

    // interface pointer to hold primary surface, note that

    // it's the 4th revision of the interface

    LPDIRECTDRAWSURFACE4  lpddsprimary = NULL;

    DDSURFACEDESC2 ddsd; // the DirectDraw surface description

    // MS recommends clearing out the structure

    memset(&ddsd,0,sizeof(ddsd)); // could use ZeroMemory()

    // now fill in size of structure

    ddsd.dwSize = sizeof(ddsd);

    // enable data fields with values from table 6.5 that we

    // will send valid data in

    // in this case only the ddsCaps field is enabled, we

    // could have enabled the width, height etc., but they

    // aren't needed since primary surfaces take on the

    // dimensions of the display mode by default

    ddsd.dwFlags = DDSD_CAPS;

    // now set the capabilities that we want from table 6.6

    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

    // now create the primary surface

    if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))

       {

       // error

       } // end if

If the function was successful, `lpddsprimary` will point to the new surface interface and you can call methods on it (of which there are quite a few, such as attaching the palette in 256-color modes). Let’s take a look at this to bring the palette example back full-circle.

#### Attaching the Palette

In the previous section on palettes, you did everything except attach the palette to a surface. You created the palette and filled it with entries, but you couldn’t attach the palette to a surface because you didn’t have one yet. Now that you have a surface (the primary), you can complete this step.

To attach a palette to any surface, all you need to do is use the `IDirectDrawSurface4::SetPalette()` function, which is shown here:

    HRESULT SetPalette(LPDIRECTDRAWPALETTE lpDDPalette);

This function simply takes a pointer to the palette that you want to be attached. Using the same palette that you created in the previous palette section, here’s how you would associate the palette with the primary surface:

    if (FAILED(lpddsprimary->SetPalette(lpddpal)))

       {

       // error

       } // end if

Not too bad, huh? At this point, you have everything you need to emulate the entire power of a DOS32 game. You can switch video modes, set the palette, and create a primary drawing surface that represents the active video image. However, there are still some details that you have to learn about, like actually locking the primary surface memory and gaining access to the VRAM and plotting a pixel. Let’s take a look at that now.

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.