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
- windows编程大师技巧第二版学习笔记——开发环境的搭建
- Windows游戏编程大师技巧(第二版)笔记-第一章
- Windows游戏编程大师技巧第二版学习笔记之第一章
- Windows游戏编程大师技巧第二版学习笔记之第一章 实验补充
- 《Windows游戏编程大师技巧》学习笔记——关于创建显示表面
- 《Windows游戏编程大师技巧》(第二版)
- windows游戏编程技巧大师第二章
- 《3D游戏编程大师技巧》——学习笔记
- 《WINDOWS游戏编程大师技巧》学习笔记1
- 游戏编程大师技巧—windows程序的基本构造
- 开始利用CSDN做学习笔记,从windows 游戏编程大师技巧和3D游戏编程大师开始
- 《Windows游戏编程大师技巧》(第二版)第1章(上)
- 《Windows游戏编程大师技巧》(第二版)第1章(下)
- 《Windows游戏编程大师技巧》(第二版)第2章
- 《Windows游戏编程大师技巧》(第二版)第11章
- 随便读读:Windows 游戏编程大师技巧 (第二版) 关于BOB
- 《Windows游戏编程大师技巧》(第二版)第1章(上)
- 《Windows游戏编程大师技巧》(第二版)第1章(下)
- 冒泡排序的三种实现
- java读取属性配置(properties)文件
- ZOJ 3905 Cake (DP)
- Android应用程序与SurfaceFlinger服务的连接过程分析
- UITabBarController--标签控制器
- windows编程大师技巧第二版学习笔记——开发环境的搭建
- ZOJ 补题 3903 && 3905 && 3911 (ZOJ Monthly, October 2015)
- Hadoop生态专辑 —— 总体架构目录
- 程序员的开始,起飞
- [ERP]ERP项目管理的利器——“均衡”之道
- HTML之Position用法
- 程序信息推送
- UITableViewController 表视图控制器
- Arrays数组转变成集合