⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddapi.cpp

📁 网页游戏赤壁
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	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 + -