📄 asl_screen.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 + -