📄 ddapi.cpp
字号:
if( pPal->SetEntries( 0, 0, 256, peFadeSave ) != DD_OK )
{
OutputDebugString( "DD_FaceRestore Error: Cannot set entries!\n" );
}
} // DD_FadeRestore()
// Clear the palette pointer to whole black. Usually used before
// DD_FadeInScreen(), to set a palette first and save the origional
// value to "peFadeSave"
// pPal : palette to be cleared
void DD_FadeClear( LPDIRECTDRAWPALETTE pPal )
{
PALETTEENTRY pe[256];
#ifdef _DD_DEBUG
return;
#endif //_DD_DEBUG
if( pPal == NULL ) return;
if( pPal->GetEntries( 0, 0, 256, peFadeSave ) != DD_OK )
{ // save palette
OutputDebugString( "DD_FaceClear Error(0): Cannot get entries!\n" );
}
memset( pe, 0, sizeof( pe ) );
if( pPal->SetEntries( 0, 0, 256, pe ) != DD_OK )
{ // set to Zero
OutputDebugString( "DD_FaceClear Error(1): Cannot set entries!\n" );
}
} // DD_FadeClear()
//////////////////////////////
// blt
//////////////////////////////
// draw from one surface to another
// ptDest : destination position in destination surface
// lprcSrc : source rectangle in source surface, full surface if it is NULL
// dwFlags : DDBLTFAST_NOCOLORKEY or DDBLTFAST_SRCCOLORKEY
// return value : TRUE if succeeded
BOOL DD_BltSurface( POINT ptDest, LPDIRECTDRAWSURFACE2 lpDDSDest, RECT *lprcSrc, LPDIRECTDRAWSURFACE2 lpDDSSrc, DWORD dwFlags )
{
HRESULT ddrval;
while( 1 )
{
ddrval = lpDDSDest->BltFast( ptDest.x, ptDest.y, lpDDSSrc, lprcSrc, dwFlags );
if( ddrval == DD_OK )
break;
#ifdef _DEBUG
DD_getBltError( "DD_BltSurface", ddrval );
#endif
if( ddrval == DDERR_SURFACELOST )
if( !::DD_RestoreScreen() )
return FALSE;
if( ddrval != DDERR_WASSTILLDRAWING )
return FALSE;
}
return TRUE;
}
// get global palette pointer
LPDIRECTDRAWPALETTE DD_GetPalette()
{
return DD_lpDDPal;
}
//////////////////////////////
//////////////////////////////
// for class CDDSurface, standard offscreen plain surface
// contructor
CDDSurface::CDDSurface()
{
m_lpSurface = NULL;
m_lpPalette = NULL;
// the surface is not created yet
m_bCreated = FALSE;
// bitmap attributes
m_bHasBitmap = FALSE;
strcpy( m_strBitmap, "" );
m_szBitmap.cx = m_szBitmap.cy = 0;
// color key
m_dwDrawFlag = 0;
// if in video memory, only used when surface lost
m_bInVideo = FALSE;
}
// destructor
CDDSurface::~CDDSurface()
{
Release();
if( m_lpPalette != NULL )
{
m_lpPalette->Release();
m_lpPalette = NULL;
}
m_bHasBitmap = FALSE;
}
// create surface object
// width, height: size of surface to create
// bColorkey : TRUE if want color key, BLACK
// bInVideo : 1, should load surface in video memory
// 0, should load surface in system memory
// -1, load surface anywhere possible
// return value : TRUE if succeeded
BOOL CDDSurface::Create( int width, int height, BOOL bColorKey/*=FALSE*/, BOOL bInVideo/*=-1*/ )
{
HRESULT ddrval;
DDSURFACEDESC ddsd;
LPDIRECTDRAWSURFACE lpSurface = NULL;
// get remained video memory
#ifdef _DEBUG
if( bInVideo )
DD_testVideoMemory();
#endif
if( m_bCreated == TRUE )
{
OutputDebugString( "CDDSurface Create Warning: surface has been already created\n " );
return FALSE;
}
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
#ifdef _DD_SYSTEMMEMORY
m_bInVideo = FALSE;
ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
#else
m_bInVideo = bInVideo;
if( bInVideo == 0 )
ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
else if( bInVideo == 1 )
ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
#endif // _DDSYSTEMMEMORY
ddsd.dwWidth = width;
ddsd.dwHeight = height;
// create DirectDraw surface
if ((ddrval = DD_lpDD->CreateSurface(&ddsd, &lpSurface, NULL)) != DD_OK)
{
int nErr=-1;
switch( ddrval )
{
case DDERR_INVALIDOBJECT:
nErr = 0;
break;
case DDERR_INVALIDPARAMS:
nErr = 1;
break;
case DDERR_OUTOFVIDEOMEMORY:
nErr = 2;
break;
case DDERR_NODIRECTDRAWHW:
nErr = 3;
break;
case DDERR_NOCOOPERATIVELEVELSET:
nErr = 4;
break;
case DDERR_INVALIDCAPS:
nErr = 5;
break;
case DDERR_INVALIDPIXELFORMAT:
nErr = 6;
break;
case DDERR_NOALPHAHW:
nErr = 7;
break;
case DDERR_NOFLIPHW:
nErr = 8;
break;
case DDERR_NOZBUFFERHW:
nErr = 9;
break;
case DDERR_NOEXCLUSIVEMODE:
nErr = 10;
break;
case DDERR_OUTOFMEMORY:
nErr = 11;
break;
case DDERR_PRIMARYSURFACEALREADYEXISTS:
nErr = 12;
break;
case DDERR_NOEMULATION:
nErr = 13;
break;
case DDERR_INCOMPATIBLEPRIMARY:
nErr = 14;
break;
}
if( nErr == 2 ) // out of video memory is not an Must Quit eror
{
OutputDebugString( "Out of video memory error!\n" );
return FALSE;
}
if( bInVideo == TRUE )
{
OutputDebugString( "In video error!\n" );
return FALSE;
}
OutputDebugString( "CDDSurface Create() Error(5): Surface create error!\n" );
return DD_initFail(hwndGame, DD_ERROR_ID+70+nErr);
}
// query direct draw surface to surface2
ddrval = lpSurface->QueryInterface(IID_IDirectDrawSurface2, (LPVOID *)&m_lpSurface);
if( ddrval != DD_OK )
{
OutputDebugString( "CDDSurface Create() Error(6): Query interface error!\n" );
return DD_initFail( hwndGame, DD_ERROR_ID+68 );
}
lpSurface->Release(); // must release, bug fix
// add to global surfaces array
BOOL bSuccess = FALSE;
for( int i=0; i<MAX_SURFACE; i++ )
{
if( DD_lppSurfaces[i] == NULL )
{
DD_lppSurfaces[i] = this;
DD_nSurfaceCounter++;
bSuccess = TRUE;
break;
}
}
if( !bSuccess )
{
OutputDebugString( "CDDSurface Create() Error(3): Surface list is full!\n" );
return DD_initFail(hwndGame, DD_ERROR_ID+51);
}
// set size to members
m_szBitmap.cx = width, m_szBitmap.cy = height;
// set color key
if( bColorKey )
{
// use black as default
SetColorKeyRGB( RGB(0,0,0) );
//m_dwDrawFlag set by SetColorKeyRGB() just now.
//m_dwDrawFlag = DDBLTFAST_SRCCOLORKEY;
}
else
m_dwDrawFlag = DDBLTFAST_NOCOLORKEY;
m_bCreated = TRUE;
return TRUE;
}
// create surface to store a bitmap
// strBitmap : bitmap filename to load
// bColorKey : TRUE if want color key, BLACK
// bInVideo : 1, should load surface in video memory
// 0, should load surface in system memory
// -1, load surface anywhere
// return value : TRUE if succeeded
BOOL CDDSurface::LoadBitmap( LPCTSTR strBitmap, BOOL bColorKey /*=TRUE*/, BOOL bInVideo/*=-1*/ )
{
if( m_bCreated == TRUE )
{
OutputDebugString( "CDDSurface LoadBitmap Warning: surface has been already created: " );
OutputDebugString( strBitmap );
OutputDebugString( "\n" );
return FALSE;
}
// store file name or resource id
strcpy( m_strBitmap, strBitmap );
m_bHasBitmap = TRUE;
// get remained video memory
#ifdef _DEBUG
if( bInVideo )
DD_testVideoMemory();
#endif
// create a surface, and load bitmap on it
// load palette of itsself
m_lpPalette = ::DDLoadPalette(DD_lpDD, strBitmap );//DD_lpDDPal;
#ifdef _DD_SYSTEMMEMORY
m_bInVideo = FALSE;
#else
m_bInVideo = bInVideo;
#endif // _DD_SYSTEMMEMORY
m_lpSurface = ::DDLoadBitmap(DD_lpDD, strBitmap, 0, 0, bInVideo);
if( m_lpSurface == NULL )
{
OutputDebugString( "CDDSurface Loadbitmap() Error(0): Surface create error!\n" );
return DD_initFail(hwndGame, DD_ERROR_ID+58);
}
// add to global surfaces array
BOOL bSuccess = FALSE;
for( int i=0; i<MAX_SURFACE; i++ )
{
if( DD_lppSurfaces[i] == NULL )
{
DD_lppSurfaces[i] = this;
DD_nSurfaceCounter++;
bSuccess = TRUE;
break;
}
}
if( !bSuccess )
{
OutputDebugString( "CDDSurface Loadbitmap() Error(1): Surface list is full!\n" );
return DD_initFail(hwndGame, DD_ERROR_ID+56);
}
// set surface size to members
HRESULT ddrval;
DDSURFACEDESC ddsd;
ddsd.dwSize = sizeof( ddsd );
ddrval = m_lpSurface->GetSurfaceDesc( &ddsd );
if( ddrval != DD_OK )
{
OutputDebugString( "CDDSurface Loadbitmap() Error(2): Get Surface desc error!\n" );
return DD_initFail(hwndGame, DD_ERROR_ID+59);
}
m_szBitmap.cx = ddsd.dwWidth, m_szBitmap.cy = ddsd.dwHeight;
// set color key
if( bColorKey )
{
// use color on top-left corner of the surface as color key
SetColorKeyRGB( RGB(0,0,0) );
//m_dwDrawFlag set by SetColorKeyRGB() just now.
//m_dwDrawFlag = DDBLTFAST_SRCCOLORKEY;
}
else
m_dwDrawFlag = DDBLTFAST_NOCOLORKEY;
m_bCreated = TRUE;
return TRUE;
}
//////////////////////////////
// color key
//////////////////////////////
// actually, you need not use these two functions to set color key,
// if you want color key, by default, BLACK is the color key
// they all can run correctly on 256 color, exclusive mode.
// in unexclusive mode, surface created by Create(),
// SetColorKeyPAL() and SetColorKeyRGB() are not correct.
// in high color mode, surface created by Create(),
// SetColorKeyPAL() and SetColorKeyRGB() are not correct.
// if surface created by LoadBitmap(), they are all correct.
// only SetColorKeyDEF() can run correctly in any condition.
// set colorkey by default
// color on top left corner of the surface to be color key
// must be used after Create() or LoadBitmap()
// if used before, no effects
// return : TRUE if successful
BOOL CDDSurface::SetColorKeyDEF()
{
// use color on top-left corner of the surface as color key
HRESULT ddrval;
if( !m_lpSurface )
{
OutputDebugString( "CDDSurface Error(38): Set color key before create surface!\n" );
return FALSE;
}
// get color from top-left corner of the surface
DWORD dw;
DDSURFACEDESC ddsd;
ddsd.dwSize = sizeof(ddsd);
while ((ddrval = m_lpSurface->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
;
if (ddrval == DD_OK)
{
dw = *(DWORD *)ddsd.lpSurface; // get DWORD
dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount)-1; // mask it to bpp
m_lpSurface->Unlock(NULL);
}
// set as color key
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue = dw;
ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
while( 1 )
{
ddrval = m_lpSurface->SetColorKey(DDCKEY_SRCBLT, &ddck);
if( ddrval == DD_OK )
break;
if( ddrval == DDERR_SURFACELOST )
if( !::DD_RestoreScreen() )
return DD_initFail(hwndGame, DD_ERROR_ID+52);
if( ddrval != DDERR_WASSTILLDRAWING )
return DD_initFail(hwndGame, DD_ERROR_ID+53);
}
m_dwDrawFlag = DDBLTFAST_SRCCOLORKEY;
return TRUE;
}
// set colorkey by given RGB value
// must be used after Create() or LoadBitmap()
// if used before, no effects
// nColor : color key value
// return : TRUE if successful
BOOL CDDSurface::SetColorKeyRGB( DWORD dwColor )
{
HRESULT ddrval;
if( !m_lpSurface )
{
OutputDebugString( "CDDSurface Error(39): Set color key before create surface!\n" );
return FALSE;
}
while( 1 )
{
ddrval = ::DDSetColorKey(m_lpSurface, dwColor);
if( ddrval == DD_OK )
break;
if( ddrval == DDERR_SURFACELOST )
if( !::DD_RestoreScreen() )
return DD_initFail(hwndGame, DD_ERROR_ID+54);
if( ddrval != DDERR_WASSTILLDRAWING )
return DD_initFail(hwndGame, DD_ERROR_ID+55);
}
m_dwDrawFlag = DDBLTFAST_SRCCOLORKEY;
return TRUE;
}
// set colorkey by given palette entry
// must be used after Create() or LoadBitmap()
// if used before, no effects
// if in high/true color mode, this functions is obsolete
// nColor : color key value
// return : TRUE if successful
BOOL CDDSurface::SetColorKeyPAL( BYTE nColor )
{
HRESULT ddrval;
if( !m_lpSurface )
{
OutputDebugString( "CDDSurface Error(40): Set color key before create surface!\n" );
return FALSE;
}
/*
// There is a bug here:
// a surface may not have palette of its own if created by Create()
// function.
if( !m_lpPalette )
{
OutputDebugString( "CDDSurface Error(41): Set color key before load palette!\n" );
OutputDebugString( "This may usually occured when set program with high/true color!\n" );
return FALSE;
}
*/
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue = nColor;
ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
while( 1 )
{
ddrval = m_lpSurface->SetColorKey(DDCKEY_SRCBLT, &ddck);
if( ddrval == DD_OK )
break;
if( ddrval == DDERR_SURFACELOST )
if( !::DD_RestoreScreen() )
return DD_initFail(hwndGame, DD_ERROR_ID+66);
if( ddrval != DDERR_WASSTILLDRAWING )
return DD_initFail(hwndGame, DD_ERROR_ID+57);
}
m_dwDrawFlag = DDBLTFAST_SRCCOLORKEY;
return TRUE;
}
//////////////////////////////
//////////////////////////////
// release surface object
void CDDSurface::Release()
{
if( DD_lpDD == NULL ) return;
if( m_lpSurface != NULL )
{
// delete surface object from global array
for( int i=0 ; i<MAX_SURFACE; i++)
{
if( DD_lppSurfaces[i] == this )
{
DD_lppSurfaces[i]=NULL;
DD_nSurfaceCounter--;
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -