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

📄 display.cpp

📁 冰人引擎,本2d游戏引擎定位于游戏次中层引擎。他不像CDX等引擎那样
💻 CPP
字号:
#include "StdAfx.h"
#include "display.h"

#pragma comment(lib , "dxguid.lib" )
#pragma comment(lib , "ddraw.lib" )
#pragma comment(lib , "winmm.lib" )

CDisplay* CDisplay::m_Instance = 0;

CDisplay::CDisplay(void)
{
	m_pDraw = NULL;
	m_pMainBuffer = NULL;
	m_pBackBuffer = NULL;

	m_dwScreenColor = 32;

	m_dwFPSState = false;

	m_pEngineBuffer = NULL;
	m_dwEngineBufferPitch = 0;
}

CDisplay::~CDisplay(void)
{
	Destroy();
}

CDisplay* CDisplay::Instance(void)
{
	if(m_Instance == 0)
		m_Instance = new CDisplay;
	return m_Instance;
}

bool CDisplay::Create(HWND hWnd,bool isFullScreen,DWORD Width,DWORD Height,DWORD ScreenColor)
{
	RECT Rect;
	m_hWnd = hWnd;
	m_bFullScreen = isFullScreen;
	m_dwScreenHeight = Height;
	m_dwScreenWidth = Width;
	m_dwScreenColor = ScreenColor;
	
	NesDrawLineInit();

	// 创建DirectDraw7接口
	if( FAILED( DirectDrawCreateEx( NULL , ( VOID ** )&m_pDraw , IID_IDirectDraw7 , NULL ) ) )
	{
		DebugMsg("DirectDrawCreateEx Error\n");
		return false;
	}

	// 设置窗口合作级别
	if( m_bFullScreen )
	{
		if( FAILED( m_pDraw->SetCooperativeLevel( hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN ) ) )
		{
			DebugMsg("Ddraw CooperativeLevel Error\n");
			return false;
		}
		if( FAILED( m_pDraw->SetDisplayMode( m_dwScreenWidth , m_dwScreenHeight , m_dwScreenColor , 0 , 0 ) ) )
		{
			DebugMsg("Ddraw SetDisplay Error in Full Screen State\n");
			return false;
		}
		
	}
	else
	{
		//校正窗口位置,大小
		RECT t_Rect;
		GetClientRect( hWnd , &Rect );
		GetWindowRect(hWnd,&t_Rect);
		SetWindowPos( hWnd , NULL , t_Rect.left , t_Rect.top ,m_dwScreenWidth  + ( m_dwScreenWidth - Rect.right ) , m_dwScreenHeight + ( m_dwScreenHeight - Rect.bottom ) , 0 );
		ShowWindow( hWnd, SW_SHOW );
		SetFocus( hWnd );

		if( FAILED( m_pDraw->SetCooperativeLevel( hWnd, DDSCL_NORMAL ) ) )	// 窗口处理
		{
			DebugMsg("Ddraw SetCooperativeLevel Error in Window State\n");
            return false;
		}
	}

	// 创建主表面
	DDSURFACEDESC2 ddsd;
	ZeroMemory( &ddsd, sizeof( ddsd ) );
	ddsd.dwSize = sizeof( ddsd );

	if( m_bFullScreen )
	{
		ddsd.dwFlags           = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
		ddsd.ddsCaps.dwCaps    = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
		ddsd.dwBackBufferCount = 1;
	}
	else
	{
		ddsd.dwFlags        = DDSD_CAPS;
		ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
	}

	if( FAILED( m_pDraw->CreateSurface( &ddsd, &m_pMainBuffer , NULL ) ) )
	{
		DebugMsg("Ddraw CreateSurface Error\n");
		return false;
	}

	// 创建后台表面
	if( m_bFullScreen )
	{
		DDSCAPS2 ddscaps;
		ZeroMemory( &ddscaps, sizeof( ddscaps ) );
		ddscaps.dwCaps = DDSCAPS_BACKBUFFER;

		if( FAILED( m_pMainBuffer->GetAttachedSurface( &ddscaps , &m_pBackBuffer ) ) )
		{
			DebugMsg("m_pMainBuffer GetAttachedSurface Error");
			return false;
		}
		m_pMainBuffer->AddRef();

		DDCAPS ddcaps;
		ZeroMemory( &ddscaps, sizeof( ddscaps ) );
		ddcaps.dwSize = sizeof( ddcaps );

	    m_pDraw->GetCaps( &ddcaps , NULL );

		if( ( ddcaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED ) == 0 )
            DebugMsg( "The display card can not render GDI\n");

		if( FAILED( m_pDraw->CreateClipper( 0 , &m_pClipper, NULL ) ) )
		{
			DebugMsg("m_pDraw->CreateClipper Error\n");
			return false;
		}
		
		m_pClipper->SetHWnd( 0 , hWnd );
		m_pDraw->FlipToGDISurface();
		
	}
	else
	{
		ddsd.dwFlags        = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;    
		ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
		ddsd.dwWidth        = m_dwScreenWidth;
		ddsd.dwHeight       = m_dwScreenHeight;

		if( FAILED( m_pDraw->CreateSurface( &ddsd, &m_pBackBuffer, NULL) ) )
		{
			DebugMsg("m_pDraw->CreateSurface Error\n");
			return false;
		}
		if( FAILED( m_pDraw->CreateClipper( 0 , &m_pClipper, NULL ) ) )
		{
			DebugMsg("m_pDraw->CreateClipper Error\n" );
			return false;
		}
		if( FAILED( m_pClipper->SetHWnd( 0 , hWnd ) ) )
		{
			m_pClipper->Release();
			DebugMsg("m_pClipper->SetHWnd Error" );
			return false;
		}
		if( FAILED( m_pMainBuffer->SetClipper( m_pClipper ) ) )
		{
			m_pClipper->Release();
			DebugMsg("m_pMainBuffer->SetClipper Error\n" );
			return false;
		}
		m_pClipper->Release();
		m_pClipper = NULL;
	
		m_pDraw->FlipToGDISurface();

		//判断当前颜色状态,以便进行像素格式转换
		DEVMODE dmScreenSettings;
		ZeroMemory( &dmScreenSettings, sizeof( dmScreenSettings ) );
		if( EnumDisplaySettings( NULL , ENUM_REGISTRY_SETTINGS , &dmScreenSettings ) != 0 )
		{
			m_dwScreenColor = dmScreenSettings.dmBitsPerPel;
		}
	}
	//创建一内存块,作为自定义缓冲,将所有的图片都复制到这个内存上,在拷贝到
	//ddraw的缓冲表面,这样,可以防止从内存中拷贝图片直接复制到显存上
	m_pEngineBuffer = new DWORD[m_dwScreenWidth*m_dwScreenHeight];
    if(m_pEngineBuffer == NULL)
    {
        DebugMsg("Alloc Custom Buffer error!\n");
        return false;
    }

	m_dwEngineBufferPitch = m_dwScreenWidth*sizeof(DWORD);

	GetClientRect( hWnd , &Rect );
	ClientToScreen( hWnd, ( LPPOINT )&Rect.left );
	ClientToScreen( hWnd, ( LPPOINT )&Rect.right );
	
	m_dwWinX	= Rect.left;
	m_dwWinY	= Rect.top;
	m_dwWinWidth	= (DWORD)(Rect.right - Rect.left);
	m_dwWinHeight	= (DWORD)(Rect.bottom - Rect.top);

	return true;
}

void CDisplay::Destroy(void)
{
	if(m_pEngineBuffer != NULL)
        delete[] m_pEngineBuffer;

	if( m_pDraw != NULL )
	{
		if( m_pBackBuffer != NULL )
		{
			m_pBackBuffer->Release();
			m_pBackBuffer = NULL;
		}
		if( m_pMainBuffer != NULL )
		{
			m_pMainBuffer->Release();
			m_pMainBuffer = NULL;
		}
		if( m_pClipper != NULL )
		{
			m_pClipper->Release();
			m_pClipper = NULL;
		}
		m_pDraw->Release();
		m_pDraw	= NULL;
	}
}

void CDisplay::ClearScreen(DWORD Color)
{
	DDBLTFX ddbltfx;
	ZeroMemory(&ddbltfx,sizeof(ddbltfx));
	ddbltfx.dwSize = sizeof(ddbltfx);
	ddbltfx.dwFillColor = Color;

	m_pMainBuffer->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
}

void CDisplay::ClearBackBuffer(DWORD Color)
{
	NesMemSet(m_pEngineBuffer,0,Color,m_dwScreenWidth*m_dwScreenHeight);
}

void CDisplay::UpdataDisplay(void)
{
	m_dwTimer = timeGetTime();
	static DWORD OldTimer		= m_dwTimer;
	static DWORD FPSCounter	= 1;
	static DWORD TimeCounter	= 1;
	FPSCounter ++;

	RECT Rect;
	GetClientRect( m_hWnd , &Rect );
	ClientToScreen( m_hWnd, ( LPPOINT )&Rect.left );
	ClientToScreen( m_hWnd, ( LPPOINT )&Rect.right );
	
	m_dwWinX	= Rect.left;
	m_dwWinY	= Rect.top;
	m_dwWinWidth	= (DWORD)(Rect.right - Rect.left);
	m_dwWinHeight	= (DWORD)(Rect.bottom - Rect.top);
	
	DDSURFACEDESC2 ddsd;
	ZeroMemory( &ddsd, sizeof( ddsd ) );
	ddsd.dwSize	= sizeof( ddsd );
	m_pBackBuffer->GetSurfaceDesc( &ddsd );
	if( FAILED( m_pBackBuffer->Lock( NULL , &ddsd , DDLOCK_WAIT | DDLOCK_WRITEONLY , 0 ) ) )
	{
		m_pBackBuffer->Restore();
		m_pMainBuffer->Restore();
		if( FAILED( m_pBackBuffer->Lock( NULL , &ddsd , 0 , 0 ) ) )
		{
			DebugMsg( "Lock Back Buffer Error\n" );
			return;
		}
	}
	
	//将自定义缓冲拷贝到ddraw后台缓冲
	//根据屏幕色彩转换像素格式
	DWORD DestOff = 0 , SrcOff = 0,i;
	switch( m_dwScreenColor )
	{
	case 32:
		for( i = 0; i < m_dwScreenHeight; i ++ )
		{
			NesDrawLineNormal(ddsd.lpSurface,DestOff,m_pEngineBuffer,SrcOff,m_dwScreenWidth);
			DestOff	+= ddsd.lPitch;
			SrcOff	+= m_dwEngineBufferPitch;
		}
		break;

	case 24:
		for( i = 0; i < m_dwScreenHeight; i ++ )
		{
			NesDrawLine32To24(ddsd.lpSurface,DestOff,m_pEngineBuffer,SrcOff,m_dwScreenWidth);
			DestOff += ddsd.lPitch;
			SrcOff += m_dwEngineBufferPitch;
		}
		break;

	case 16:
		for( i = 0; i < m_dwScreenHeight; i ++ )
		{
			NesDrawLine32To16( ddsd.lpSurface,DestOff ,m_pEngineBuffer,SrcOff,m_dwScreenWidth);
			DestOff += ddsd.lPitch;
			SrcOff += m_dwEngineBufferPitch;
		}
		break;
	}

	m_pBackBuffer->Unlock(NULL);
	
	//FPS开关
	if( m_dwFPSState )
	{
		if( m_dwTimer - OldTimer > 1000 )
		{
			TimeCounter += m_dwTimer - OldTimer;
			OldTimer = m_dwTimer;
		}
		DWORD FPS = ( FPSCounter * 1000 ) / TimeCounter;
		char Buffer[ 256 ] = "";
		sprintf( Buffer , "FPS= %d" , FPS );
		HDC hDC;
		m_pBackBuffer->GetDC( &hDC );
		SetBkColor( hDC , 0 );
		SetTextColor( hDC , RGB( 0 , 255 , 0 ) );
		TextOut( hDC , 3 , 3 , Buffer , ( int )strlen( Buffer ) );
		m_pBackBuffer->ReleaseDC( hDC );
	}

	if( FAILED( m_pMainBuffer->Blt( &Rect , m_pBackBuffer , NULL , DDBLT_WAIT , NULL ) ) )
			DebugMsg( "Flip Error \n" );
}

⌨️ 快捷键说明

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