📄 ddutil.cpp
字号:
//-----------------------------------------------------------------------------
// File: ddutil.cpp
//
// Desc: DirectDraw framewark classes. Feel free to use this class as a
// starting point for adding extra functionality.
//
//
// Copyright (c) 1995-2001 Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
//#define STRICT
#include <tchar.h>
#include <windows.h>
#include <windowsx.h>
#include <ddraw.h>
#include <stdio.h>
#include "ddutil.h"
#include "dxutil.h"
//-----------------------------------------------------------------------------
// Name: CDisplay()
// Desc:
//-----------------------------------------------------------------------------
CDisplay::CDisplay()
{
m_pDD = NULL;
m_pddsFrontBuffer = NULL;
m_pddsBackBuffer = NULL;
m_pddsBackBufferLeft = NULL;
}
//-----------------------------------------------------------------------------
// Name: ~CDisplay()
// Desc:
//-----------------------------------------------------------------------------
CDisplay::~CDisplay()
{
DestroyObjects();
}
//-----------------------------------------------------------------------------
// Name: DestroyObjects()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::DestroyObjects()
{
SAFE_RELEASE( m_pddsBackBufferLeft );
SAFE_RELEASE( m_pddsBackBuffer );
SAFE_RELEASE( m_pddsFrontBuffer );
if( m_pDD )
m_pDD->SetCooperativeLevel( m_hWnd, DDSCL_NORMAL );
SAFE_RELEASE( m_pDD );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CreateFullScreenDisplay()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::CreateFullScreenDisplay( HWND hWnd, DWORD dwWidth,
DWORD dwHeight, DWORD dwBPP )
{
HRESULT hr;
// Cleanup anything from a previous call
DestroyObjects();
// DDraw stuff begins here
if( FAILED( hr = DirectDrawCreateEx( NULL, (VOID**)&m_pDD,
IID_IDirectDraw7, NULL ) ) )
return E_FAIL;
// Set cooperative level
hr = m_pDD->SetCooperativeLevel( hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN );
if( FAILED(hr) )
return E_FAIL;
// Set the display mode
if( FAILED( m_pDD->SetDisplayMode( dwWidth, dwHeight, dwBPP, 0, 0 ) ) )
return E_FAIL;
// Create primary surface (with backbuffer attached)
DDSURFACEDESC2 ddsd;
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP |
DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE | DDSCAPS_SYSTEMMEMORY;
ddsd.dwBackBufferCount = 1;
if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer,
NULL ) ) )
return E_FAIL;
// Get a pointer to the back buffer
DDSCAPS2 ddscaps;
ZeroMemory( &ddscaps, sizeof( ddscaps ) );
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
if( FAILED( hr = m_pddsFrontBuffer->GetAttachedSurface( &ddscaps,
&m_pddsBackBuffer ) ) )
return E_FAIL;
m_pddsBackBuffer->AddRef();
m_hWnd = hWnd;
m_bWindowed = FALSE;
UpdateBounds();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CreateWindowedDisplay()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::CreateWindowedDisplay( HWND hWnd, DWORD dwWidth, DWORD dwHeight )
{
HRESULT hr;
// Cleanup anything from a previous call
DestroyObjects();
// DDraw stuff begins here
if( FAILED( hr = DirectDrawCreateEx( NULL, (VOID**)&m_pDD,
IID_IDirectDraw7, NULL ) ) )
return E_FAIL;
// Set cooperative level
hr = m_pDD->SetCooperativeLevel( hWnd, DDSCL_NORMAL );
if( FAILED(hr) )
return E_FAIL;
RECT rcWork;
RECT rc;
DWORD dwStyle;
// If we are still a WS_POPUP window we should convert to a normal app
// window so we look like a windows app.
dwStyle = GetWindowStyle( hWnd );
dwStyle &= ~WS_POPUP;
dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX;
SetWindowLong( hWnd, GWL_STYLE, dwStyle );
// Aet window size
SetRect( &rc, 0, 0, dwWidth, dwHeight );
AdjustWindowRectEx( &rc, GetWindowStyle(hWnd), GetMenu(hWnd) != NULL,
GetWindowExStyle(hWnd) );
SetWindowPos( hWnd, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
SetWindowPos( hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
// Make sure our window does not hang outside of the work area
SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWork, 0 );
GetWindowRect( hWnd, &rc );
if( rc.left < rcWork.left ) rc.left = rcWork.left;
if( rc.top < rcWork.top ) rc.top = rcWork.top;
SetWindowPos( hWnd, NULL, rc.left, rc.top, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
LPDIRECTDRAWCLIPPER pcClipper;
// Create the primary surface
DDSURFACEDESC2 ddsd;
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY;
if( FAILED( m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL ) ) )
return E_FAIL;
// Create the backbuffer surface
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
// ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = dwWidth;
ddsd.dwHeight = dwHeight;
if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsBackBuffer, NULL ) ) )
return E_FAIL;
if( FAILED( hr = m_pDD->CreateClipper( 0, &pcClipper, NULL ) ) )
return E_FAIL;
if( FAILED( hr = pcClipper->SetHWnd( 0, hWnd ) ) )
{
pcClipper->Release();
return E_FAIL;
}
if( FAILED( hr = m_pddsFrontBuffer->SetClipper( pcClipper ) ) )
{
pcClipper->Release();
return E_FAIL;
}
// Done with clipper
pcClipper->Release();
m_hWnd = hWnd;
m_bWindowed = TRUE;
UpdateBounds();
return S_OK;
}
// Create display
// Only for child control: Edit, static.etc. .
HRESULT CDisplay::CreateChildCtrlDisplay( HWND hWnd, DWORD dwWidth, DWORD dwHeight )
{
HRESULT hr;
// Cleanup anything from a previous call
DestroyObjects();
// DDraw stuff begins here
if( FAILED( hr = DirectDrawCreateEx( NULL, (VOID**)&m_pDD,
IID_IDirectDraw7, NULL ) ) )
return E_FAIL;
// Set cooperative level
hr = m_pDD->SetCooperativeLevel( hWnd, DDSCL_NORMAL );
if( FAILED(hr) )
return E_FAIL;
LPDIRECTDRAWCLIPPER pcClipper;
// Create the primary surface
DDSURFACEDESC2 ddsd;
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE| DDSCAPS_SYSTEMMEMORY;
if( FAILED( m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL ) ) )
return E_FAIL;
// Create the backbuffer surface
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = dwWidth;
ddsd.dwHeight = dwHeight;
if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsBackBuffer, NULL ) ) )
return E_FAIL;
if( FAILED( hr = m_pDD->CreateClipper( 0, &pcClipper, NULL ) ) )
return E_FAIL;
if( FAILED( hr = pcClipper->SetHWnd( 0, hWnd ) ) )
{
pcClipper->Release();
return E_FAIL;
}
if( FAILED( hr = m_pddsFrontBuffer->SetClipper( pcClipper ) ) )
{
pcClipper->Release();
return E_FAIL;
}
// Done with clipper
pcClipper->Release();
m_hWnd = hWnd;
m_bWindowed = TRUE;
UpdateBounds();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::CreateSurface( CSurface** ppSurface,
DWORD dwWidth, DWORD dwHeight )
{
if( NULL == m_pDD )
return E_POINTER;
if( NULL == ppSurface )
return E_INVALIDARG;
HRESULT hr;
DDSURFACEDESC2 ddsd;
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = dwWidth;
ddsd.dwHeight = dwHeight;
(*ppSurface) = new CSurface();
if( FAILED( hr = (*ppSurface)->Create( m_pDD, &ddsd ) ) )
{
delete (*ppSurface);
return hr;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CDisplay::CreateSurfaceFromBitmap()
// Desc: Create a DirectDrawSurface from a bitmap resource or bitmap file.
// Use MAKEINTRESOURCE() to pass a constant into strBMP.
//-----------------------------------------------------------------------------
HRESULT CDisplay::CreateSurfaceFromTGA( CSurface** ppSurface,const TCHAR* strTGA)
{
HRESULT hr;
DDSURFACEDESC2 ddsd;
TgaHead head;
long lPriPitch = 0;
if( m_pDD == NULL || strTGA == NULL || ppSurface == NULL )
return E_INVALIDARG;
*ppSurface = NULL;
//Open TGA
FILE* file = NULL;
if(file = _tfopen(strTGA, _T("rb")))
{
fread(&head, sizeof(TgaHead), 1, file);
// Try to load the bitmap as a resource, if that fails, try it as a file
// 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 | DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = head.Width;
ddsd.dwHeight = head.Height;
(*ppSurface) = new CSurface();
if( FAILED( hr = (*ppSurface)->Create( m_pDD, &ddsd ) ) )
{
delete (*ppSurface);
return hr;
}
ZeroMemory( &ddsd, sizeof(ddsd) );
ddsd.dwSize = sizeof(ddsd);
if( !FAILED( hr = (*ppSurface)->GetDDrawSurface()->Lock(NULL,&ddsd,DDLOCK_WAIT|DDLOCK_READONLY,NULL) ) )
{
WORD *pwSur = (WORD *)ddsd.lpSurface;
lPriPitch = ddsd.lPitch;
DWORD dwGMask = ddsd.ddpfPixelFormat.dwGBitMask;
if((head.ImageType == 10) && (head.PixelDepth == 16))
{
BYTE header; //压缩包头
WORD wColor; //颜色
WORD wColor2 = 0; //透明
WORD Count; //压缩包中的像素数目
int nTotal = 0; //已读的像素数目(行)
int nHang = 0; //已读了的行数
pwSur += ((lPriPitch>>1) * (head.Height - 1));
WORD *pwTemp = pwSur;
while(fread(&header,sizeof(BYTE),1, file))
{
if(header & 0x80)
{
Count = (header & 0x7F) + 1;
nTotal += Count;
fread(&wColor,sizeof(WORD),1, file);
if(wColor2 == 0) wColor2 = wColor;
for(int i = 0; i < Count; i++)
{
if(wColor == wColor2)
*pwSur = 0;
else
*pwSur = ((wColor & 0x7c00)<<1) + ((wColor & 0x3e0)<<1) + (wColor & 0x1f);
pwSur++;
}
}
else
{
Count = (header & 0x7F) + 1;
nTotal += Count;
for(int i =0 ; i < Count; i++)
{
fread(&wColor,sizeof(WORD),1,file);
if(wColor2 == 0) wColor2 = wColor;
if(wColor == wColor2)
*pwSur = 0;
else
*pwSur = ((wColor & 0x7c00)<<1) + ((wColor & 0x3e0)<<1) + (wColor & 0x1f);
pwSur++;
}
}
if(nTotal >= head.Width)
{
if(++nHang == head.Height) break;
nTotal = 0;
pwTemp -= head.Width;
pwSur = pwTemp;
}
}
}
else if((head.ImageType == 10) && (head.PixelDepth == 32))
{
BYTE header;
DWORD dwAttribute;
DWORD dwColor;
DWORD dwTemp =0;
WORD Count;
int nHang = 0;
int nTotal =0;
pwSur += ((lPriPitch>>1) * (head.Height - 1));
WORD *pwTemp = pwSur;
float fAlpha;
while(fread(&header,sizeof(BYTE),1, file))
{
if(header & 0x80)
{
Count = (header & 0x7F) + 1;
nTotal += Count;
fread(&dwColor,sizeof(DWORD),1, file);
for(int i = 0; i < Count; i++)
{
//A R G B
dwAttribute = ((dwColor & 0xff000000)>>24) & 0xff;
fAlpha = (float)dwAttribute/255;
if(fAlpha == 0) dwTemp = 0;
else
{
dwTemp = (DWORD)(((dwColor & 0xff0000)>>8)*fAlpha + 0x8800*(1-fAlpha)) & 0xf800;
dwTemp += (DWORD)(((dwColor & 0xff00)>>5)*fAlpha + 0x3e0*(1-fAlpha)) & 0x7e0;
dwTemp += (DWORD)(((dwColor & 0xff)>>3)*fAlpha + 0x18*(1-fAlpha)) & 0x1F;
}
*pwSur = dwTemp;
pwSur++;
}
}
else
{
Count = (header & 0x7F) + 1;
nTotal += Count;
for(int i =0 ; i < Count; i++)
{
fread(&dwColor,sizeof(DWORD),1,file);
dwAttribute = ((dwColor & 0xff000000)>>24) & 0xff;
fAlpha =(float)dwAttribute/255;
if(fAlpha == 0) dwTemp = 0;
else
{
dwTemp = (DWORD)(((dwColor & 0xff0000)>>8)*fAlpha + 0x8800*(1-fAlpha)) & 0xf800;
dwTemp += (DWORD)(((dwColor & 0xff00)>>5)*fAlpha + 0x3e0*(1-fAlpha)) & 0x7e0;
dwTemp += (DWORD)(((dwColor & 0xff)>>3)*fAlpha + 0x18*(1-fAlpha)) & 0x1F;
}
*pwSur = dwTemp;
pwSur++;
}
}
if(nTotal >= head.Width)
{
if(++nHang == head.Height) break;
nTotal = 0;
pwTemp -= head.Width;
pwSur = pwTemp;
}
}
}
else if((head.ImageType == 2) && (head.PixelDepth == 32))
{
DWORD dwAttribute;
DWORD dwColor;
DWORD dwTemp =0;
int nHang = 0;
int nTotal =0;
double fAlpha;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -