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