windows编程大师技巧第二版学习笔记——开发环境的搭建

来源:互联网 发布:数据录入员招聘 兼职 编辑:程序博客网 时间:2024/06/05 11:06

 先说一下学习这本书的初衷,现在的游戏开发一般都会直接使用游戏引擎来渲染和组织一些功能,笔者以前只用过u3d做过一次cs场景类的程序(严格来说不是游戏。。。)但是作为被封装好的引擎,作为初学者不能更好的理解引擎内部的运行机制,所以我打算用很久的空余时间来学习这本书。不使用引擎,自己做渲染等,这是一个挑战,但相信对长远发展会有帮助。

大师的代码最好使用dx7sdk,因为这本书的许多程序需要调用d3dim.lib直接模式(或立即模式)导入库,他是D3D immediatel mode使用的LIB,而在dx8.0(包括8.0)的以上版本取消了这种区别,也就是取消了这个库,所以在vs2010中会提示缺少d3dim.lib库。

所以推荐使用版本

dx7sdk-7001

编译器这本书使用的是vc++6.0,但是现在都是vc有点老了,所以我使用了vs2010,话说我现在才知道微软以前的编译器叫vc,在6.0之后的版本就开始叫vs了。。

这次主要的目标就是在vs2010上搭建我们的开发环境。

开始:

首先安装dx7sdk-7001


选择好使用的路径,点击unzip就可以了,实际上dx7.0作为很古老的版本,我们使用的也仅仅是它的一些include,lib文件。

然后在vs2010中配置dx环境

打开vs2010新建一个空的win32项目

然后右键点击这个项目


选择属性

在配置属性里面


选择vc++目录,我们需要修改的是第二行的包含目录和库目录。

我这里把刚才安装的dx7.0放在了d盘,以此为例。


包含目录修改成:

$(IncludePath);D:\dx7sdk-700.1\include

注意一定要把$(IncludePath);(原路径)放在最前面,手动修改的时候是默认在后面的。如果放在前面会出现很严重的程序错误。至少vs2010是这么不智能的。。。

库目录修改成

$(LibraryPath);D:\dx7sdk-700.1\lib;D:\dx7sdk-700.1\lib\borland

这三个路径同样需要把$(LibraryPath);这个原路径放在最前面,稍微提及一下dx7.0的borland产品,在使用声音等处理的时候还是加上这个库,他在dx7.0中的lib文件中的一个子文件。

修改完之后点击应用即可。

做完这些并不可以,还需要修改连接器的lib


同样是选择工程的右键属性点击链接器,选择输入属性,然后我们会看到附加依赖值这一项

点击编辑一项之后



我们需要添加的项目是

ddraw.lib
dinput.lib
dinput8.lib
dsound.lib
d3dim.lib
dxguid.lib
winmm.lib

这几项,d3dim.lib是dx7.0特有的文件,所以推荐使用dx7.0不然在本书的大多程序会报错。

修改完这些之后,大功告成,开始我们的开发之旅把。

第一个跑起来的游戏就从打砖块开始把:(因为没有引擎所以使用了blackbox.h进行渲染)

// FREAKOUT.CPP - break game demo// INCLUDES ///////////////////////////////////////////////////#define WIN32_LEAN_AND_MEAN // include all macros#define INITGUID            // include all GUIDs #include <windows.h>        // include important windows stuff#include <windowsx.h> #include <mmsystem.h>#include <iostream>       // include important C/C++ stuff#include <conio.h>#include <stdlib.h>#include <malloc.h>#include <memory.h>#include <string.h>#include <stdarg.h>#include <stdio.h>#include <math.h>#include <io.h>#include <fcntl.h>#include <ddraw.h>          // directX includes#include "blackbox.h"       // game library includes// DEFINES ////////////////////////////////////////////////////// defines for windows #define WINDOW_CLASS_NAME "WIN3DCLASS"  // class name#define WINDOW_WIDTH            640     // size of window#define WINDOW_HEIGHT           480// states for game loop#define GAME_STATE_INIT         0#define GAME_STATE_START_LEVEL  1#define GAME_STATE_RUN          2#define GAME_STATE_SHUTDOWN     3#define GAME_STATE_EXIT         4 // block defines#define NUM_BLOCK_ROWS          6#define NUM_BLOCK_COLUMNS       8#define BLOCK_WIDTH             64#define BLOCK_HEIGHT            16#define BLOCK_ORIGIN_X          8#define BLOCK_ORIGIN_Y          8#define BLOCK_X_GAP             80#define BLOCK_Y_GAP             32// paddle defines#define PADDLE_START_X          (SCREEN_WIDTH/2 - 16)#define PADDLE_START_Y          (SCREEN_HEIGHT - 32);#define PADDLE_WIDTH            32#define PADDLE_HEIGHT           8#define PADDLE_COLOR            191// ball defines#define BALL_START_Y            (SCREEN_HEIGHT/2)#define BALL_SIZE                4// PROTOTYPES /////////////////////////////////////////////////// game consoleint Game_Init(void *parms=NULL);int Game_Shutdown(void *parms=NULL);int Game_Main(void *parms=NULL);// GLOBALS ////////////////////////////////////////////////////HWND main_window_handle  = NULL; // save the window handleHINSTANCE main_instance  = NULL; // save the instanceint game_state           = GAME_STATE_INIT; // starting stateint paddle_x = 0, paddle_y = 0; // tracks position of paddleint ball_x   = 0, ball_y   = 0; // tracks position of ballint ball_dx  = 0, ball_dy  = 0; // velocity of ballint score    = 0;               // the scoreint level    = 1;               // the current levelint blocks_hit = 0;             // tracks number of blocks hit// this contains the game grid data   UCHAR blocks[NUM_BLOCK_ROWS][NUM_BLOCK_COLUMNS];     // FUNCTIONS //////////////////////////////////////////////////LRESULT CALLBACK WindowProc(HWND hwnd,     UINT msg,                             WPARAM wparam,                             LPARAM lparam){// this is the main message handler of the systemPAINTSTRUCTps;   // used in WM_PAINTHDChdc;   // handle to a device context// what is the message switch(msg){case WM_CREATE:         {// do initialization stuff herereturn(0);} break;    case WM_PAINT:         {         // start painting         hdc = BeginPaint(hwnd,&ps);         // the window is now validated          // end painting         EndPaint(hwnd,&ps);         return(0);        } break;case WM_DESTROY: {// kill the applicationPostQuitMessage(0);return(0);} break;default:break;    } // end switch// process any messages that we didn't take care of return (DefWindowProc(hwnd, msg, wparam, lparam));} // end WinProc// WINMAIN ////////////////////////////////////////////////////int WINAPI WinMain(HINSTANCE hinstance,HINSTANCE hprevinstance,LPSTR lpcmdline,int ncmdshow){// this is the winmain functionWNDCLASS winclass;// this will hold the class we createHWND hwnd;// generic window handleMSG msg;// generic messageHDC      hdc;       // generic dcPAINTSTRUCT ps;     // generic paintstruct// first fill in the window class stucturewinclass.style= CS_DBLCLKS | CS_OWNDC |                           CS_HREDRAW | CS_VREDRAW;winclass.lpfnWndProc= WindowProc;winclass.cbClsExtra= 0;winclass.cbWndExtra= 0;winclass.hInstance= hinstance;winclass.hIcon= LoadIcon(NULL, IDI_APPLICATION);winclass.hCursor= LoadCursor(NULL, IDC_ARROW);winclass.hbrBackground= (HBRUSH)GetStockObject(BLACK_BRUSH);winclass.lpszMenuName= NULL; winclass.lpszClassName= WINDOW_CLASS_NAME;// register the window classif (!RegisterClass(&winclass))return(0);// create the window, note the use of WS_POPUPif (!(hwnd = CreateWindow(WINDOW_CLASS_NAME,    // class             "WIN3D Game Console",// title WS_POPUP | WS_VISIBLE, 0,0,                // initial x,y        GetSystemMetrics(SM_CXSCREEN),  // intial width             GetSystemMetrics(SM_CYSCREEN),  // initial height NULL,    // handle to parent  NULL,    // handle to menu hinstance,// instance NULL)))// creation parmsreturn(0);// hide mouseShowCursor(FALSE);// save the window handle and instance in a globalmain_window_handle = hwnd;main_instance      = hinstance;// perform all game console specific initializationGame_Init();// enter main event loopwhile(1){if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)){ // test if this is a quit        if (msg.message == WM_QUIT)           break;// translate any accelerator keysTranslateMessage(&msg);// send the message to the window procDispatchMessage(&msg);} // end if        // main game processing goes here    Game_Main();} // end while// shutdown game and release all resourcesGame_Shutdown();// show mouseShowCursor(TRUE);// return to Windows like thisreturn(msg.wParam);} // end WinMain// T3DX GAME PROGRAMMING CONSOLE FUNCTIONS ////////////////////int Game_Init(void *parms){// this function is where you do all the initialization // for your game// return successreturn(1);} // end Game_Init///////////////////////////////////////////////////////////////int Game_Shutdown(void *parms){// this function is where you shutdown your game and// release all resources that you allocated// return successreturn(1);} // end Game_Shutdown///////////////////////////////////////////////////////////////void Init_Blocks(void){// initialize the block fieldfor (int row=0; row < NUM_BLOCK_ROWS; row++)    for (int col=0; col < NUM_BLOCK_COLUMNS; col++)         blocks[row][col] = row*16+col*3+16;} // end Init_Blocks///////////////////////////////////////////////////////////////void Draw_Blocks(void){// this function draws all the blocks in row major formint x1 = BLOCK_ORIGIN_X, // used to track current position    y1 = BLOCK_ORIGIN_Y; // draw all the blocksfor (int row=0; row < NUM_BLOCK_ROWS; row++)    {        // reset column position    x1 = BLOCK_ORIGIN_X;    // draw this row of blocks    for (int col=0; col < NUM_BLOCK_COLUMNS; col++)        {        // draw next block (if there is one)        if (blocks[row][col]!=0)            {            // draw block                 Draw_Rectangle(x1-4,y1+4,                 x1+BLOCK_WIDTH-4,y1+BLOCK_HEIGHT+4,0);            Draw_Rectangle(x1,y1,x1+BLOCK_WIDTH,                 y1+BLOCK_HEIGHT,blocks[row][col]);            } // end if        // advance column position        x1+=BLOCK_X_GAP;        } // end for col    // advance to next row position    y1+=BLOCK_Y_GAP;    } // end for row} // end Draw_Blocks///////////////////////////////////////////////////////////////void Process_Ball(void){// this function tests if the ball has hit a block or the paddle// if so, the ball is bounced and the block is removed from // the playfield note: very cheesy collision algorithm :)// first test for ball block collisions// the algorithm basically tests the ball against each // block's bounding box this is inefficient, but easy to // implement, later we'll see a better wayint x1 = BLOCK_ORIGIN_X, // current rendering position    y1 = BLOCK_ORIGIN_Y; int ball_cx = ball_x+(BALL_SIZE/2),  // computer center of ball    ball_cy = ball_y+(BALL_SIZE/2);// test of the ball has hit the paddleif (ball_y > (SCREEN_HEIGHT/2) && ball_dy > 0)   {   // extract leading edge of ball   int x = ball_x+(BALL_SIZE/2);   int y = ball_y+(BALL_SIZE/2);   // test for collision with paddle   if ((x >= paddle_x && x <= paddle_x+PADDLE_WIDTH) &&       (y >= paddle_y && y <= paddle_y+PADDLE_HEIGHT))       {       // reflect ball       ball_dy=-ball_dy;       // push ball out of paddle since it made contact       ball_y+=ball_dy;       // add a little english to ball based on motion of paddle       if (KEY_DOWN(VK_RIGHT))          ball_dx-=(rand()%3);       else       if (KEY_DOWN(VK_LEFT))          ball_dx+=(rand()%3);       else          ball_dx+=(-1+rand()%3);              // test if there are no blocks, if so send a message       // to game loop to start another level       if (blocks_hit >= (NUM_BLOCK_ROWS*NUM_BLOCK_COLUMNS))          {          game_state = GAME_STATE_START_LEVEL;          level++;          } // end if       // make a little noise       MessageBeep(MB_OK);       // return       return;        } // end if   } // end if// now scan thru all the blocks and see of ball hit blocksfor (int row=0; row < NUM_BLOCK_ROWS; row++)    {        // reset column position    x1 = BLOCK_ORIGIN_X;    // scan this row of blocks    for (int col=0; col < NUM_BLOCK_COLUMNS; col++)        {        // if there is a block here then test it against ball        if (blocks[row][col]!=0)           {           // test ball against bounding box of block           if ((ball_cx > x1) && (ball_cx < x1+BLOCK_WIDTH) &&                    (ball_cy > y1) && (ball_cy < y1+BLOCK_HEIGHT))               {               // remove the block               blocks[row][col] = 0;                // increment global block counter, so we know                // when to start another level up               blocks_hit++;               // bounce the ball               ball_dy=-ball_dy;               // add a little english               ball_dx+=(-1+rand()%3);               // make a little noise               MessageBeep(MB_OK);               // add some points               score+=5*(level+(abs(ball_dx)));               // that's it -- no more block               return;               } // end if             } // end if        // advance column position        x1+=BLOCK_X_GAP;        } // end for col    // advance to next row position    y1+=BLOCK_Y_GAP;    } // end for row} // end Process_Ball///////////////////////////////////////////////////////////////int Game_Main(void *parms){// this is the workhorse of your game it will be called// continuously in real-time this is like main() in C// all the calls for you game go here!char buffer[80]; // used to print text// what state is the game in? if (game_state == GAME_STATE_INIT)    {    // initialize everything here graphics    DD_Init(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP);    // seed the random number generator    // so game is different each play    srand(Start_Clock());    // set the paddle position here to the middle bottom    paddle_x = PADDLE_START_X;    paddle_y = PADDLE_START_Y;    // set ball position and velocity    ball_x = 8+rand()%(SCREEN_WIDTH-16);    ball_y = BALL_START_Y;    ball_dx = -4 + rand()%(8+1);    ball_dy = 6 + rand()%2;    // transition to start level state    game_state = GAME_STATE_START_LEVEL;    } // end if ////////////////////////////////////////////////////////////////elseif (game_state == GAME_STATE_START_LEVEL)    {    // get a new level ready to run    // initialize the blocks    Init_Blocks();    // reset block counter    blocks_hit = 0;    // transition to run state    game_state = GAME_STATE_RUN;    } // end if///////////////////////////////////////////////////////////////elseif (game_state == GAME_STATE_RUN)    {    // start the timing clock    Start_Clock();    // clear drawing surface for the next frame of animation    Draw_Rectangle(0,0,SCREEN_WIDTH-1, SCREEN_HEIGHT-1,200);    // move the paddle    if (KEY_DOWN(VK_RIGHT))       {       // move paddle to right       paddle_x+=8;        // make sure paddle doesn't go off screen       if (paddle_x > (SCREEN_WIDTH-PADDLE_WIDTH))          paddle_x = SCREEN_WIDTH-PADDLE_WIDTH;       } // end if    else    if (KEY_DOWN(VK_LEFT))       {       // move paddle to right       paddle_x-=8;        // make sure paddle doesn't go off screen       if (paddle_x < 0)          paddle_x = 0;       } // end if    // draw blocks    Draw_Blocks();    // move the ball    ball_x+=ball_dx;    ball_y+=ball_dy;    // keep ball on screen, if the ball hits the edge of     // screen then bounce it by reflecting its velocity    if (ball_x > (SCREEN_WIDTH - BALL_SIZE) || ball_x < 0)        {       // reflect x-axis velocity       ball_dx=-ball_dx;       // update position        ball_x+=ball_dx;       } // end if    // now y-axis    if (ball_y < 0)        {       // reflect y-axis velocity       ball_dy=-ball_dy;       // update position        ball_y+=ball_dy;       } // end if   else    // penalize player for missing the ball   if (ball_y > (SCREEN_HEIGHT - BALL_SIZE))       {       // reflect y-axis velocity       ball_dy=-ball_dy;       // update position        ball_y+=ball_dy;       // minus the score       score-=100;       } // end if    // next watch out for ball velocity getting out of hand    if (ball_dx > 8) ball_dx = 8;    else    if (ball_dx < -8) ball_dx = -8;        // test if ball hit any blocks or the paddle    Process_Ball();    // draw the paddle and shadow    Draw_Rectangle(paddle_x-8, paddle_y+8,                    paddle_x+PADDLE_WIDTH-8,                    paddle_y+PADDLE_HEIGHT+8,0);    Draw_Rectangle(paddle_x, paddle_y,                    paddle_x+PADDLE_WIDTH,                    paddle_y+PADDLE_HEIGHT,PADDLE_COLOR);    // draw the ball    Draw_Rectangle(ball_x-4, ball_y+4, ball_x+BALL_SIZE-4,                    ball_y+BALL_SIZE+4, 0);    Draw_Rectangle(ball_x, ball_y, ball_x+BALL_SIZE,                    ball_y+BALL_SIZE, 255);    // draw the info    sprintf(buffer,"F R E A K O U T           Score %d             Level %d",score,level);    Draw_Text_GDI(buffer, 8,SCREEN_HEIGHT-16, 127);        // flip the surfaces    DD_Flip();    // sync to 33ish fps    Wait_Clock(30);    // check of user is trying to exit    if (KEY_DOWN(VK_ESCAPE))       {       // send message to windows to exit       PostMessage(main_window_handle, WM_DESTROY,0,0);       // set exit state       game_state = GAME_STATE_SHUTDOWN;       } // end if    } // end if///////////////////////////////////////////////////////////////elseif (game_state == GAME_STATE_SHUTDOWN)   {   // in this state shut everything down and release resources   DD_Shutdown();   // switch to exit state   game_state = GAME_STATE_EXIT;   } // end if// return successreturn(1);} // end Game_Main///////////////////////////////////////////////////////////////

// BLACKBOX.CPP - Game Engine  // INCLUDES ///////////////////////////////////////////////////#define WIN32_LEAN_AND_MEAN  // make sure all macros are included      // 添加这句,告诉链接器链接这个lib文件#include <windows.h>         // include important windows stuff#include <windowsx.h> #include <mmsystem.h>#include <iostream>        // include important C/C++ stuff#include <conio.h>#include <stdlib.h>#include <malloc.h>#include <memory.h>#include <string.h>#include <stdarg.h>#include <stdio.h>#include <math.h>#include <io.h>#include <fcntl.h>#include <ddraw.h>           // directX includes#include "blackbox.h"        // game library includes                                   // DEFINES ////////////////////////////////////////////////////// TYPES //////////////////////////////////////////////////////// PROTOTYPES /////////////////////////////////////////////////// EXTERNALS //////////////////////////////////////////////////extern HWND main_window_handle; // save the window handleextern HINSTANCE main_instance; // save the instance// GLOBALS ////////////////////////////////////////////////////LPDIRECTDRAW7         lpdd         = NULL;   // dd objectLPDIRECTDRAWSURFACE7  lpddsprimary = NULL;   // dd primary surfaceLPDIRECTDRAWSURFACE7  lpddsback    = NULL;   // dd back surfaceLPDIRECTDRAWPALETTE   lpddpal      = NULL;   // a pointer to the created dd paletteLPDIRECTDRAWCLIPPER   lpddclipper  = NULL;   // dd clipperPALETTEENTRY          palette[256];          // color palettePALETTEENTRY          save_palette[256];     // used to save palettesDDSURFACEDESC2        ddsd;                  // a direct draw surface description structDDBLTFX               ddbltfx;               // used to fillDDSCAPS2              ddscaps;               // a direct draw surface capabilities structHRESULT               ddrval;                // result back from dd callsDWORD                 start_clock_count = 0; // used for timing// these defined the general clipping rectangleint min_clip_x = 0,                          // clipping rectangle     max_clip_x = SCREEN_WIDTH-1,    min_clip_y = 0,    max_clip_y = SCREEN_HEIGHT-1;// these are overwritten globally by DD_Init()int screen_width  = SCREEN_WIDTH,            // width of screen    screen_height = SCREEN_HEIGHT,           // height of screen    screen_bpp    = SCREEN_BPP;              // bits per pixel// FUNCTIONS //////////////////////////////////////////////////int DD_Init(int width, int height, int bpp){// this function initializes directdrawint index; // looping variable// create object and test for errorif (DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)!=DD_OK)   return(0);// set cooperation level to windowed mode normalif (lpdd->SetCooperativeLevel(main_window_handle,           DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN |            DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)!=DD_OK)    return(0);// set the display modeif (lpdd->SetDisplayMode(width,height,bpp,0,0)!=DD_OK)   return(0);// set globalsscreen_height = height;screen_width  = width;screen_bpp    = bpp;// Create the primary surfacememset(&ddsd,0,sizeof(ddsd));ddsd.dwSize = sizeof(ddsd);ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;// we need to let dd know that we want a complex // flippable surface structure, set flags for thatddsd.ddsCaps.dwCaps =   DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;// set the backbuffer count to 1ddsd.dwBackBufferCount = 1;// create the primary surfacelpdd->CreateSurface(&ddsd,&lpddsprimary,NULL);// query for the backbuffer i.e the secondary surfaceddscaps.dwCaps = DDSCAPS_BACKBUFFER;lpddsprimary->GetAttachedSurface(&ddscaps,&lpddsback);// create and attach palette// create palette data// clear all entries defensive programmingmemset(palette,0,256*sizeof(PALETTEENTRY));// create a R,G,B,GR gradient palettefor (index=0; index < 256; index++)    {    // set each entry    if (index < 64)         palette[index].peRed = index*4;     else           // shades of green    if (index >= 64 && index < 128)         palette[index].peGreen = (index-64)*4;    else           // shades of blue    if (index >= 128 && index < 192)        palette[index].peBlue = (index-128)*4;    else           // shades of grey    if (index >= 192 && index < 256)         palette[index].peRed = palette[index].peGreen =         palette[index].peBlue = (index-192)*4;        // set flags    palette[index].peFlags = PC_NOCOLLAPSE;    } // end for index// now create the palette objectif (lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256,                         palette,&lpddpal,NULL)!=DD_OK)   return(0);// attach the palette to the primaryif (lpddsprimary->SetPalette(lpddpal)!=DD_OK)   return(0);// clear out both primary and secondary surfacesDD_Fill_Surface(lpddsprimary,0);DD_Fill_Surface(lpddsback,0);// attach a clipper to the screenRECT screen_rect = {0,0,screen_width,screen_height};lpddclipper = DD_Attach_Clipper(lpddsback,1,&screen_rect);// return successreturn(1);} // end DD_Init///////////////////////////////////////////////////////////////int DD_Shutdown(void){// this function release all the resources directdraw// allocated, mainly to com objects// release the clipper firstif (lpddclipper)    lpddclipper->Release();// release the paletteif (lpddpal)   lpddpal->Release();// release the secondary surfaceif (lpddsback)    lpddsback->Release();// release the primary surfaceif (lpddsprimary)   lpddsprimary->Release();// finally, the main dd objectif (lpdd)    lpdd->Release();// return successreturn(1);} // end DD_Shutdown///////////////////////////////////////////////////////////////   LPDIRECTDRAWCLIPPER DD_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds,                                      int num_rects,                                      LPRECT clip_list){// this function creates a clipper from the sent clip list and attaches// it to the sent surfaceint index;                         // looping varLPDIRECTDRAWCLIPPER lpddclipper;   // pointer to the newly created dd clipperLPRGNDATA region_data;             // pointer to the region data that contains                                   // the header and clip list// first create the direct draw clipperif ((lpdd->CreateClipper(0,&lpddclipper,NULL))!=DD_OK)   return(NULL);// now create the clip list from the sent data// first allocate memory for region dataregion_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT));// now copy the rects into region datamemcpy(region_data->Buffer, clip_list, sizeof(RECT)*num_rects);// set up fields of headerregion_data->rdh.dwSize          = sizeof(RGNDATAHEADER);region_data->rdh.iType           = RDH_RECTANGLES;region_data->rdh.nCount          = num_rects;region_data->rdh.nRgnSize        = num_rects*sizeof(RECT);region_data->rdh.rcBound.left    =  64000;region_data->rdh.rcBound.top     =  64000;region_data->rdh.rcBound.right   = -64000;region_data->rdh.rcBound.bottom  = -64000;// find bounds of all clipping regionsfor (index=0; index<num_rects; index++)    {    // test if the next rectangle unioned with the current bound is larger    if (clip_list[index].left < region_data->rdh.rcBound.left)       region_data->rdh.rcBound.left = clip_list[index].left;    if (clip_list[index].right > region_data->rdh.rcBound.right)       region_data->rdh.rcBound.right = clip_list[index].right;    if (clip_list[index].top < region_data->rdh.rcBound.top)       region_data->rdh.rcBound.top = clip_list[index].top;    if (clip_list[index].bottom > region_data->rdh.rcBound.bottom)       region_data->rdh.rcBound.bottom = clip_list[index].bottom;    } // end for index// now we have computed the bounding rectangle region and set up the data// now let's set the clipping listif ((lpddclipper->SetClipList(region_data, 0))!=DD_OK)   {   // release memory and return error   free(region_data);   return(NULL);   } // end if// now attach the clipper to the surfaceif ((lpdds->SetClipper(lpddclipper))!=DD_OK)   {   // release memory and return error   free(region_data);   return(NULL);   } // end if// all is well, so release memory and send back the pointer to the new clipperfree(region_data);return(lpddclipper);} // end DD_Attach_Clipper///////////////////////////////////////////////////////////////   int DD_Flip(void){// this function flip the primary surface with the secondary surface// flip pageswhile(lpddsprimary->Flip(NULL, DDFLIP_WAIT)!=DD_OK);// flip the surface// return successreturn(1);} // end DD_Flip///////////////////////////////////////////////////////////////DWORD Start_Clock(void){// this function starts the clock, that is, saves the current// count, use in conjunction with Wait_Clock()return(start_clock_count = Get_Clock());} // end Start_Clock///////////////////////////////////////////////////////////////DWORD Get_Clock(void){// this function returns the current tick count// return timereturn(GetTickCount());} // end Get_Clock///////////////////////////////////////////////////////////////DWORD Wait_Clock(DWORD count){// this function is used to wait for a specific number of clicks// since the call to Start_Clockwhile((Get_Clock() - start_clock_count) < count);return(Get_Clock());} // end Wait_Clock///////////////////////////////////////////////////////////////int DD_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds,int color){DDBLTFX ddbltfx; // this contains the DDBLTFX structure// clear out the structure and set the size field DD_INIT_STRUCT(ddbltfx);// set the dwfillcolor field to the desired colorddbltfx.dwFillColor = color; // ready to blt to surfacelpdds->Blt(NULL,       // ptr to dest rectangle           NULL,       // ptr to source surface, NA                       NULL,       // ptr to source rectangle, NA           DDBLT_COLORFILL | DDBLT_WAIT | DDBLT_ASYNC,   // fill and wait                              &ddbltfx);  // ptr to DDBLTFX structure// return successreturn(1);} // end DD_Fill_Surface///////////////////////////////////////////////////////////////   int Draw_Rectangle(int x1, int y1, int x2, int y2, int color,                   LPDIRECTDRAWSURFACE7 lpdds){// this function uses directdraw to draw a filled rectangleDDBLTFX ddbltfx; // this contains the DDBLTFX structureRECT fill_area;  // this contains the destination rectangle// clear out the structure and set the size field DD_INIT_STRUCT(ddbltfx);// set the dwfillcolor field to the desired colorddbltfx.dwFillColor = color; // fill in the destination rectangle data (your data)fill_area.top    = y1;fill_area.left   = x1;fill_area.bottom = y2+1;fill_area.right  = x2+1;// ready to blt to surface, in this case blt to primarylpdds->Blt(&fill_area, // ptr to dest rectangle           NULL,       // ptr to source surface, NA                       NULL,       // ptr to source rectangle, NA           DDBLT_COLORFILL | DDBLT_WAIT | DDBLT_ASYNC,   // fill and wait                              &ddbltfx);  // ptr to DDBLTFX structure// return successreturn(1);} // end Draw_Rectangle///////////////////////////////////////////////////////////////int Draw_Text_GDI(char *text, int x,int y,int color, LPDIRECTDRAWSURFACE7 lpdds){// this function draws the sent text on the sent surface // using color index as the color in the paletteHDC xdc; // the working dc// get the dc from surfaceif (lpdds->GetDC(&xdc)!=DD_OK)   return(0);// set the colors for the text upSetTextColor(xdc,RGB(palette[color].peRed,palette[color].peGreen,palette[color].peBlue) );// set background mode to transparent so black isn't copiedSetBkMode(xdc, TRANSPARENT);// draw the text aTextOut(xdc,x,y,text,strlen(text));// release the dclpdds->ReleaseDC(xdc);// return successreturn(1);} // end Draw_Text_GDI///////////////////////////////////////////////////////////////

// BLACKBOX.H - Header file for demo game engine library// watch for multiple inclusions#ifndef BLACKBOX#define BLACKBOX#include <ddraw.h>           // directX includes#pragma comment(lib, "ddraw.lib")         // 添加这句,告诉链接器链接这个lib文件// 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 typestypedef unsigned short USHORT;typedef unsigned short WORD;typedef unsigned char  UCHAR;typedef unsigned char  BYTE;// EXTERNALS //////////////////////////////////////////////////extern LPDIRECTDRAW7         lpdd;                 // dd objectextern LPDIRECTDRAWSURFACE7  lpddsprimary;         // dd primary surfaceextern LPDIRECTDRAWSURFACE7  lpddsback;            // dd back surfaceextern LPDIRECTDRAWPALETTE   lpddpal;              // a pointer to the created dd paletteextern LPDIRECTDRAWCLIPPER   lpddclipper;          // dd clipperextern PALETTEENTRY          palette[256];         // color paletteextern PALETTEENTRY          save_palette[256];    // used to save palettesextern DDSURFACEDESC2        ddsd;                 // a direct draw surface description structextern DDBLTFX               ddbltfx;              // used to fillextern DDSCAPS2              ddscaps;              // a direct draw surface capabilities structextern HRESULT               ddrval;               // result back from dd callsextern DWORD                 start_clock_count;    // used for timing// these defined the general clipping rectangleextern 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 functionsint DD_Init(int width, int height, int bpp);int DD_Shutdown(void);LPDIRECTDRAWCLIPPER DD_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds, int num_rects, LPRECT clip_list);int DD_Flip(void);int DD_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds,int color);// general utility functionsDWORD Start_Clock(void);DWORD Get_Clock(void);DWORD Wait_Clock(DWORD count);// graphics functionsint Draw_Rectangle(int x1, int y1, int x2, int y2, int color,LPDIRECTDRAWSURFACE7 lpdds=lpddsback);// gdi functionsint Draw_Text_GDI(char *text, int x,int y,COLORREF color, LPDIRECTDRAWSURFACE7 lpdds=lpddsback);int Draw_Text_GDI(char *text, int x,int y,int color, LPDIRECTDRAWSURFACE7 lpdds=lpddsback);#endif



0 0
原创粉丝点击