⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 directdrawwin.cpp

📁 Clear Mine扫雷游戏: 这是一个模拟扫雷游戏的vc编码程序 编码思想: 通过几个数组设定好雷区的位置
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "Headers.h"
#include "DirectDrawApp.h"
#include "DirectDrawWin.h"
#include "ksrc\sound.h"
extern BOOL InitDirectInput();
extern BOOL ReleaseDirectInput();


#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

BEGIN_MESSAGE_MAP(DirectDrawWin, CWnd)
	//{{AFX_MSG_MAP(DirectDrawWin)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_ACTIVATEAPP()
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

DirectDrawWin* DirectDrawWin::thisptr;

BOOL DirectDrawWin::ActivateDisplayMode( int mode, DWORD rate )
{
	if ( mode<0 || mode>=totaldisplaymodes )
		return FALSE;

	DWORD width = displaymode[mode].width;
	DWORD height = displaymode[mode].height;
	DWORD depth = displaymode[mode].depth;
	
	displayrect.left=0;
	displayrect.top=0;
	displayrect.right=width;
	displayrect.bottom=height;
	displaydepth=depth;

	ddraw2->SetDisplayMode( width, height, depth, rate, 0 );
	curdisplaymode = mode;

	TRACE("------------------- %dx%dx%d (%dhz) ---------------\n", width, height, depth, rate);

	if (CreateFlippingSurfaces()==FALSE)
	{
		TRACE("CreateFlippingSurfaces() failed");
		return FALSE;
	}

	if (CreateCustomSurfaces()==FALSE)
	{
		TRACE("CreateCustomSurfaces() failed");
		return FALSE;
	}

	return TRUE;
}

BOOL DirectDrawWin::ActivateDisplayMode( int mode )
{
	if ( mode<0 || mode>=totaldisplaymodes )
		return FALSE;

	DWORD width = displaymode[mode].width;
	DWORD height = displaymode[mode].height;
	DWORD depth = displaymode[mode].depth;
	
	displayrect.left=0;
	displayrect.top=0;
	displayrect.right=width;
	displayrect.bottom=height;
	displaydepth=depth;

	ddraw2->SetDisplayMode( width, height, depth, 0, 0 );
	curdisplaymode = mode;

	TRACE("------------------- %dx%dx%d ----------------------\n", width, height, depth);

	if (CreateFlippingSurfaces()==FALSE)
	{
		TRACE("CreateFlippingSurfaces() failed");
		return FALSE;
	}

	if (CreateCustomSurfaces()==FALSE)
	{
		TRACE("CreateCustomSurfaces() failed");
		return FALSE;
	}

	return TRUE;
}

BOOL DirectDrawWin::BltSurface( LPDIRECTDRAWSURFACE destsurf, LPDIRECTDRAWSURFACE srcsurf, int x, int y, BOOL srccolorkey )
{
	if (destsurf==0 || srcsurf==0)
		return FALSE;

	BOOL use_fastblt=TRUE;

	DDSURFACEDESC destsurfdesc;
	ZeroMemory( &destsurfdesc, sizeof(destsurfdesc) );
	destsurfdesc.dwSize = sizeof(destsurfdesc);
	destsurf->GetSurfaceDesc( &destsurfdesc );

	CRect destrect;
	destrect.left=0;
	destrect.top=0;
	destrect.right=destsurfdesc.dwWidth;
	destrect.bottom=destsurfdesc.dwHeight;

	DDSURFACEDESC srcsurfdesc;
	ZeroMemory( &srcsurfdesc, sizeof(srcsurfdesc) );
	srcsurfdesc.dwSize = sizeof(srcsurfdesc);
	srcsurf->GetSurfaceDesc( &srcsurfdesc );

	CRect srcrect;
	srcrect.left=0;
	srcrect.top=0;
	srcrect.right=srcsurfdesc.dwWidth;
	srcrect.bottom=srcsurfdesc.dwHeight;
	
	// make sure that there is something to do...
	if (x+srcrect.left>=destrect.right)
		return FALSE;
	if (y+srcrect.top>=destrect.bottom)
		return FALSE;
	if (x+srcrect.right<=destrect.left)
		return FALSE;
	if (y+srcrect.bottom<=destrect.top)
		return FALSE;

	// clip the source rect if nessesary
	if (x+srcrect.right>destrect.right)
		srcrect.right-=x+srcrect.right-destrect.right;
	if (y+srcrect.bottom>destrect.bottom)
		srcrect.bottom-=y+srcrect.bottom-destrect.bottom;

	CRect dr;
	if (x<0)
	{
		srcrect.left=-x;
		x=0;
		dr.left=x;
		dr.top=y;
		dr.right=x+srcrect.Width();
		dr.bottom=y+srcrect.Height();
		use_fastblt=FALSE;
	}

	if (y<0)
	{
		srcrect.top=-y;
		y=0;
		dr.left=x;
		dr.top=y;
		dr.right=x+srcrect.Width();
		dr.bottom=y+srcrect.Height();
		use_fastblt=FALSE;
	}

	DWORD flags;
	if (use_fastblt)
	{
		flags=DDBLTFAST_WAIT;
		if (srccolorkey)
			flags |= DDBLTFAST_SRCCOLORKEY;
		destsurf->BltFast( x, y, srcsurf, &srcrect, flags );
	}
	else
	{
		flags=DDBLT_WAIT;
		if (srccolorkey)
			flags |= DDBLT_KEYSRC;
		destsurf->Blt( &dr, srcsurf, &srcrect, flags, 0 );
	}
	return TRUE;
}

BOOL DirectDrawWin::ClearSurface( LPDIRECTDRAWSURFACE surf, DWORD clr, RECT* rect )
{
	if (surf==0)
		return FALSE;

	DDBLTFX bltfx;
	ZeroMemory( &bltfx, sizeof(bltfx) );
	bltfx.dwSize = sizeof(bltfx);
	bltfx.dwFillColor = clr;

	HRESULT r;
	r=surf->Blt( rect, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx );
	if (r==DD_OK)
		return TRUE;

	if (r==DDERR_NOBLTHW && clr==0 && rect==0)
	{
		DDSURFACEDESC desc;
		ZeroMemory( &desc, sizeof(desc) );
		desc.dwSize = sizeof(desc);
		desc.dwFlags=DDSD_WIDTH | DDSD_HEIGHT;
		if (surf->GetSurfaceDesc( &desc )!=DD_OK)
			return FALSE;
		int w=desc.dwWidth;
		int h=desc.dwHeight;

		r=surf->Lock( 0, &desc, DDLOCK_WAIT  | DDLOCK_WRITEONLY, 0 );
		if (r!=DD_OK)
			return FALSE;

		BYTE* surfbits = (BYTE*)desc.lpSurface;

		for (int i=0;i<h;i++)
		{
			ZeroMemory( surfbits, desc.lPitch );
			surfbits += desc.lPitch;
		}
		surf->Unlock( 0 );
	}
	
	return FALSE;
}

int DirectDrawWin::CompareModes( const void *arg1, const void *arg2 )
{
	DisplayModeInfo* mode1=(DisplayModeInfo*)arg1;
	DisplayModeInfo* mode2=(DisplayModeInfo*)arg2;

	DWORD volume1=mode1->width*mode1->height;
	DWORD volume2=mode2->width*mode2->height;

	if (volume1<volume2)
		return -1;
	else if (volume1>volume2)
		return 1;

	if (mode1->depth<mode2->depth)
		return -1;
	else if (mode1->depth>mode2->depth)
		return 1;
	
	return 0;
}

BOOL DirectDrawWin::Copy_Bmp08_Surface08( LPDIRECTDRAWSURFACE surf, 
										 BYTE* bmpbuf, int w, int h )
{
	if (surf==0 || bmpbuf==0)
		return FALSE;

	DDSURFACEDESC desc;
	ZeroMemory( &desc, sizeof(desc) );
	desc.dwSize = sizeof(desc);
	HRESULT r=surf->Lock( 0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0 );
	if (r!=DD_OK)
	{
		TRACE("ShowBmp: Lock() failed\n");
		return FALSE;
	}
	int bytesgiven=(w+3) & ~3;
	BYTE* surfbits = (BYTE*)desc.lpSurface;
	BYTE* imagebits = (BYTE*)(&bmpbuf[(h-1)*bytesgiven]);
	for( int i=0; i<h; i++ )
	{
		memcpy( surfbits, imagebits, w );
		surfbits += desc.lPitch;
		imagebits -= bytesgiven;
	}
	surf->Unlock( 0 );
	return TRUE;
}

BOOL DirectDrawWin::Copy_Bmp_Surface( LPDIRECTDRAWSURFACE surf, 
		BITMAPINFOHEADER* bmphdr, BYTE* buf)
{
	if (surf==0 || bmphdr==0 || buf==0)
		return FALSE;
	
	int imagew=bmphdr->biWidth;
	int imageh=bmphdr->biHeight;
	int imagebitdepth=bmphdr->biBitCount;

	BOOL ret=FALSE;
	if (imagebitdepth==8)
	{
		if (displaydepth==8)
			ret=Copy_Bmp08_Surface08( surf, buf, imagew, imageh );
	}
	else 
		ret=FALSE;//not implent
	return ret;
}

BOOL DirectDrawWin::Create(const CString& title,int icon)
{
	CString sClassName;

	sClassName = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,LoadCursor(0, IDC_ARROW),
			(HBRUSH)(COLOR_WINDOW + 1), LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(icon)));

	return CWnd::CreateEx( WS_EX_TOPMOST, sClassName, title, WS_POPUP, 0,0,100,100, 0, 0 );
}

BOOL DirectDrawWin::CreateFlippingSurfaces()
{
	if (primsurf)
		primsurf->Release(), primsurf=0;

	DDSURFACEDESC desc;
	ZeroMemory( &desc, sizeof(desc) );
	desc.dwSize = sizeof( desc );
	desc.dwFlags =  DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
	desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
	desc.dwBackBufferCount = 1;
	HRESULT r=ddraw2->CreateSurface( &desc, &primsurf, 0 );
	if (r!=DD_OK)
		return FALSE;

	DDSCAPS surfcaps;
	surfcaps.dwCaps = DDSCAPS_BACKBUFFER;
	r=primsurf->GetAttachedSurface( &surfcaps, &backsurf );
	if (r!=DD_OK)
		return FALSE;

	ClearSurface( primsurf, 0 );
	ClearSurface( backsurf, 0 );

	return TRUE;
}

BOOL DirectDrawWin::CreatePalette(RGBQUAD* quad, int ncolors)
{
	if (palette)
		palette->Release(), palette=0;
	
	PALETTEENTRY pe[256];
	ZeroMemory( pe, sizeof(pe) );
	for( int i=0; i<ncolors; i++)
	{
		pe[i].peRed   = quad[i].rgbRed;
		pe[i].peGreen = quad[i].rgbGreen;
		pe[i].peBlue  = quad[i].rgbBlue;
	}

	HRESULT r=ddraw2->CreatePalette( DDPCAPS_8BIT | DDPCAPS_ALLOW256, 
								pe, &palette, 0 );
	if (r!=DD_OK)
	{
		TRACE("failed to create DirectDraw palette\n");
		return FALSE;
	}

	primsurf->SetPalette( palette );

	return TRUE;
}
/*
LPDIRECTDRAWSURFACE DirectDrawWin::CreateSurface(LPCTSTR filename, BOOL installpalette)
{
	int imagew, imageh;
	GetBmpDimensions( filename, imagew, imageh );
	
	LPDIRECTDRAWSURFACE surf=CreateSurface( imagew, imageh );
	if (surf==0)
	{
		TRACE("CreateSurface(filename) failed to create surface\n");
		return 0;
	}
	
	ifstream bmp( filename, ios::binary | ios::nocreate );
	if (!bmp.is_open())
	{
		TRACE("LoadSurface: cannot open Bmp file\n");
		return 0;
	}

	BITMAPFILEHEADER bmpfilehdr;
	bmp.read( (char*)&bmpfilehdr, sizeof(bmpfilehdr) );
	char* ptr=(char*)&bmpfilehdr.bfType;
	if (*ptr!='B' || *++ptr!='M')
	{
		TRACE("invalid bitmap\n");
		return 0;
	}

	BITMAPINFOHEADER bmpinfohdr;
	bmp.read( (char*)&bmpinfohdr, sizeof(bmpinfohdr) );
	bmp.seekg( sizeof(bmpfilehdr)+bmpinfohdr.biSize, ios::beg );
	int imagebitdepth=bmpinfohdr.biBitCount;

	int imagesize=bmpinfohdr.biSizeImage;
	if (imagesize==0)
		imagesize=((imagew*(imagebitdepth/8)+3) & ~3)*imageh;

	if (bmpinfohdr.biCompression!=BI_RGB)
	{
		TRACE("compressed BMP format\n");
		return 0;
	}

	TRACE("loading '%s': width=%d height=%d depth=%d\n", filename, imagew, imageh, imagebitdepth);

	if (imagebitdepth==8)
	{
		int ncolors;
		if (bmpinfohdr.biClrUsed==0)
			ncolors=256;
		else
			ncolors=bmpinfohdr.biClrUsed;

		RGBQUAD* quad=new RGBQUAD[ncolors];
		bmp.read( (char*)quad, sizeof(RGBQUAD)*ncolors );
		if (installpalette)
			CreatePalette( quad, ncolors );
		delete [] quad;
	}

	BYTE* buf=new BYTE[imagesize];
	bmp.read( buf, imagesize );

	if (!Copy_Bmp_Surface( surf, &bmpinfohdr, buf ))
	{
		TRACE("copy failed\n");
		delete [] buf;
		surf->Release();
		return 0;
	}

	delete [] buf;

	return surf;
}
*/
LPDIRECTDRAWSURFACE DirectDrawWin::CreateSurface( DWORD w, DWORD h )
{
	DWORD bytes=w*h*(displaydepth/8);

	DDSURFACEDESC desc;
	ZeroMemory( &desc, sizeof(desc) );
	desc.dwSize = sizeof(desc);
	desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
	desc.dwWidth = w;
	desc.dwHeight = h;
	desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;

	LPDIRECTDRAWSURFACE surf;
	HRESULT r=ddraw2->CreateSurface( &desc, &surf, 0 );
	if (r==DD_OK)
	{
		TRACE("CreateSurface(%d,%d) created in video memory (%d bytes)\n", w, h, bytes);
		return surf;
	}

	desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
	r=ddraw2->CreateSurface( &desc, &surf, 0 );
	if (r==DD_OK)
	{
		TRACE("CreateSurface(%d,%d) allocated in system memory (%d bytes)\n", w, h, bytes);
		return surf;
	}

	TRACE("CreateSurface(%d,%d) failed\n", w, h);
	return 0;
}


DirectDrawWin::DirectDrawWin()
{
	thisptr=this;

	totaldrivers=0;
	totaldisplaymodes=0;
	curdisplaymode=-1;

	ddraw2=0;
	primsurf=0;
	backsurf=0;
	palette=0;

	window_active=TRUE;


    DirectDrawApp* pApp = (DirectDrawApp*)AfxGetApp();
    pApp->ddwin = this;
}

HRESULT WINAPI DirectDrawWin::DisplayModeAvailable( LPDDSURFACEDESC desc, LPVOID p )
{
	DirectDrawWin* win=(DirectDrawWin*)p;

	int& count=win->totaldisplaymodes;
	if (count==MAXDISPLAYMODES)
		return DDENUMRET_CANCEL;

	win->displaymode[count].width  = desc->dwWidth;
	win->displaymode[count].height = desc->dwHeight;
	win->displaymode[count].depth  = desc->ddpfPixelFormat.dwRGBBitCount;

	count++;

	return DDENUMRET_OK;
}

BOOL WINAPI DirectDrawWin::DriverAvailable(LPGUID guid, LPSTR desc, LPSTR name, LPVOID p )
{
	DirectDrawWin* win=(DirectDrawWin*)p;

	if (win->totaldrivers >= MAXDRIVERS)
		return DDENUMRET_CANCEL;

	DriverInfo& info=win->driver[win->totaldrivers];

	if (guid)
	{
		info.guid=(GUID*)new BYTE[sizeof(GUID)];
		memcpy( info.guid, guid, sizeof(GUID) );
	}
	else
		info.guid=0;

	info.desc=strdup( desc );
	info.name=strdup( name );

	win->totaldrivers++;

    return DDENUMRET_OK;
}
/*
BOOL DirectDrawWin::GetBmpDimensions( LPCTSTR filename, int& w, int& h)
{
	ifstream bmp( filename, ios::binary | ios::nocreate );
	if (!bmp.is_open())
	{
		TRACE("GetBmpDimensions: cannot open file\n");
		return FALSE;
	}

	BITMAPFILEHEADER bmpfilehdr;
	bmp.read( (char*)&bmpfilehdr, sizeof(bmpfilehdr) );

	char* ptr=(char*)&bmpfilehdr.bfType;
	if (*ptr!='B' || *++ptr!='M')
	{
		TRACE("GetBmpDimensions: invalid bitmap\n");
		return FALSE;
	}

	BITMAPINFOHEADER bmpinfohdr;
	bmp.read( (char*)&bmpinfohdr, sizeof(bmpinfohdr) );

	w=bmpinfohdr.biWidth;
	h=bmpinfohdr.biHeight;

	return TRUE;
}
*/
BOOL DirectDrawWin::GetDisplayModeDimensions( int mode, DWORD& width, DWORD& height, DWORD& depth )
{
	if ( mode < 0 || mode > totaldisplaymodes )
		return FALSE;

	width  = displaymode[mode].width;
	height = displaymode[mode].height;
	depth  = displaymode[mode].depth;

	return TRUE;
}

int DirectDrawWin::GetDisplayModeIndex( DWORD w, DWORD h, DWORD d )
{
	for (int i=0;i<totaldisplaymodes;i++)
	{
		DisplayModeInfo& m=displaymode[i];
		if (m.width==w && m.height==h && m.depth==d)
			return i;
	}
	return -1;
}

BOOL DirectDrawWin::GetDriverInfo( int index, LPGUID* guid, LPSTR* desc, LPSTR* name )
{
	if (index<0 || index>totaldrivers)
		return FALSE;

	if (name)
		*name=driver[index].name;
	if (desc)
		*desc=driver[index].desc;
	if (guid)
		*guid=driver[index].guid;

	return TRUE;
}

BOOL DirectDrawWin::GetSurfaceDimensions( LPDIRECTDRAWSURFACE surf, DWORD& w, DWORD& h )
{
	if (surf==0)
		return FALSE;

	DDSURFACEDESC desc;
	ZeroMemory( &desc, sizeof(desc) );
	desc.dwSize=sizeof(desc);
	desc.dwFlags=DDSD_WIDTH | DDSD_HEIGHT;

	if (surf->GetSurfaceDesc( &desc )!=DD_OK)
		return FALSE;

	w=desc.dwWidth;
	h=desc.dwHeight;

	return TRUE;
}

BOOL DirectDrawWin::GetSurfaceRect( LPDIRECTDRAWSURFACE surf, RECT& rect)
{
	if (surf==0)
		return FALSE;

	DDSURFACEDESC desc;
	desc.dwSize=sizeof(desc);
	desc.dwFlags=DDSD_WIDTH | DDSD_HEIGHT;

	if (surf->GetSurfaceDesc( &desc )!=DD_OK)
		return FALSE;

	rect.left=0;
	rect.top=0;
	rect.right=desc.dwWidth;
	rect.bottom=desc.dwHeight;

	return TRUE;
}
/*
BOOL DirectDrawWin::LoadSurface( LPDIRECTDRAWSURFACE surf, LPCTSTR filename)
{
	ifstream bmp( filename, ios::binary | ios::nocreate );
	if (!bmp.is_open())
	{
		TRACE("LoadSurface: cannot open Bmp file\n");
		return FALSE;
	}

	BITMAPFILEHEADER bmpfilehdr;
	bmp.read( (char*)&bmpfilehdr, sizeof(bmpfilehdr) );

	char* ptr=(char*)&bmpfilehdr.bfType;
	if (*ptr!='B' || *++ptr!='M')
	{
		TRACE("LoadSurface: invalid bitmap\n");
		return FALSE;
	}
	
	BITMAPINFOHEADER bmpinfohdr;
	bmp.read( (char*)&bmpinfohdr, sizeof(bmpinfohdr) );
	bmp.seekg( sizeof(bmpfilehdr)+bmpinfohdr.biSize, ios::beg );

	int imagew=bmpinfohdr.biWidth;
	int imageh=bmpinfohdr.biHeight;
	int imagebitdepth=bmpinfohdr.biBitCount;

	int imagesize=bmpinfohdr.biSizeImage;
	if (imagesize==0)
		imagesize=((imagew*(imagebitdepth/8)+3) & ~3)*imageh;

	if (bmpinfohdr.biCompression!=BI_RGB)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -