我们继续上次的话题。
上一讲中,我们介绍了一下具体的步骤。下面的清单 1.0 包含了所有的功能以及一个展示如何操作显存和键盘的例子。我们简单地将它作为一个演示。
// LISTING 1.0 - DIRECT X 5.0 GAME CONSOLE ////////////////////////////////////
// INCLUDES ///////////////////////////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN // make sure certain headers are included correctly
#include
// include the standard windows stuff
#include // include the 32 bit stuff
#include // include the multi media stuff
// note you need winmm.lib also
#include
// include direct draw components
#include
// include all the good stuff
#include
#include
#include
// DEFINES ////////////////////////////////////////////////////////////////////
#define WINDOW_CLASS_NAME "WINDOW_CLASS" // this is the name of the window class
// defines for screen parameters
#define SCREEN_WIDTH 640
// the width of the viewing surface
#define SCREEN_HEIGHT 480
// the height of the viewing surface
#define SCREEN_BPP 8
// the bits per pixel
#define MAX_COLORS 256
// the maximum number of colors
// TYPES //////////////////////////////////////////////////////////////////////
typedef unsigned char UCHAR;
// MACROS /////////////////////////////////////////////////////////////////////
// these query the keyboard in real-time
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
// PROTOTYPES /////////////////////////////////////////////////////////////////
int DD_Init(HWND hwnd);
int DD_Shutdown(void);
int Set_Pal_Entry(int index, int red, int green, int blue);
void Game_Init(void);
void Game_Main(void);
void Game_Shutdown(void);
// DIRECTDRAW GLOBALS ////////////////////////////////////////////////////////
LPDIRECTDRAW lpdd = NULL;
// dd object
LPDIRECTDRAWSURFACE lpddsprimary = NULL; // dd primary surface
LPDIRECTDRAWPALETTE lpddpal = NULL;
// a pointer to the created dd palette
PALETTEENTRY color_palette[256];
// holds the shadow palette entries
DDSURFACEDESC ddsd;
// a direct draw surface description struct
DDSCAPS ddscaps;
// a direct draw surface capabilities struct
HRESULT ddrval;
// result back from dd calls
HWND main_window_handle = NULL;
// used to store the window handle
UCHAR *video_buffer = NULL;
// pointer to video ram
// GAME GLOBALS GO HERE /////////////////////////////////////////////////////
// DIRECT X FUNCTIONS /////////////////////////////////////////////////////////
int DD_Init(HWND hwnd)
{
// this function is responsible for initializing direct draw, it creates a
// primary surface
int index; // looping index
// now that the windows portion is complete, start up direct draw
if (DirectDrawCreate(NULL,&lpdd,NULL)!=DD_OK)
{
// shutdown any other dd objects and kill window
DD_Shutdown();
return(0);
} // end if
// now set the coop level to exclusive and set for full screen and mode x
if (lpdd-SetCooperativeLevel(hwnd, DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE |
DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX)!=DD_OK)
{
// shutdown any other dd objects and kill window
DD_Shutdown();
return(0);
} // end if
// now set the display mode
if (lpdd-SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP)!=DD_OK)
{
// shutdown any other dd objects and kill window
DD_Shutdown();
return(0);
} // end if
// Create the primary surface
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if
(lpdd-CreateSurface(&ddsd,&lpddsprimary,NULL)!=DD_OK)
{
// shutdown any other dd objects and kill window
DD_Shutdown();
return(0);
} // end if
// create the palette and attach it to the primary surface
// clear all the palette entries to RGB 0,0,0
memset(color_palette,0,256*sizeof(PALETTEENTRY));
// set all of the flags to the correct value
for (index=0; index
{
// create the GRAY/RED/GREEN/BLUE palette, 64 shades of each
if ((index / 64)==0)
{
color_palette[index].peRed = index*4;
color_palette[index].peGreen = index*4;
color_palette[index].peBlue = index*4;
} // end if
else
if ((index / 64)==1)
color_palette[index].peRed = (index%64)*4;
else
if ((index / 64)==2)
color_palette[index].peGreen = (index%64)*4;
else
if ((index / 64)==3)
color_palette[index].peBlue = (index%64)*4;
// set the no collapse flag
color_palette[index].peFlags = PC_NOCOLLAPSE;
} // end for index
// now create the palette object, note that it is a member of the dd object itself
if (lpdd-CreatePalette((DDPCAPS_8BIT | DDPCAPS_INITIALIZE),color_palette,&lpddpal,NULL)!=DD_OK)
{
// shutdown any other dd objects and kill window
DD_Shutdown();
return(0);
} // end if
// now attach the palette to the primary surface
lpddsprimary-SetPalette(lpddpal);
// return success if we got this far
return(1);
} // end DD_Init
///////////////////////////////////////////////////////////////////////////////
int DD_Shutdown(void)
{
// this function tests for dd components that have been created and releases
// them back to the operating system
// test if the dd object exists
if (lpdd)
{
// test if there is a primary surface
if(lpddsprimary)
{
// release the memory and set pointer to NULL
lpddsprimary-Release();
lpddsprimary = NULL;
} // end if
// now release the dd object itself
lpdd-Release();
lpdd = NULL;
// return success
return(1);
} // end if
else
return(0);
} // end DD_Shutdown
//////////////////////////////////////////////////////////////////////////////
int Set_Pal_Entry(int index, int red, int green, int blue)
{
// this function sets a palette entry with the sent color
PALETTEENTRY color; // used to build up color
// set RGB value in structure
color.peRed = (BYTE)red;
color.peGreen = (BYTE)green;
color.peBlue = (BYTE)blue;
color.peFlags = PC_NOCOLLAPSE;
// set the color palette entry
lpddpal-SetEntries(0,index,1,&color);
// make copy in shadow palette
memcpy(&color_palette[index],
&color,
sizeof(PALETTEENTRY));
// return success
return(1);
} // end Set_Pal_Entry
// WINDOWS CALLBACK FUNCTION //////////////////////////////////////////////////
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
// this is the main message handler of the system
HDC hdc; // handle to graphics context