📄 ddapi.cpp
字号:
}
// release DirectDraw surface
m_lpSurface->Release();
m_lpSurface = NULL;
m_lpPalette = NULL;
}
m_bCreated = FALSE;
}
// load a bitmap to an existing surface
// strBitmap: new bitmap file name
// return value: TRUE if succeeded
BOOL CDDSurface::ReLoadBitmap( LPCTSTR strBitmap /*= NULL*/)
{
// store name of file or resource
if( strBitmap != NULL ) strcpy( m_strBitmap, strBitmap );
m_bHasBitmap = TRUE;
// test if the palette pointer has been deleted
if( m_lpPalette != NULL )
{
BOOL bSuccess = FALSE;
for ( int j=0 ; j< MAX_PALETTE ; j++ )
{
if( DD_lppPalettes[j] != NULL &&
m_lpPalette == DD_lppPalettes[j]->GetPalette() )
bSuccess = TRUE;
}
if( bSuccess == FALSE ) m_lpPalette = NULL;
}
// set my palette
// if( m_lpPalette != NULL ) DD_lpDDSFront->SetPalette( m_lpPalette );
// reload
if( ::DDReLoadBitmap(m_lpSurface, m_strBitmap) == NULL )
return DD_initFail(hwndGame, DD_ERROR_ID+67);
// restore palette
DD_lpDDSFront->SetPalette( DD_lpDDPal );
return TRUE;
}
// if surface is lost, run restore
// there maybe a bug, if bitmap was loaded by Auto memory detect,
// and load into video memory, but got surface lost, the bitmap may
// not be reloaded.
// return value : TRUE if it is succeeded
BOOL CDDSurface::Restore( void )
{
HRESULT ddrval;
ddrval = m_lpSurface->Restore();
if( ddrval == DD_OK )
{
// only if has bitmap loaded and is in video memory,
// should reload bitmap from file
if( m_bHasBitmap && m_bInVideo != FALSE )
{
// test if the palette pointer has been deleted
if( m_lpPalette != NULL )
{
BOOL bSuccess = FALSE;
for ( int j=0 ; j< MAX_PALETTE ; j++ )
{
if( DD_lppPalettes[j] != NULL &&
m_lpPalette == DD_lppPalettes[j]->GetPalette() )
bSuccess = TRUE;
}
if( bSuccess == FALSE ) m_lpPalette = NULL;
}
// set my palette
if( m_lpPalette != NULL )
DD_lpDDSFront->SetPalette( m_lpPalette );
// reload
ddrval = ::DDReLoadBitmap(m_lpSurface, m_strBitmap);
if( ddrval != DD_OK )
return FALSE;
// reset palette
DD_lpDDSFront->SetPalette( DD_lpDDPal );
}
return TRUE;
}
return FALSE;
}
// MMX
// blt my surface to front surface
// 贴图直接到显示面上
// ptDest : destination position, top-left
// lpercSrc : source rectangle, full surface if it is NULL
// return value : TRUE if succeeded
BOOL CDDSurface::BltToFront( POINT ptDest, LPRECT lprcSrc )
{
HRESULT ddrval;
while( 1 )
{
ddrval = DD_lpDDSFront->BltFast( ptDest.x, ptDest.y, m_lpSurface, lprcSrc, m_dwDrawFlag );
if( ddrval == DD_OK )
break;
#ifdef _DEBUG
DD_getBltError( "CDDSurface::BltToFront", ddrval );
#endif
if( ddrval == DDERR_SURFACELOST )
if( !::DD_RestoreScreen() )
return FALSE;
if( ddrval != DDERR_WASSTILLDRAWING )
return FALSE;
}
return TRUE;
}
// MMX
// blt my surface to back surface
// 贴图到背景面上
// ptDest : destination position, top-left
// lprcSrc : source rectangle, full surface if it is NULL
// return value : TRUE if succeeded
BOOL CDDSurface::BltToBack( POINT ptDest, LPRECT lprcSrc )
{
HRESULT ddrval;
while( 1 )
{
ddrval = DD_lpDDSBack->BltFast( ptDest.x, ptDest.y, m_lpSurface, lprcSrc, m_dwDrawFlag );
if( ddrval == DD_OK )
break;
#ifdef _DEBUG
DD_getBltError( "CDDSurface::BltToBack", ddrval );
#endif
if( ddrval == DDERR_SURFACELOST )
if( !::DD_RestoreScreen() )
return FALSE;
if( ddrval != DDERR_WASSTILLDRAWING )
return FALSE;
}
return TRUE;
}
// blt given surface to my surface
// if created by Create(), flags must be DDBLTFAST_NOCOLORKEY
// if created by LoadBitmap( .., FALSE ), flags must be DDBLTFAST_NOCOLORKEY
// if created by LoadBitmap( .., [TRUE]), flags must be DDBLTFAST_SRCCOLORKEY
// x,y : Destinaiton position
// lpsrcSurface : source surface
// src : source rectangle, full surface if it is NULL
// flags : blting flag, DDBLTFAST_NOCOLORKEY or DDBLTFAST_SRCCOLORKEY
// return value : TRUE if succeeded
BOOL CDDSurface::BltSurface( int x, int y,
LPDIRECTDRAWSURFACE2 lpsrcSurface, LPRECT src, DWORD dwflags )
{
HRESULT ddrval;
while( 1 )
{
ddrval = m_lpSurface->BltFast( x, y, lpsrcSurface, src, dwflags );
if( ddrval == DD_OK )
break;
#ifdef _DEBUG
DD_getBltError( "CDDSurface::BltSurface", ddrval );
#endif
if( ddrval == DDERR_SURFACELOST )
if( !::DD_RestoreScreen() )
return FALSE;
if( ddrval != DDERR_WASSTILLDRAWING )
return FALSE;
}
return TRUE;
}
// fill black color to the surface
// nColor : color index you want to fill, default is BLACK
// pRect : region to fill, default is the entire surface
// return value : TRUE if succeeded
BOOL CDDSurface::Erase( int nColor/*=0*/, RECT *pRect/*=NULL*/ )
{
DDBLTFX ddbltfx;
HRESULT ddrval;
// Erase the background
ddbltfx.dwSize = sizeof( ddbltfx );
ddbltfx.dwFillColor = nColor;
while( 1 )
{
ddrval = m_lpSurface->Blt( pRect, NULL, NULL, DDBLT_COLORFILL, &ddbltfx );
if( ddrval == DD_OK )
{
break;
}
#ifdef _DEBUG
DD_getBltError( "CDDSurface::Erase", ddrval );
#endif
if( ddrval == DDERR_SURFACELOST )
{
if( !::DD_RestoreScreen() )
return FALSE;
}
if( ddrval != DDERR_WASSTILLDRAWING )
{
return FALSE;
}
}
return TRUE;
}
//////////////////////////////
//////////////////////////////
// class palette
// contructor
CDDPalette::CDDPalette()
{
m_lpPalette = NULL;
m_nType = -1;
}
// destructor
CDDPalette::~CDDPalette()
{
Release();
}
// create palette object from a bitmap
// strBitmap : bitmap file name
// bSet : TRUE if should set palette to
// the primary surface right after creation
BOOL CDDPalette::LoadPalette( LPCTSTR strBitmap , BOOL bSet /*=FALSE*/)
{
strcpy( m_strPalette, strBitmap ); // save source bitmap file name
m_lpPalette = DDLoadPalette(DD_lpDD, strBitmap);
m_nType = DD_PALTYPE_BMP;
if( m_lpPalette )
{
// add to global palette array
BOOL bSuccess = FALSE;
for ( int j=0 ; j< MAX_PALETTE ; j++ )
{
if( DD_lppPalettes[j] == NULL )
{
DD_lppPalettes[j] = this;
DD_nPaletteCounter++;
bSuccess = TRUE;
break;
}
}
if( !bSuccess ) return DD_initFail(hwndGame, DD_ERROR_ID+60);
// set palette to primary if you want
if( bSet )
if( !SetPalette() )
return DD_initFail(hwndGame, DD_ERROR_ID+62);
return TRUE;
}
return DD_initFail(hwndGame, DD_ERROR_ID+61);
}
// create palette object from a customed palette file
// strPal : palette file name
// bSet : TRUE if should set palette to
// the primary surface right after creation
BOOL CDDPalette::LoadPalettePAL( LPCTSTR strPal , BOOL bSet /*=TRUE*/)
{
PALETTEENTRY ape[256];
strcpy( m_strPalette, strPal ); // save source bitmap file name
TY_LoadPaletteFromPAL( strPal, ape, 256 );
// !Warning:
// you must use DDPCAPS_ALLOW256 if you want to use all the 256 palette entries
//|DDPCAPS_ALLOW256
DD_lpDD->CreatePalette(DDPCAPS_8BIT, ape, &m_lpPalette, NULL);
m_nType = DD_PALTYPE_PAL;
if( m_lpPalette )
{
// add to global palette array
BOOL bSuccess = FALSE;
for ( int j=0 ; j< MAX_PALETTE ; j++ )
{
if( DD_lppPalettes[j] == NULL )
{
DD_lppPalettes[j] = this;
DD_nPaletteCounter++;
bSuccess = TRUE;
break;
}
}
if( !bSuccess ) return DD_initFail(hwndGame, DD_ERROR_ID+63);
// set palette to primary if you want
if( bSet )
if( !SetPalette() )
return DD_initFail(hwndGame, DD_ERROR_ID+64);
return TRUE;
}
return DD_initFail(hwndGame, DD_ERROR_ID+65);
}
// return : TRUE if successful
BOOL CDDPalette::ReloadPalette()
{
int nType = m_nType;
Release();
if( nType == DD_PALTYPE_PAL )
return LoadPalettePAL( m_strPalette );
else if( nType == DD_PALTYPE_BMP )
return LoadPalette( m_strPalette );
return FALSE;
}
// set palette to primary surface
// if color depth is higher than 256, this may result an unkown error
// return value : TRUE if succeeded
BOOL CDDPalette::SetPalette( void )
{
HRESULT ddrval;
if ( m_lpPalette )
{
PALETTEENTRY pe[256];
if(m_lpPalette->GetEntries( 0, 0, 256, pe ) != DD_OK)
{ // get source palette entries
OutputDebugString( "CDDPalette SetPalette Error(0): Cannot get entries!\n" );
return FALSE;
}
if(DD_lpDDPal->SetEntries( 0, 0, 256, pe ) != DD_OK)
{ // set to global palette object
OutputDebugString( "CDDPalette SetPalette Error(1): Cannot set entries!\n" );
return FALSE;
}
ddrval = DD_lpDDSFront->SetPalette( DD_lpDDPal );
if( ddrval == DDERR_SURFACELOST )
{
if( DD_RestoreScreen() == FALSE )
{
return FALSE;
}
return TRUE;
}
else if( ddrval == DD_OK )
{
return TRUE;
}
else
{
int nErr = -1;
switch( ddrval )
{
case DDERR_GENERIC :
nErr = 0;
break;
case DDERR_INVALIDOBJECT :
nErr = 1;
break;
case DDERR_INVALIDPARAMS :
nErr = 2;
break;
case DDERR_INVALIDSURFACETYPE :
nErr = 3;
break;
case DDERR_NOEXCLUSIVEMODE :
nErr = 4;
break;
case DDERR_NOPALETTEATTACHED :
nErr = 5;
break;
case DDERR_NOPALETTEHW :
nErr = 6;
break;
case DDERR_NOT8BITCOLOR :
nErr = 7;
break;
case DDERR_SURFACELOST :
nErr = 8;
break;
case DDERR_UNSUPPORTED :
nErr = 9;
break;
case 0x88760091:
// the palette cannot be initialized under high
// color or True color mode
nErr = 10;
break;
}
OutputDebugString( "CDDPalette SetPalette Error(2): Set palette error!\n" );
return DD_initFail(hwndGame, DD_ERROR_ID+30+nErr);
}
}
OutputDebugString( "CDDPalette SetPalette Error(3): No palette pointer at all!\n" );
return FALSE;
}
// release palette object
void CDDPalette::Release( void )
{
if( DD_lpDD == NULL ) return;
m_nType = -1;
if( m_lpPalette )
{
// reset current palette to NULL
if( m_lpPalette == DD_lpDDPal ) DD_lpDDPal = NULL;
// delete palette object from global array
for( int j=0 ; j<MAX_PALETTE; j++)
{
if( DD_lppPalettes[j] == this )
{
DD_lppPalettes[j]=NULL;
DD_nPaletteCounter--;
break;
}
}
m_lpPalette->Release();
m_lpPalette = NULL;
}
}
//////////////////////////////
// local functions
//////////////////////////////
// get remained video memory, for debug version only
void DD_testVideoMemory()
{
DDCAPS capsDRV, capsHEL;
capsDRV.dwSize = sizeof( DDCAPS );
capsHEL.dwSize = sizeof( DDCAPS );
if( DD_lpDD->GetCaps( &capsDRV, &capsHEL ) == DD_OK )
{
char strVideo[128];
wsprintf( strVideo, "DD_testVideoMemory: %d, %d\n", capsDRV.dwVidMemTotal, capsDRV.dwVidMemFree );
//OutputDebugString( strVideo );
}
}
// get blitter error when using BltFast() and Blt(),
// not all the errors are here
// ddrval : error number returned by BltFast() and Blt()
void DD_getBltError( char * strHead, int ddrval )
{
char msg[128];
if( strlen( strHead ) > 65 ) return;
strcpy( msg, strHead );
strcat( msg, ": " );
switch( ddrval )
{
case DDERR_EXCEPTION :
strcat( msg, "Exception" );
break;
case DDERR_GENERIC :
strcat( msg, "Generic" );
break;
case DDERR_INVALIDOBJECT :
strcat( msg, "Invalid Object" );
break;
case DDERR_INVALIDPARAMS :
strcat( msg, "Invalid Params" );
break;
case DDERR_INVALIDRECT :
strcat( msg, "Invalid Rect" );
break;
case DDERR_NOBLTHW :
strcat( msg, "No Blitter HardWare" );
break;
case DDERR_SURFACEBUSY :
strcat( msg, "Surface Busy" );
break;
case DDERR_SURFACELOST :
strcat( msg, "Surface Lost" );
break;
case DDERR_UNSUPPORTED :
strcat( msg, "This Operation is Unsupported" );
break;
default:
strcat( msg, "I don\'t know this" );
}
strcat( msg, " Error!\n" );
// WriteLogFile( "DDApi.log", msg );
OutputDebugString( msg );
}
//////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -