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 + -
显示快捷键?