dxsurface.cpp
来自「网络泡泡被.net管理」· C++ 代码 · 共 1,815 行 · 第 1/4 页
CPP
1,815 行
// DxSurface.cpp: implementation of the CDxSurface class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "gsSurface.h"
#include "GSLib_Internal.h"
#include "gif89a.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDxSurface::CDxSurface()
{
m_pEngine = NULL;
m_pdds = NULL;
m_isDismiss = true;
m_isUseVideoMemory = false;
m_dxsf = D3DX_SF_UNKNOWN;
CGsFunc::DxInitSurfaceDesc(m_ddsd);
m_dwColorCount = 0;
m_nRShiftL = 8; m_nRShiftR = 0;
m_nGShiftL = 8; m_nGShiftR = 0;
m_nBShiftL = 8; m_nBShiftR = 0;
m_nAShiftL = 8; m_nAShiftR = 0;
m_guid_buf = NULL;
m_guid_size = 0;
}
VOID CDxSurface::SetGsEngine(CGsEngine* pEngine)
{
m_pEngine = pEngine;
if(m_pEngine && !m_pEngine->m_isDismiss)
m_isDismiss = false;
else
m_isDismiss = true;
}
CDxSurface::CDxSurface( CGsEngine* pEngine )
{
m_pEngine = pEngine;
m_pdds = NULL;
if(m_pEngine && !m_pEngine->m_isDismiss)
m_isDismiss = false;
else
m_isDismiss = true;
m_isUseVideoMemory = false;
m_dxsf = D3DX_SF_UNKNOWN;
m_dwColorCount = 0;
m_nRShiftL = 8; m_nRShiftR = 0;
m_nGShiftL = 8; m_nGShiftR = 0;
m_nBShiftL = 8; m_nBShiftR = 0;
m_nAShiftL = 8; m_nAShiftR = 0;
m_guid_buf = NULL;
m_guid_size = 0;
CGsFunc::DxInitSurfaceDesc(m_ddsd);
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
CDxSurface::~CDxSurface()
{
SAFE_RELEASE( m_pdds );
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDxSurface::Create( LPDIRECTDRAWSURFACE7 pdds )
{
SAFE_RELEASE(m_pdds);
m_pdds = pdds;
if( m_pdds )
{
m_pdds->AddRef();
// Get the DDSURFACEDESC structure for this surface
}
return OnCreate();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDxSurface::Create( DDSURFACEDESC2* pddsd )
{
HRESULT hr;
if(m_pEngine==NULL)
return E_FAIL;
SAFE_RELEASE(m_pdds);
// Create the DDraw surface
if( FAILED( hr = m_pEngine->m_pDD->CreateSurface( pddsd, &m_pdds, NULL ) ) )
return hr;
return OnCreate();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
VOID CDxSurface::Cleanup()
{
SAFE_RELEASE( m_pdds );
SAFE_DELETE_ARRAY(m_guid_buf);
m_guid_size = 0;
CGsFunc::DxInitSurfaceDesc( m_ddsd );
}
//-----------------------------------------------------------------------------
// Name: Blt()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDxSurface::Blt( int x, int y,
CDxSurface* pSrcSurface,
GRECT* pSrcRect,
BOOL bUseColorKey )
{
if( NULL == pSrcSurface )
return E_INVALIDARG;
int itemp;
if(!pSrcRect)
{
GRECT rc( pSrcSurface->GetRect() );
pSrcRect = &rc;
}
if(x>(int)m_ddsd.dwWidth || y>(int)m_ddsd.dwHeight)
return S_OK;
if(x<0)
{
pSrcRect->left -= x;
x = 0;
}
if(y<0)
{
pSrcRect->top -= y;
y = 0;
}
itemp = pSrcRect->right - pSrcRect->left - m_ddsd.dwWidth + x;
if(itemp>0)
{
pSrcRect->right -= itemp;
}
itemp=pSrcRect->bottom - pSrcRect->top - m_ddsd.dwHeight + y;
if(itemp>0)
{
pSrcRect->bottom -= itemp;
}
GRECT rcDest(x, y, pSrcRect->right - pSrcRect->left + x, pSrcRect->bottom - pSrcRect->top + y);
if(bUseColorKey)
return m_pdds->Blt( &rcDest, pSrcSurface->GetDDrawSurface(), pSrcRect, DDBLT_WAIT|DDBLT_KEYSRC, NULL );
else
return m_pdds->Blt( &rcDest, pSrcSurface->GetDDrawSurface(), pSrcRect, DDBLT_WAIT, NULL );
}
//-----------------------------------------------------------------------------
// Name: Blt()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDxSurface::Blt( GRECT* pDestRect,
CDxSurface* pSrcSurface,
GRECT* pSrcRect,
BOOL bUseColorKey )
{
if( NULL == pSrcSurface )
return E_INVALIDARG;
if(!pSrcRect)
{
GRECT rc( pSrcSurface->GetRect() );
pSrcRect = &rc;
}
if(!pDestRect)
{
GRECT rc1( GetRect() );
pDestRect = &rc1;
}
float fw = (float)pSrcRect->width()/(float)pDestRect->width();
float fh = (float)pSrcRect->height()/(float)pDestRect->height();
if(pDestRect->left<0)
{
pSrcRect->left -= pDestRect->left*fw;
pDestRect->left = 0;
}
if(pDestRect->top<0)
{
pSrcRect->top -= pDestRect->top*fw;
pDestRect->top = 0;
}
if(pDestRect->right>m_ddsd.dwWidth)
{
pSrcRect->right -= (pDestRect->right-m_ddsd.dwWidth)*fw;
pDestRect->right = m_ddsd.dwWidth;
}
if(pDestRect->bottom>m_ddsd.dwHeight)
{
pSrcRect->bottom -= (pDestRect->bottom-m_ddsd.dwHeight)*fw;
pDestRect->bottom = m_ddsd.dwHeight;
}
if(bUseColorKey)
return m_pdds->Blt( pDestRect, pSrcSurface->GetDDrawSurface(), pSrcRect, DDBLT_WAIT|DDBLT_KEYSRC, NULL );
else
return m_pdds->Blt( pDestRect, pSrcSurface->GetDDrawSurface(), pSrcRect, DDBLT_WAIT, NULL );
}
//-----------------------------------------------------------------------------
// Name: CDxSurface::CopySurface()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDxSurface::CopySurface(int x, int y, CDxSurface *pSrcSurface, GRECT *pSrcRect)
{
if( NULL == pSrcSurface )
return E_INVALIDARG;
if(m_dxsf!=pSrcSurface->m_dxsf)
return Blt(x, y, pSrcSurface, pSrcRect);
int itemp;
if(!pSrcRect)
{
GRECT rc( pSrcSurface->GetRect() );
pSrcRect = &rc;
}
if(x>(int)m_ddsd.dwWidth || y>(int)m_ddsd.dwHeight)
return S_OK;
if(x<0)
{
pSrcRect->left -= x;
x = 0;
}
if(y<0)
{
pSrcRect->top -= y;
y = 0;
}
int w = pSrcRect->right - pSrcRect->left;
int h = pSrcRect->bottom - pSrcRect->top;
itemp = w - m_ddsd.dwWidth + x;
if(itemp>0)
{
w -= itemp;
}
itemp=h - m_ddsd.dwHeight + y;
if(itemp>0)
{
h -= itemp;
}
if(w<=0 || h<=0)
return S_OK;
HRESULT hr;
DDSURFACEDESC2 ddsd;
ddsd.dwSize = sizeof(ddsd);
while( hr = pSrcSurface->m_pdds->Lock( NULL, &ddsd, 0, 0 ) == DDERR_WASSTILLDRAWING );
if(FAILED(hr))
return hr;
int sx,dx;
if(32 == ddsd.ddpfPixelFormat.dwRGBBitCount)
{
w <<=2;
sx = pSrcRect->left<<2;
dx = x<<2;
}
else
{
w <<=1;
sx = pSrcRect->left<<1;
dx = x<<1;
}
int lPitchSrc = ddsd.lPitch;
BYTE* pBytesSrc = (BYTE*)ddsd.lpSurface + sx + lPitchSrc*pSrcRect->top;
ddsd.dwSize = sizeof(ddsd);
while( hr = m_pdds->Lock( NULL, &ddsd, 0, 0 ) == DDERR_WASSTILLDRAWING );
if(FAILED(hr))
return hr;
int lPitchDest = ddsd.lPitch;
BYTE* pBytesDest = (BYTE*)ddsd.lpSurface + dx + lPitchDest*y;
int c = w>>3;
int l = c<<3;
while(h>0)
{
if(g_pGsApp->IsMMXSupport())
{
if(c>0)
{
_asm
{
push ecx
mov ecx,c
mov esi,pBytesSrc
mov edi,pBytesDest
loop1:
movq mm0,[esi]
movq [edi],mm0
add esi,8
add edi,8
dec ecx
jnz loop1
pop ecx
emms
}
}
memcpy(pBytesDest+l, pBytesSrc+l, w-l);
}
else
memcpy(pBytesDest, pBytesSrc, w);
h--;
pBytesSrc += lPitchSrc;
pBytesDest += lPitchDest;
}
m_pdds->Unlock(0);
pSrcSurface->m_pdds->Unlock(0);
return hr;
}
//-----------------------------------------------------------------------------
// Name: CDxSurface::DrawBitmap()
// Desc: Draws a bitmap over an entire DirectDrawSurface, stretching the
// bitmap if nessasary
//-----------------------------------------------------------------------------
HRESULT CDxSurface::DrawBitmap( HBITMAP hBMP,
DWORD dwBMPOriginX, DWORD dwBMPOriginY,
DWORD dwBMPWidth, DWORD dwBMPHeight )
{
HDC hDCImage;
HDC hDC;
BITMAP bmp;
DDSURFACEDESC2 ddsd;
HRESULT hr;
if( hBMP == NULL || m_pdds == NULL )
return E_INVALIDARG;
// Make sure this surface is restored.
if( FAILED( hr = m_pdds->Restore() ) )
return hr;
// Get the surface.description
ddsd.dwSize = sizeof(ddsd);
m_pdds->GetSurfaceDesc( &ddsd );
if( ddsd.ddpfPixelFormat.dwFlags == DDPF_FOURCC )
return E_NOTIMPL;
// Select bitmap into a memoryDC so we can use it.
hDCImage = CreateCompatibleDC( NULL );
if( NULL == hDCImage )
return E_FAIL;
SelectObject( hDCImage, hBMP );
// Get size of the bitmap
GetObject( hBMP, sizeof(bmp), &bmp );
// Use the passed size, unless zero
dwBMPWidth = ( dwBMPWidth == 0 ) ? bmp.bmWidth : dwBMPWidth;
dwBMPHeight = ( dwBMPHeight == 0 ) ? bmp.bmHeight : dwBMPHeight;
// Stretch the bitmap to cover this surface
if( FAILED( hr = m_pdds->GetDC( &hDC ) ) )
return hr;
StretchBlt( hDC, 0, 0,
ddsd.dwWidth, ddsd.dwHeight,
hDCImage, dwBMPOriginX, dwBMPOriginY,
dwBMPWidth, dwBMPHeight, SRCCOPY );
if( FAILED( hr = m_pdds->ReleaseDC( hDC ) ) )
return hr;
DeleteDC( hDCImage );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CDxSurface::DrawText()
// Desc: Draws a text string on a DirectDraw surface using hFont or the default
// GDI font if hFont is NULL.
//-----------------------------------------------------------------------------
HRESULT CDxSurface::DrawTextDirect( HFONT hFont, const TCHAR* strText,
DWORD dwOriginX, DWORD dwOriginY,
COLORREF crForeground, COLORREF crBackground )
{
HDC hDC = NULL;
HRESULT hr;
if( m_pdds == NULL || strText == NULL )
return E_INVALIDARG;
// Make sure this surface is restored.
if( FAILED( hr = m_pdds->Restore() ) )
return hr;
if( FAILED( hr = m_pdds->GetDC( &hDC ) ) )
return hr;
if(crBackground==RGB(0,0,0))
SetBkMode(hDC, TRANSPARENT);
else
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?