www.gusucode.com > VC++游戏雷霆战机源代码-源码程序 > VC++游戏雷霆战机源代码-源码程序\code\DirectWnd.cpp

    // DirectWnd.cpp: implementation of the CDirectWnd class.
// Download by http://www.NewXing.com
//////////////////////////////////////////////////////////////////////

#include "DirectWnd.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDirectWnd::CDirectWnd(HINSTANCE hInstance,
					   int nCmdShow):CWindow(hInstance,nCmdShow)
{
	lpDD=NULL;
    lpFrontBuffer=NULL;
    lpBackBuffer=NULL;
	for (int i = 0; i < BkgNum; i++)
	{
		lpBKGObject[i]=NULL;

	}
    nBufferCount=1;
}

CDirectWnd::~CDirectWnd()
{
	if(lpDD)
    {
		CleanSurface();
		lpDD->Release();
        lpDD=NULL;
    }
}

void CDirectWnd::CleanSurface()
{  
    SAFE_RELEASE(lpBackBuffer)
    SAFE_RELEASE(lpFrontBuffer)
	for (int i = 0; i < BkgNum; i++)
	{
		SAFE_RELEASE(lpBKGObject[i])
	}
    return;
}

void CDirectWnd::LoadBitmapResource()
{
	lpBKGObject[0] = DDLoadBitmap(lpDD,"pic//loading.bmp",640,480);
	lpBKGObject[1] = DDLoadBitmap(lpDD,"pic//bkgnd.bmp",200,200);
	lpBKGObject[2] = DDLoadBitmap(lpDD,"pic//bkgnd1.bmp",200,200);
	
	// 创建我机页面
	lpBKGObject[3] = DDLoadBitmap(lpDD,"pic//center.bmp",50,60);
	lpBKGObject[4] = DDLoadBitmap(lpDD,"pic//left.bmp",50,60);
	lpBKGObject[5] = DDLoadBitmap(lpDD,"pic//right.bmp",50,60);
	DDSetColorKey(lpBKGObject[3],RGB(0,0,0));
	DDSetColorKey(lpBKGObject[4],RGB(0,0,0));
	DDSetColorKey(lpBKGObject[5],RGB(0,0,0));
    
	// 创建子弹页面
	lpBKGObject[6] = DDLoadBitmap(lpDD,"pic//bullet.bmp",16*5,20);
	DDSetColorKey(lpBKGObject[6],RGB(0,0,0));

	//创建敌机页面
	lpBKGObject[7] = DDLoadBitmap(lpDD,"pic//enemy.bmp",230,130);
	DDSetColorKey(lpBKGObject[7],RGB(0,0,0));

	//创建爆炸页面
	lpBKGObject[8] = DDLoadBitmap(lpDD,"pic//explode.bmp",780,170);
	DDSetColorKey(lpBKGObject[8],RGB(0,0,0));
	
	//创建奖励物品页面
	lpBKGObject[9] = DDLoadBitmap(lpDD,"pic//bonus.bmp",80,120);
	DDSetColorKey(lpBKGObject[9],RGB(0,0,0));

	//创建游戏结束页面
	lpBKGObject[10] = DDLoadBitmap(lpDD,"pic//gameover.bmp",640,480);

	//创建炸弹页面
	lpBKGObject[11] = DDLoadBitmap(lpDD,"pic//enemy1.bmp",35,35);
	DDSetColorKey(lpBKGObject[11],RGB(4,4,4));
}

BOOL CDirectWnd::InitializeWnd(UINT Width,UINT Height,UINT Bpp)
{
	DDSURFACEDESC ddsd ; //表面描述
	DDSCAPS ddscaps ;
	
	::ZeroMemory(&ddsd,sizeof(ddsd));//清零(起始,长度)
	//创建DirectDraw对象
    DirectDrawCreate(NULL,&lpDD,NULL);
	//取得独占和全屏模式
    lpDD->SetCooperativeLevel(GetHwnd(),DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN);
    //设置显示模式
	lpDD->SetDisplayMode(Width,Height,Bpp);
    //也可以加 HRESULT ddrval;	它是下面三个函数的返回值.
	DDCAPS ddcaps;
	ddcaps.dwSize=sizeof(ddcaps);
    lpDD->GetCaps(&ddcaps,NULL);
	
	//填充主表面信息
    ddsd.dwSize=sizeof(ddsd);
    ddsd.dwFlags=DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
    ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX;
    ddsd.dwBackBufferCount=nBufferCount;
	//创建主表面对象
    
	lpDD->CreateSurface(&ddsd,&lpFrontBuffer,NULL);		
    //提取后台缓存表面指针

    ddscaps.dwCaps=DDSCAPS_BACKBUFFER;
    lpFrontBuffer->GetAttachedSurface(&ddscaps,&lpBackBuffer);

	LoadBitmapResource();
	return TRUE;
}

HRESULT CDirectWnd::FlipScreen()
{
    HRESULT hr;

    if( NULL == lpFrontBuffer && NULL == lpBackBuffer )
        return E_POINTER;

    while( 1 )
    {   
        hr = lpFrontBuffer->Flip( NULL, 0 );
        if( hr == DDERR_SURFACELOST )
        {
            lpFrontBuffer->Restore();
            lpBackBuffer->Restore();
        }

        if( hr != DDERR_WASSTILLDRAWING )
            return hr;
    }
}

HRESULT CDirectWnd::Clear(DWORD dwColor)
{
    if( NULL == lpBackBuffer )
        return E_POINTER;
	 
	DDBLTFX ddbltfx;
    ZeroMemory( &ddbltfx, sizeof(ddbltfx) );
    ddbltfx.dwSize      = sizeof(ddbltfx);
    ddbltfx.dwFillColor = dwColor;
    return lpBackBuffer->Blt( NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx );
}

void CDirectWnd::BltBitMap( LPDIRECTDRAWSURFACE surSrc,
						    LPDIRECTDRAWSURFACE surDest,
						    RECT *rtSrc,
						    RECT *rtDest)
{
	surDest->Blt( rtDest,//dest rect
				  surSrc,//src surface
				  rtSrc,//src rect
				  DDBLT_WAIT,
			      NULL);
}

void CDirectWnd::BltBitMap(	LPDIRECTDRAWSURFACE surSrc,
						    RECT *rtSrc,
						    RECT *rtDest)
{
	lpBackBuffer->Blt( rtDest,//dest rect
					   surSrc,//src surface
					   rtSrc,//src rect
					   DDBLT_WAIT,
					   NULL);
}

void CDirectWnd::BltObject( LPDIRECTDRAWSURFACE surSrc,
						    LPDIRECTDRAWSURFACE surDest,
						    RECT *rtSrc,
						    RECT *rtDest)
{
	surDest->Blt( rtDest,//dest rect
				  surSrc,//src surface
				  rtSrc,//src rect
				  DDBLT_WAIT|DDBLT_KEYSRC,
			      NULL);
}

void CDirectWnd::BltObject(	LPDIRECTDRAWSURFACE surSrc,
						    RECT *rtSrc,
						    RECT *rtDest)
{
	lpBackBuffer->Blt( rtDest,//dest rect
					   surSrc,//src surface
					   rtSrc,//src rect
					   DDBLT_WAIT|DDBLT_KEYSRC,
					   NULL);
}

LPDIRECTDRAWSURFACE CDirectWnd::CreateSurface(DWORD width,DWORD height)
{
	IDirectDrawSurface *pdds;
	DDSURFACEDESC ddsd;
	ZeroMemory(&ddsd, sizeof(ddsd));
	ddsd.dwSize=sizeof(ddsd);
	ddsd.dwFlags=DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT;
    ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN;	
	ddsd.dwWidth = width;
	ddsd.dwHeight = height;
	lpDD->CreateSurface( &ddsd, &pdds, NULL );
	return pdds;
}

void CDirectWnd::GetRect(RECT* rect, long left, long top, long width, long height)
{
	rect->left=left;
	rect->top=top;
	rect->right=left+width;
	rect->bottom=top+height;
	return;
}

void CDirectWnd::ShowText( int x, int y, char *text , COLORREF color )
{
	HDC hdc;
	lpBackBuffer->GetDC(&hdc);
	SetBkMode(hdc,TRANSPARENT);
	SetTextColor(hdc,color);
	TextOut(hdc,x,y,text,strlen(text));
	lpBackBuffer->ReleaseDC(hdc);
}

void CDirectWnd::ShowText( int x, int y, int num , COLORREF color )
{
	HDC hdc;
	char temp[200];
	sprintf(temp,"%d",num);
	lpBackBuffer->GetDC(&hdc);
	SetBkMode(hdc,TRANSPARENT);
	SetTextColor(hdc,color);
	TextOut(hdc,x,y,temp,strlen(temp));
	lpBackBuffer->ReleaseDC(hdc);
}

IDirectDrawSurface * CDirectWnd::DDLoadBitmap(IDirectDraw *pdd, LPCSTR szBitmap, int dx, int dy)
{
    HBITMAP             hbm;
    BITMAP              bm;
    DDSURFACEDESC       ddsd;
    IDirectDrawSurface *pdds;

    //
    //  try to load the bitmap as a resource, if that fails, try it as a file
    //
    hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, dx, dy, LR_CREATEDIBSECTION);

    if (hbm == NULL)
        hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, dx, dy, LR_LOADFROMFILE|LR_CREATEDIBSECTION);

    if (hbm == NULL)
        return NULL;

    //
    // get size of the bitmap
    //
    GetObject(hbm, sizeof(bm), &bm);      // get size of bitmap

    //
    // create a DirectDrawSurface for this bitmap
    //
    ZeroMemory(&ddsd, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    ddsd.dwWidth = bm.bmWidth;
    ddsd.dwHeight = bm.bmHeight;

    if (pdd->CreateSurface(&ddsd, &pdds, NULL) != DD_OK)
        return NULL;

    DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);

    DeleteObject(hbm);

    return pdds;
}

HRESULT CDirectWnd::DDSetColorKey(IDirectDrawSurface *pdds, COLORREF rgb)
{
    DDCOLORKEY          ddck;

    ddck.dwColorSpaceLowValue  = DDColorMatch(pdds, rgb);
    ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
    return pdds->SetColorKey(DDCKEY_SRCBLT, &ddck);
}

HRESULT CDirectWnd::DDCopyBitmap(IDirectDrawSurface *pdds, HBITMAP hbm, int x, int y, int dx, int dy)
{
    HDC                 hdcImage;
    HDC                 hdc;
    BITMAP              bm;
    DDSURFACEDESC       ddsd;
    HRESULT             hr;

    if (hbm == NULL || pdds == NULL)
        return E_FAIL;

    //
    // make sure this surface is restored.
    //
    pdds->Restore();

    //
    //  select bitmap into a memoryDC so we can use it.
    //
    hdcImage = CreateCompatibleDC(NULL);
    if (!hdcImage)
        OutputDebugString("createcompatible dc failed\n");
    SelectObject(hdcImage, hbm);

    //
    // get size of the bitmap
    //
    GetObject(hbm, sizeof(bm), &bm);    // get size of bitmap
    dx = dx == 0 ? bm.bmWidth  : dx;    // use the passed size, unless zero
    dy = dy == 0 ? bm.bmHeight : dy;

    //
    // get size of surface.
    //
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
    pdds->GetSurfaceDesc(&ddsd);

    if ((hr = pdds->GetDC(&hdc)) == DD_OK)
    {
        StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y, dx, dy, SRCCOPY);
        pdds->ReleaseDC(hdc);
    }

    DeleteDC(hdcImage);

    return hr;
}

/*
 * DDColorMatch
 *
 * convert a RGB color to a pysical color.
 *
 * we do this by leting GDI SetPixel() do the color matching
 * then we lock the memory and see what it got mapped to.
 */
//获得指定颜色所对应的调色板索引
DWORD CDirectWnd::DDColorMatch(IDirectDrawSurface *pdds, COLORREF rgb)
{
    COLORREF rgbT;
    HDC hdc;
    DWORD dw = CLR_INVALID;
    DDSURFACEDESC ddsd;
    HRESULT hres;

    //
    //  use GDI SetPixel to color match for us
    //
    if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
    {
        rgbT = GetPixel(hdc, 0, 0);             // save current pixel value
        SetPixel(hdc, 0, 0, rgb);               // set our value
        pdds->ReleaseDC(hdc);
    }

    //
    // now lock the surface so we can read back the converted color
    //
    ddsd.dwSize = sizeof(ddsd);
    while ((hres = pdds->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
        ;

    if (hres == DD_OK)
    {
        dw  = *(DWORD *)ddsd.lpSurface;                     // get DWORD
        dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount)-1;  // mask it to bpp
        pdds->Unlock(NULL);
    }

    //
    //  now put the color that was there back.
    //
    if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
    {
        SetPixel(hdc, 0, 0, rgbT);
        pdds->ReleaseDC(hdc);
    }

    return dw;
}