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

📄 asl_screen.cpp

📁 泡泡堂单机版(含ASL游戏引擎源码 泡泡堂单机版(含ASL游戏引擎源码
💻 CPP
字号:
//-----------------------------------------------------------------------------
//
//    ____ Azure Star Game Engine 蓝星游戏引擎 ____
//
//    Copyright (c) 2006, 蓝星工作室
//    All rights reserved.
//
//    文件名称: asl_screen.cpp
//    摘    要: 屏幕类实现
//
//    当前版本: 1.0
//    作    者: 汤  祺
//    创建日期: 2006-7-23
//
//-----------------------------------------------------------------------------

#include "asl_screen.h"

namespace ASL
{

//-----------------------------------------------------------------------------
// 函数名: ASLScreen::~ASLScreen()
// 功  能: 构造函数
// 参  数: [void] - 无
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
ASLScreen::ASLScreen(void) 
: m_lpDD(NULL)
, m_lpSurface(NULL)
, m_hWnd(NULL)
, m_bWait(true)
, m_bFull(true)
, m_bIs565(true)
{
}

//-----------------------------------------------------------------------------
// 函数名: ASLScreen::~ASLScreen()
// 功  能: 析构函数
// 参  数: [void] - 无
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
ASLScreen::~ASLScreen(void) 
{
	ReleaseDD();
}

//-----------------------------------------------------------------------------
// 函数名: ASLScreen::Instance()
// 功  能: 取全局唯一实例
// 参  数: [void] - 无
// 返回值: [ASLScreen&] - 全局唯一实例
//-----------------------------------------------------------------------------
ASLScreen& ASLScreen::Instance(void)
{
	static ASLScreen instance;
	return instance;
}

//-----------------------------------------------------------------------------
// 函数名: ASLScreen::SwitchScreen()
// 功  能: 切换全屏和窗口模式
// 参  数: [void] - 无
// 返回值: [void] - 无
//         失败则抛出ASLDirectDrawException异常
//-----------------------------------------------------------------------------
void ASLScreen::SwitchScreen(void) throw(ASLDirectDrawException)
{
	SetDD(!m_bFull);
}

//-----------------------------------------------------------------------------
// 函数名: ASLScreen::ChangeResolution()
// 功  能: 改变分辨率
// 参  数: [nWidth] - 改变后的宽度
//         [nHeight] - 改变后的高度
// 返回值: [void] - 无
//         失败则抛出ASLDirectDrawException异常
//-----------------------------------------------------------------------------
void ASLScreen::ChangeResolution(int nWidth, int nHeight) throw(ASLDirectDrawException)
{
	CreateBlank(nWidth, nHeight);
	SetDD(m_bFull);
}

//-----------------------------------------------------------------------------
// 函数名: ASLScreen::Init()
// 功  能: 初始化
// 参  数: [hWnd] - 主窗口句柄
//         [nWidth] - 画面宽度
//         [nHeight] - 画面高度
//         [bFull] - 是否全屏显示
//         [bWait] - 是否垂直同步刷新
// 返回值: [void] - 无
//         失败则抛出ASLDirectDrawException异常
//-----------------------------------------------------------------------------
void ASLScreen::Init(HWND hWnd, int nWidth, int nHeight, bool bFull, bool bWait)
	throw(ASLDirectDrawException)
{
	ASSERT(hWnd != NULL && m_lpDD == NULL);

	m_hWnd = hWnd;
	m_bWait = bWait;

	// 建立空白位图
	CreateBlank(nWidth, nHeight);

	// 创建DirectDraw
	HRESULT hr;
	hr = DirectDrawCreateEx(NULL, (void **)&m_lpDD, IID_IDirectDraw7, NULL);
	if (FAILED(hr))
	{
		throw ASLDirectDrawException("创建DirectDraw失败", hr);
	}

	// 设置DirectDraw
	SetDD(bFull);
}

//-----------------------------------------------------------------------------
// 函数名: ASLScreen::Update()
// 功  能: 刷新, 将位图内容显示到屏幕上
// 参  数: [void] - 无
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLScreen::Update(void)
{
	if (m_bWait)
	{
		// 等待垂直刷新信号
		m_lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);
	}
	
	if (m_bFull)	// 全屏模式
	{
		DDSURFACEDESC2 ddsd;
		ddsd.dwSize = sizeof(ddsd);

		// 锁住主表面
		if (m_lpSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) == DD_OK)
		{
			if (m_bIs565)	// 象素格式为565
			{
				BlitToMem565((BYTE*)ddsd.lpSurface, ddsd.lPitch);
			}
			else			// 象素格式为555
			{
				BlitToMem555((BYTE*)ddsd.lpSurface, ddsd.lPitch);
			}
		}
		m_lpSurface->Unlock(NULL);		// 解锁主表面

		if (FAILED(m_lpSurface->IsLost()))
		{
			m_lpSurface->Restore();		// 若主表面丢失则恢复之
		}
	}
	else			// 窗口模式
	{
		BlitToWnd(m_hWnd);
	}
}

//-----------------------------------------------------------------------------
// 函数名: ASLScreen::ReleaseDD()
// 功  能: 释放DirectDraw
// 参  数: [void] - 无
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLScreen::ReleaseDD(void)
{
	SAFE_RELEASE(m_lpSurface);
	
	if (m_lpDD != NULL)
	{
		m_lpDD->SetCooperativeLevel(m_hWnd, DDSCL_NORMAL);
	}
	
	SAFE_RELEASE(m_lpDD);
}

//-----------------------------------------------------------------------------
// 函数名: ASLScreen::SetDD()
// 功  能: 设置DirectDraw
// 参  数: [full] - 是否全屏显示
// 返回值: [void] - 无
//         失败则抛出ASLDirectDrawException异常
//-----------------------------------------------------------------------------
void ASLScreen::SetDD(bool bFull) throw(ASLDirectDrawException)
{
	ASSERT(m_lpDD != NULL);
	
	m_bFull = bFull;
	HRESULT hr;
	SAFE_RELEASE(m_lpSurface);
	
	if (!m_bFull)
	{
		// 设置协作等级为普通
		hr = m_lpDD->SetCooperativeLevel(m_hWnd, DDSCL_NORMAL);
		if (hr != DD_OK)
		{
			throw ASLDirectDrawException("设置视频协作等级失败", hr);
		}

		// 调整窗口
		DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
		RECT rc;
		SetRect(&rc, 0, 0, m_nWidth, m_nHeight);

		AdjustWindowRect(&rc, style, NULL);
		int w = rc.right - rc.left;
		int h = rc.bottom - rc.top;

		SystemParametersInfo(SPI_GETWORKAREA, NULL, &rc, NULL);
		int x = rc.left + (rc.right - rc.left - w) / 2;
		int y = rc.top + (rc.bottom - rc.top - h) / 2;

		SetWindowLong(m_hWnd, GWL_STYLE, style);
		SetWindowPos(m_hWnd, HWND_NOTOPMOST, x, y, w, h, SWP_SHOWWINDOW);
	}
	else
	{
		// 设窗口样式为POPUP窗口
		SetWindowLong(m_hWnd, GWL_STYLE, WS_POPUP);
		
		// 设置协作等级为独占全屏
		hr = m_lpDD->SetCooperativeLevel(m_hWnd, DDSCL_EXCLUSIVE | 
			DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT);
		if (hr != DD_OK)
		{
			throw ASLDirectDrawException("设置视频协作等级失败", hr);
		}

		// 设置显示模式为16位色
		hr = m_lpDD->SetDisplayMode(m_nWidth, m_nHeight, 16, 0, DDSDM_STANDARDVGAMODE);
		if (hr != DD_OK)
		{
			throw ASLDirectDrawException("设置显示模式失败", hr);
		}

		// 创建主表面
		DDSURFACEDESC2 ddsd;
		memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
		ddsd.dwSize			= sizeof(ddsd);
		ddsd.dwFlags		= DDSD_CAPS;
		ddsd.ddsCaps.dwCaps	= DDSCAPS_PRIMARYSURFACE;
		hr = m_lpDD->CreateSurface(&ddsd, &m_lpSurface, NULL);
		if (hr != DD_OK)
		{
			throw ASLDirectDrawException("创建主表面失败", hr);
		}
		
		// 检测像素格式
		CheckPixelFormat();
	}
}

//-----------------------------------------------------------------------------
// 函数名: ASLScreen::CheckPixelFormat()
// 功  能: 检测象素类型是565还是555, 并写入变量m_bIs565中
// 参  数: [void] - 无
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLScreen::CheckPixelFormat(void)
{
	ASSERT(m_lpSurface != NULL);

	DDPIXELFORMAT DDPixelFormat;
	ZeroMemory(&DDPixelFormat, sizeof(DDPixelFormat));

	DDPixelFormat.dwSize = sizeof(DDPixelFormat);
	m_lpSurface->GetPixelFormat(&DDPixelFormat);
	
	m_bIs565 = (WORD)DDPixelFormat.dwGBitMask == 0x07E0;
}

} // namespace ASL

⌨️ 快捷键说明

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