www.pudn.com > DirectX的游戏代码.rar > BlackBox.cpp


// BlackBox.cpp: implementation of the CBlackBox class. 
// 
////////////////////////////////////////////////////////////////////// 
#include "stdio.h" 
#include "BlackBox.h" 
#include "GameInfo.h" 
 
int			g_max_x=WINDOW_WIDTH; 
int			g_max_y=WINDOW_HEIGHT; 
int			g_max_colors=MAX_COLORS; 
int			g_screen_bpp=SCREEN_BPP; 
 
#pragma comment(lib,"Ddraw.lib") 
#pragma comment(lib,"Dxguid.lib") 
 
LPDIRECTDRAW7         lpdd         = NULL;   // dd object 
LPDIRECTDRAWSURFACE7  lpddsprimary = NULL;   // dd primary surface 
LPDIRECTDRAWSURFACE7  lpddsback    = NULL;   // dd back surface 
LPDIRECTDRAWPALETTE   lpddpal      = NULL;   // a pointer to the created dd palette 
LPDIRECTDRAWCLIPPER   lpddclipper  = NULL;   // dd clipper 
PALETTEENTRY          palette[256];          // color palette 
PALETTEENTRY          save_palette[256];     // used to save palettes 
DDSURFACEDESC2        ddsd;                  // a direct draw surface description struct 
DDBLTFX               ddbltfx;               // used to fill 
DDSCAPS2              ddscaps;               // a direct draw surface capabilities struct 
 
extern HWND		g_h_wnd; 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CBlackBox::CBlackBox() 
{ 
 
} 
 
CBlackBox::~CBlackBox() 
{ 
 
} 
void CBlackBox::LogFile(char *p) 
{ 
	FILE *f; 
	if((f=fopen("log.txt","a"))==NULL) 
	{ 
		return; 
	} 
	fseek(f,0,SEEK_END); 
 
	fwrite(p,strlen(p),1,f); 
	fclose(f); 
	return; 
} 
bool CBlackBox::DD_Init() 
{ 
	HRESULT result; 
	result=DirectDrawCreateEx(NULL,(VOID**)&lpdd,IID_IDirectDraw7,NULL); 
	if(DD_OK!=result) 
	{ 
		MessageBox(NULL,"DirectDrawCreateEx fail!","fail",MB_OKCANCEL); 
		return false; 
	} 
	result=lpdd->SetCooperativeLevel(g_h_wnd,DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN 
		|DDSCL_ALLOWREBOOT); 
	if(DD_OK!=result) 
	{ 
		MessageBox(NULL,"lpdd->SetCooperativeLevel(g_h_wnd,DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN|DDSCL_ALLOWREBOOT) FAIL", 
			"FAIL",MB_OKCANCEL); 
		return false; 
	} 
	result=lpdd->SetDisplayMode(g_max_x,g_max_y,g_screen_bpp,0,DDSDM_STANDARDVGAMODE); 
	if(DD_OK!=result) 
	{ 
		MessageBox(NULL,"SetDisplayMode(g_max_x,g_max_y,g_screen_bpp,0,DDSDM_STANDARDVGAMODE)","FAIL",MB_OKCANCEL); 
		return false; 
	} 
	memset(&ddsd,sizeof(ddsd),0); 
	ddsd.dwSize=sizeof(ddsd); 
	ddsd.dwFlags=DDSD_CAPS|DDSD_BACKBUFFERCOUNT; 
	ddsd.dwBackBufferCount=1; 
	ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE|DDSCAPS_COMPLEX|DDSCAPS_FLIP; 
	 
	result=lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL); 
	if(DD_OK!=result) 
	{ 
		MessageBox(NULL,"lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL) fail","FALI",MB_OKCANCEL); 
		return false; 
	} 
	ddscaps.dwCaps=DDSCAPS_BACKBUFFER; 
	result=lpddsprimary->GetAttachedSurface(&ddscaps,&lpddsback); 
	if(DD_OK!=result) 
	{ 
		MessageBox(NULL,"lpPb->GetAttachedSurface(&ddsc,&lpBb) fail","fail",MB_OKCANCEL); 
		return false; 
	} 
	 
	//初始化调色板 
	memset(palette,0,256*sizeof(PALETTEENTRY)); 
	for(int i=0;i<256;i++) 
	{ 
		if(i<64) 
		{ 
			palette[i].peRed=i*4; 
		} 
		else if(i>=64 && i<128) 
		{ 
			palette[i].peGreen=(i-64)*4; 
		} 
		else if(i>=128 && i<192) 
		{ 
			palette[i].peBlue=(i-128)*4; 
		} 
		else if(i>=192 && i<256) 
		{ 
			palette[i].peGreen= 
				palette[i].peGreen= 
				palette[i].peGreen=(i-192)*4; 
		} 
		palette[i].peFlags=PC_NOCOLLAPSE; 
	} 
	 
	result=lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256, 
		palette,&lpddpal,NULL); 
	if(result!=DD_OK) 
	{ 
		MessageBox(NULL,"CreatePalette fail","fail",MB_OKCANCEL); 
		return false; 
	} 
	result=lpddsprimary->SetPalette(lpddpal); 
	if(result!=DD_OK) 
	{ 
		MessageBox(NULL,"SetPalette fail","fail",MB_OKCANCEL); 
		return false; 
	} 
	 
	RECT screen_rect = {0,0,g_max_x,g_max_y}; 
	lpddclipper = DD_Attach_Clipper(1,&screen_rect,lpddsback); 
	 
	return true; 
} 
 
void CBlackBox::DD_Fill_Surface(int color,LPDIRECTDRAWSURFACE7 lpdds) 
{ 
	DD_INIT_STRUCT(ddbltfx); 
 
	ddbltfx.dwFillColor=color; 
 
	lpdds->Blt(NULL, 
			   NULL, 
			   NULL, 
			   DDBLT_COLORFILL | DDBLT_WAIT | DDBLT_ASYNC, 
			   &ddbltfx); 
} 
 
void CBlackBox::DD_ShutDown() 
{ 
	if (lpddclipper) 
		lpddclipper->Release(); 
	 
	// release the palette 
	if (lpddpal) 
		lpddpal->Release(); 
	 
	// release the secondary surface 
	if (lpddsback) 
		lpddsback->Release(); 
	 
	// release the primary surface 
	if (lpddsprimary) 
		lpddsprimary->Release(); 
	 
	// finally, the main dd object 
	if (lpdd) 
		lpdd->Release(); 
} 
 
LPDIRECTDRAWCLIPPER CBlackBox::DD_Attach_Clipper(int num_rects,LPRECT clip_list,LPDIRECTDRAWSURFACE7 lpdds) 
{ 
	int index;                         // looping var 
	LPDIRECTDRAWCLIPPER lpddclipper;   // pointer to the newly created dd clipper 
	LPRGNDATA region_data;             // pointer to the region data that contains 
	// first create the direct draw clipper 
	if ((lpdd->CreateClipper(0,&lpddclipper,NULL))!=DD_OK) 
		return(NULL); 
	 
	// now create the clip list from the sent data 
	 
	// first allocate memory for region data 
	region_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT)); 
	 
	// now copy the rects into region data 
	memcpy(region_data->Buffer, clip_list, sizeof(RECT)*num_rects); 
	 
	// set up fields of header 
	region_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 regions 
	for (index=0; indexrdh.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 list 
	 
	if ((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 surface 
	if ((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 clipper 
	free(region_data); 
 
	return(lpddclipper); 
} // end DD_Attach_Clipper 
 
void CBlackBox::DD_Flip() 
{ 
	while(lpddsprimary->Flip(NULL, DDFLIP_WAIT)!=DD_OK); 
} 
 
/********************************************************************************* 
*GDI代码 
*********************************************************************************/ 
int CBlackBox::Draw_Rectangle(int x1, int y1, int x2, int y2, int color,LPDIRECTDRAWSURFACE7 lpdds) 
{ 
	RECT	fill_area; 
	DD_INIT_STRUCT(ddbltfx); 
 
	ddbltfx.dwFillColor=color; 
 
	fill_area.left=x1; 
	fill_area.top=y1; 
	fill_area.right=x2; 
	fill_area.bottom=y2; 
 
	lpdds->Blt(&fill_area,NULL,NULL, 
		DDBLT_COLORFILL | DDBLT_WAIT | DDBLT_ASYNC, 
		&ddbltfx); 
	return (1); 
} 
int CBlackBox::Draw_Text_GDI(char *text, int x,int y,int color, LPDIRECTDRAWSURFACE7 lpdds) 
{ 
	HDC hdc; 
 
	if(lpdds->GetDC(&hdc)!=DD_OK) 
	{ 
		return (0); 
	} 
 
	SetTextColor(hdc,RGB(palette[color].peRed,palette[color].peGreen,palette[color].peBlue)); 
	SetBkMode(hdc,TRANSPARENT); 
 
	TextOut(hdc,x,y,text,strlen(text)); 
 
	lpdds->ReleaseDC(hdc); 
 
	return (1); 
} 
 
double CBlackBox::DD_Start_Clock() 
{ 
	m_start_clock=GetTickCount(); 
	return m_start_clock; 
} 
 
double CBlackBox::DD_Wait_Clock(double count) 
{ 
	while(GetTickCount()-m_start_clock