www.pudn.com > GameEngine_src.rar > CSurface.cpp


#include "CSurface.h" 
#include "CEasyDraw.h" 
#include "BaseUtil.h" 
#include "normal.h" 
#include  
 
 
 
//------------------------------------------------CSurface函数-------------------------------------------------------- 
int CSurface::g_TextOutX; 
int CSurface::g_TextOutY; 
HDC CSurface::g_hdc; 
HFONT CSurface::g_hFont; 
RECT CSurface::g_TextRect; 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
CSurface::CSurface() 
{ 
	Init(); 
} 
 
 
CSurface::~CSurface() 
{ 
	FreeSurface(); 
} 
 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CSurface::OnCreateSurface( bool isSysMemory, bool isColorKey ) 
{ 
	if ( m_lpDDSurface == NULL ) 
		return false; 
	 
	GetWH( &m_iWidth, &m_iHeight ); 
	if ( isColorKey ) 
	{ 
		m_ColorKeyType = DDBLTFAST_SRCCOLORKEY; 
	} 
 
	if ( !isSysMemory ) 
		return CreateCopySurface(); 
	else 
		return true; 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CSurface::Init() 
{ 
	m_ColorKeyType = DDBLTFAST_NOCOLORKEY; 
	m_lpDDSurface = NULL; 
	m_lpDDSurfaceCopy = NULL; 
	m_iWidth = 0; 
	m_iHeight = 0; 
	return true; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::FreeSurface() 
{ 
	SafeRelease( m_lpDDSurface ); 
	SafeRelease( m_lpDDSurfaceCopy ); 
	m_ColorKeyType = DDBLTFAST_NOCOLORKEY; 
	m_iWidth = 0; 
	m_iHeight = 0; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CSurface::CreateImageSurface( char *szFileName, bool isSysMemory, bool isColorKey, DWORD ColorKey ) 
{ 
	if ( szFileName != NULL ) 
	{ 
		int len = strlen(szFileName); 
		char szNameEx[3]; 
		strcpy( szNameEx, &szFileName[len-3] ); 
		 
		if ( strcmp( szNameEx, "BMP" ) == 0 || strcmp( szNameEx, "bmp" ) == 0 ) 
		{ 
			return CreateBmpSurface( szFileName, isSysMemory, isColorKey, ColorKey ); 
		} 
		/*else if ( strcmp( szNameEx, "JPG" ) == 0 || strcmp( szNameEx, "jpg" ) == 0 ) 
		{ 
			return CreateJpegSurface( szFileName, isSysMemory, isColorKey, ColorKey ); 
		}*/ 
		else if ( strcmp( szNameEx, "ECP" ) == 0 || strcmp( szNameEx, "ecp" ) == 0 ) 
		{ 
			return CreateEcpSurface( szFileName, isSysMemory ); 
		} 
		else  
			return false; 
	} 
	 
	return false; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CSurface::CreateBmpSurface( char *szFileName, bool isSysMemory, bool isColorKey, DWORD ColorKey ) 
{ 
	FreeSurface(); 
	LPDIRECTDRAW7 lpdd = GetEasyDrawPointer()->GetLPDD();  
 
	HRESULT hr = CreateSurfaceOfBmp( lpdd, &m_lpDDSurface, szFileName, isSysMemory, isColorKey, ColorKey ); 
	 
	if ( hr == DDERR_OUTOFVIDEOMEMORY ) 
		isSysMemory = true; 
 
	return OnCreateSurface( isSysMemory, isColorKey ); 
} 
/* 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
inline bool CSurface::CreateJpegSurface( char *szFileName, bool isSysMemory, bool isColorKey, DWORD ColorKey ) 
{ 
	FreeSurface(); 
 
	HRESULT hr = LoadJpegHelp(	GetEasyDrawPointer()->GetLPDD(), 
								&m_lpDDSurface, 
								szFileName, 
								m_lpDDSurface, 
								isSysMemory, 
								isColorKey, 
								ColorKey, 
								GetEasyDrawPointer()->Is565() ); 
 
	if ( hr == DDERR_OUTOFVIDEOMEMORY ) 
		isSysMemory = true; 
	 
	if ( m_lpDDSurface == NULL ) 
		return false; 
 
	GetWH( &m_iWidth, &m_iHeight ); 
	if ( isColorKey ) 
	{ 
		m_ColorKeyType = DDBLTFAST_SRCCOLORKEY; 
	} 
 
	if ( !isSysMemory ) 
		return CreateCopySurface(); 
	else 
		return true; 
}*/ 
 
////////////////////////////////////////////////////////////////////// 
//从ECP文件中载入,并创建一个页面 
////////////////////////////////////////////////////////////////////// 
inline bool CSurface::CreateEcpSurface( char *filename, bool isSysMemory ) 
{ 
	FreeSurface(); 
 
	FILE *fp; 
	fp = fopen(filename, "rb"); 
	if ( fp == NULL ) 
		return false; 
 
	bool b = CreateEcpSurfaceHelp( fp, 0, NULL, isSysMemory ); 
	fclose(fp); 
	return true; 
} 
 
 
////////////////////////////////////////////////////////////////////// 
//从ECP文件中载入,并创建一个页面 
////////////////////////////////////////////////////////////////////// 
bool CSurface::CreateEcpSurfaceHelp( FILE *fp, int offset, POINT *pPoint, bool isSysMemory ) 
{ 
	/******************************************************** 
	*为了保护游戏资源,此函数内容省略 
	********************************************************/ 
	return true; 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CSurface::CreateBmpSurfaceFromMemory( BYTE *pData, bool isSysMemory ) 
{ 
	if ( pData == NULL )	return false; 
	BYTE *pOldData = pData; 
	FreeSurface(); 
 
	m_lpDDSurface = LoadBmpFromMemory( pData, GetEasyDrawPointer()->GetLPDD(), NULL, NULL, isSysMemory ); 
	if ( m_lpDDSurface == 0 ) 
		return false; 
 
	return OnCreateSurface( isSysMemory, false ); 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CSurface::CreateEcpSurfaceFromMemory( BYTE *pData, bool isSysMemory, POINT *point ) 
{ 
	/******************************************************** 
	*为了保护游戏资源,此函数内容省略 
	********************************************************/ 
	return true; 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CSurface::CreateNullSurface( int iw, int ih, bool isSysMemory, bool isColorKey, DWORD ColorKey ) 
{ 
	FreeSurface(); 
 
	HRESULT hr = CreateSurfaceHelp(	GetEasyDrawPointer()->GetLPDD(),  
									&m_lpDDSurface, iw, ih, 
									isSysMemory, isColorKey, ColorKey ); 
 
	if ( hr == DDERR_OUTOFVIDEOMEMORY ) 
	{ 
		isSysMemory = true; 
	} 
 
	return OnCreateSurface( isSysMemory, isColorKey ); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CSurface::CreateCopySurface() 
{ 
	if ( m_lpDDSurface == NULL ) 
		return false; 
 
	SafeRelease( m_lpDDSurfaceCopy ); 
	CreateSurfaceHelp( GetEasyDrawPointer()->GetLPDD(), &m_lpDDSurfaceCopy, m_iWidth, m_iHeight, true, false, 0 ); 
	if ( m_lpDDSurfaceCopy == NULL ) 
		return false; 
 
	m_lpDDSurfaceCopy->BltFast( 0, 0, m_lpDDSurface, NULL, DDBLTFAST_NOCOLORKEY ); 
 
	return true; 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::DrawSurface( int x, int y, RECT *pRect ) 
{ 
	LPDIRECTDRAWSURFACE7 lpDDBack = GetEasyDrawPointer()->GetBackSurface(); 
 
	if ( m_lpDDSurface != NULL ) 
	{ 
		lpDDBack->BltFast( x, y, m_lpDDSurface, pRect, m_ColorKeyType ); 
	} 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::DrawAutoClip( int x, int y ) 
{ 
	int iSW = GetEasyDrawPointer()->GetDeviceWidth(); 
	int iSH = GetEasyDrawPointer()->GetDeviceHeight(); 
 
	RECT rc; 
	rc.left = 0; 
	rc.top	= 0; 
	rc.right= m_iWidth; 
	rc.bottom=m_iHeight; 
 
	if ( x + m_iWidth > iSW )  
	{ 
		rc.right -= x + m_iWidth - iSW; 
	} 
	else if ( x < 0 )  
	{ 
		rc.left -= x; 
		x = 0; 
	} 
 
	if ( y + m_iHeight > iSH )  
	{ 
		rc.bottom -= y + m_iHeight - iSH; 
	} 
	else if ( y < 0 )  
	{ 
		rc.top -= y; 
		y = 0; 
	} 
  
	LPDIRECTDRAWSURFACE7 lpDDBack = GetEasyDrawPointer()->GetBackSurface(); 
	lpDDBack->BltFast( x, y, m_lpDDSurface, &rc, m_ColorKeyType ); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::DrawAlphaShadow( int x, int y ) 
{ 
	//if ( m_lpDDSurface == NULL ) 
		//return; 
	RECT rc_src;		//temp页面上要锁定的矩形区域 
	RECT rc;			//temp页面上要blt的区域 
	RECT rc_dest;		//目标页面上的矩形区域 
 
	rc_src.left = 0; 
	rc_src.top  = 0; 
	rc_src.right= m_iWidth; 
	rc_src.bottom=m_iHeight; 
 
	rc = rc_src; 
 
	int iSW = GetEasyDrawPointer()->GetDeviceWidth(); 
	int iSH = GetEasyDrawPointer()->GetDeviceHeight(); 
 
	if ( x + m_iWidth > iSW )  
		rc.right -= x + m_iWidth - iSW; 
 
	if ( x < 0 )  
	{ 
		rc.left -= x; 
		x = 0; 
	} 
 
	if ( y + m_iHeight > iSH )  
		rc.bottom -= y + m_iHeight - iSH; 
 
	if ( y < 0 )  
	{ 
		rc.top -= y; 
		y = 0; 
	} 
 
	rc_dest.left = x; 
	rc_dest.top	= y; 
	rc_dest.right= x + rc.right - rc.left; 
	rc_dest.bottom=y + rc.bottom- rc.top; 
 
	LPDIRECTDRAWSURFACE7 back, temp; 
	back = GetEasyDrawPointer()->GetBackSurface(); 
	temp = GetEasyDrawPointer()->GetTempSurface(); 
 
	//把后台页面的矩形拷贝到特效页面上 
	temp->BltFast( rc.left, rc.top, back, &rc_dest, DDBLTFAST_NOCOLORKEY ); 
 
	//锁定特效页面 
	DDSURFACEDESC2 ddsd; 
	WORD *buf_temp, *buf_surf; 
	int pitch_temp; 
 
	ddsd.dwSize = sizeof(ddsd); 
	if ( temp->Lock( &rc_src, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL ) != DD_OK )		return; 
	buf_temp = (WORD *)ddsd.lpSurface; 
	pitch_temp = ddsd.lPitch >> 1; 
 
	//锁定内存页面 
	ddsd.dwSize = sizeof(ddsd); 
	if ( m_lpDDSurface->Lock( NULL, &ddsd, DDLOCK_READONLY, NULL ) != DD_OK ) 
	{ 
		temp->Unlock(0); 
		return; 
	} 
	 
	buf_surf = (WORD *)ddsd.lpSurface; 
 
	WORD *buf = buf_temp; 
	__int64 _0x7befx4 = 0x7bef7bef7bef7bef; 
	WORD data = 0; 
 
	while ( 1 ) 
	{ 
		data = (*buf_surf); 
		buf_surf++; 
		if ( data == 0xffff ) 
		{ 
			data = (*buf_surf); 
			buf_surf++; 
			buf += data; 
		} 
		else if ( data == 0xfffe ) 
		{ 
			data = (*buf_surf); 
			buf_surf++; 
			int len = data; 
			len = len - len % 4; 
			int k = 0; 
			 
			__asm { 
				mov eax, k; 
				mov edx, buf; 
_for_k_begin: 
				cmp eax, len; 
				jge _for_k_end; 
				 
				movq mm0, [edx]; 
				psrlw mm0, 1; 
				pand mm0, _0x7befx4; 
				movq [edx], mm0; 
 
				add edx, 8; 
				add eax, 4; 
				jmp _for_k_begin; 
 
_for_k_end: 
				mov k, eax; 
				mov buf, edx; 
			} 
 
			for ( ; k < data; ++k ) 
			{ 
				(*buf) = ( (*buf) >> 1 ) & 0x7bef;		//565 mask 
				++buf; 
			} 
		} 
		else if ( data == 0xfffd ) 
		{ 
			buf_temp += pitch_temp; 
			buf = buf_temp; 
		} 
		else 
		{ 
			goto _exit; 
		} 
	} 
_exit: 
	__asm emms; 
	m_lpDDSurface->Unlock(0); 
	temp->Unlock(0); 
	back->BltFast( x, y, temp, &rc, DDBLTFAST_NOCOLORKEY );  
} 
 
 
////////////////////////////////////////////////////////////////////// 
//画带精灵轮廓的图片 
////////////////////////////////////////////////////////////////////// 
void CSurface::DrawContour( int x, int y ) 
{ 
	if ( m_lpDDSurface == NULL ) 
		return; 
	RECT rc_src;		//temp页面上要锁定的矩形区域 
	rc_src.left = 0; 
	rc_src.top  = 0; 
	rc_src.right= m_iWidth; 
	rc_src.bottom=m_iHeight; 
 
	int iSW = GetEasyDrawPointer()->GetDeviceWidth(); 
	int iSH = GetEasyDrawPointer()->GetDeviceHeight(); 
 
	if ( x + m_iWidth > iSW )  
		rc_src.right -= x + m_iWidth - iSW; 
	else if ( x < 0 )  
	{ 
		rc_src.left -= x; 
		x = 0; 
	} 
 
	if ( y + m_iHeight > iSH )  
		rc_src.bottom -= y + m_iHeight - iSH; 
	else if ( y < 0 )  
	{ 
		rc_src.top -= y; 
		y = 0; 
	} 
 
	LPDIRECTDRAWSURFACE7 back, temp; 
	back = GetEasyDrawPointer()->GetBackSurface(); 
	temp = GetEasyDrawPointer()->GetTempSurface(); 
 
	WORD colorkey = (WORD)GetColorKey(); 
 
	//把页面全部拷贝到temp上 
	LPDIRECTDRAWSURFACE7 surf = m_lpDDSurfaceCopy; 
	if ( surf == NULL )	surf = m_lpDDSurface; 
 
	temp->BltFast( 0, 0, surf, 0, DDBLTFAST_NOCOLORKEY ); 
	 
	//锁定temp,绘制精灵轮廓 
	RECT rc = {0, 0, m_iWidth, m_iHeight}; 
	DDSURFACEDESC2 ddsd; 
	ddsd.dwSize = sizeof(ddsd); 
	if ( temp->Lock( &rc, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL ) != DD_OK )		return; 
	WORD * buf_temp = (WORD *)ddsd.lpSurface; 
	int pitch_temp = ddsd.lPitch >> 1; 
 
	//绘制精灵轮廓 
	int i, j; 
	for ( i = 0; i < m_iHeight; ++i ) 
	{ 
		for ( j = 0; j < m_iWidth; ++j ) 
		{ 
			if ( buf_temp[i * pitch_temp + j] != colorkey ) 
			{ 
				buf_temp[i * pitch_temp + j] = 0xffff;		// colorkey; 
				break; 
			} 
		} 
	} 
	for ( i = 0; i < m_iHeight; ++i ) 
	{ 
		for ( j = m_iWidth-1; j >= 0; --j ) 
		{ 
			if ( buf_temp[i * pitch_temp + j] != colorkey ) 
			{ 
				buf_temp[i * pitch_temp + j] = 0xffff; 
				break; 
			} 
		} 
	} 
	for ( i = 0; i < m_iWidth; ++i ) 
	{ 
		for ( j = 0; j < m_iHeight; ++j ) 
		{ 
			if ( buf_temp[j * pitch_temp + i] != colorkey ) 
			{ 
				buf_temp[j * pitch_temp + i] = 0xffff; 
				break; 
			} 
		} 
	} 
	for ( i = 0; i < m_iWidth; ++i ) 
	{ 
		for ( j = m_iHeight-1; j >= 0; --j ) 
		{ 
			if ( buf_temp[j * pitch_temp + i] != colorkey ) 
			{ 
				buf_temp[j * pitch_temp + i] = 0xffff; 
				break; 
			} 
		} 
	} 
	temp->Unlock(0); 
	SetColorKeyHelp( temp, colorkey ); 
	back->BltFast( x, y, temp, &rc_src, DDBLTFAST_SRCCOLORKEY );   
} 
 
////////////////////////////////////////////////////////////////////// 
//MMX半透明混合,注意页面宽度整除4,无关健色 
////////////////////////////////////////////////////////////////////// 
void CSurface::DrawAlphaMMX( int x, int y ) 
{ 
	if ( m_lpDDSurface == NULL ) 
		return; 
	RECT rc_src;		//temp页面上要锁定的矩形区域 
	RECT rc;			//temp页面上要blt的区域 
	RECT rc_dest;		//目标页面上的矩形区域 
 
	rc_src.left = 0; 
	rc_src.top  = 0; 
	rc_src.right= m_iWidth; 
	rc_src.bottom=m_iHeight; 
 
	rc = rc_src; 
 
	int iSW = GetEasyDrawPointer()->GetDeviceWidth(); 
	int iSH = GetEasyDrawPointer()->GetDeviceHeight(); 
 
	if ( x + m_iWidth > iSW )  
		rc.right -= x + m_iWidth - iSW; 
 
	if ( x < 0 )  
	{ 
		rc.left -= x; 
		x = 0; 
	} 
 
	if ( y + m_iHeight > iSH )  
		rc.bottom -= y + m_iHeight - iSH; 
 
	if ( y < 0 )  
	{ 
		rc.top -= y; 
		y = 0; 
	} 
 
	rc_dest.left = x; 
	rc_dest.top	= y; 
	rc_dest.right= x + rc.right - rc.left; 
	rc_dest.bottom=y + rc.bottom- rc.top; 
 
	LPDIRECTDRAWSURFACE7 back, temp; 
	back = GetEasyDrawPointer()->GetBackSurface(); 
	temp = GetEasyDrawPointer()->GetTempSurface(); 
 
	//把后台页面的矩形拷贝到特效页面上 
	temp->BltFast( rc.left, rc.top, back, &rc_dest, DDBLTFAST_NOCOLORKEY ); 
 
	//锁定特效页面 
	DDSURFACEDESC2 ddsd; 
 
	ddsd.dwSize = sizeof(ddsd); 
	if ( temp->Lock( &rc_src, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL ) != DD_OK )		return; 
	WORD *buf_temp = (WORD *)ddsd.lpSurface; 
	int pitch_temp = ddsd.lPitch; 
 
	//锁定内存页面 
	ddsd.dwSize = sizeof(ddsd); 
	if ( m_lpDDSurface->Lock( NULL, &ddsd, DDLOCK_READONLY, NULL ) != DD_OK ) 
	{ 
		temp->Unlock(0); 
		return; 
	} 
	 
	WORD *buf_surf = (WORD *)ddsd.lpSurface; 
	ddsd.dwWidth *= 2; 
	int pitch_surf = ddsd.lPitch - ddsd.dwWidth; 
	pitch_temp -= ddsd.dwWidth; 
 
	__int64 _0x7befx4 = 0x7bef7bef7bef7bef; 
	__asm 
	{	 
		mov edx, buf_temp;				//edx 目标页面指针 
		mov ecx, buf_surf;				//ecx 源页面指针 
		xor ebx, ebx; 
 
_for_h_begin: 
		cmp ebx, ddsd.dwHeight; 
		jnb _for_h_end; 
 
		xor eax, eax; 
 
_for_w_begin: 
		cmp eax, ddsd.dwWidth; 
		jnb _for_w_end; 
 
		movq mm0, [edx]; 
		movq mm1, [ecx]; 
		psrlw mm0, 1; 
		psrlw mm1, 1; 
		pand mm0, _0x7befx4; 
		pand mm1, _0x7befx4; 
		paddusw mm0, mm1;			//注意要用paddusw无符号饱和压缩加法 
		movq [edx], mm0; 
 
		add edx, 8; 
		add ecx, 8; 
		add eax, 8; 
		jmp _for_w_begin; 
 
_for_w_end: 
		inc ebx; 
		add edx, pitch_temp; 
		add ecx, pitch_surf; 
		jmp _for_h_begin; 
_for_h_end: 
		emms; 
	} 
 
	m_lpDDSurface->Unlock(0); 
	temp->Unlock(0); 
	back->BltFast( x, y, temp, &rc, DDBLTFAST_NOCOLORKEY );  
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::BltTo( int destX, int destY, CSurface *pDestSurf, RECT *rcSrc ) 
{ 
	if ( pDestSurf->m_lpDDSurface != NULL && m_lpDDSurface != NULL ) 
	{ 
		pDestSurf->m_lpDDSurface->BltFast( destX, destY, m_lpDDSurface, rcSrc, m_ColorKeyType ); 
 
		if ( pDestSurf->m_lpDDSurfaceCopy != NULL ) 
			pDestSurf->m_lpDDSurfaceCopy->BltFast( destX, destY, m_lpDDSurface, rcSrc, m_ColorKeyType ); 
	} 
} 
 
////////////////////////////////////////////////////////////////////// 
//判断一个带关键色的页面上的(x,y)点是否非关健色 
////////////////////////////////////////////////////////////////////// 
bool CSurface::IsSurfaceSelected( int x, int y ) 
{ 
	WORD colorkey = (WORD)GetColorKey(); 
	bool re = false; 
 
	LPDIRECTDRAWSURFACE7 surf = m_lpDDSurfaceCopy; 
	if ( surf == NULL )	surf = m_lpDDSurface; 
	DDSURFACEDESC2 ddsd; 
	ddsd.dwSize = sizeof(ddsd); 
	if ( surf->Lock( 0, &ddsd, DDLOCK_READONLY, NULL ) != DD_OK )		return false; 
 
	WORD * buf = (WORD *)ddsd.lpSurface; 
	int pitch = ddsd.lPitch >> 1; 
 
	if ( buf[y * pitch + x] != colorkey ) 
		re = true; 
	surf->Unlock(0); 
	return re; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CSurface::Restore() 
{ 
	if ( m_lpDDSurface == NULL ) 
		return false; 
 
	HRESULT hr; 
	hr = m_lpDDSurface->IsLost(); 
	if ( hr != DD_OK ) 
	{ 
		hr = m_lpDDSurface->Restore(); 
		if ( hr != DD_OK ) 
			return false; 
	} 
 
	if ( m_lpDDSurfaceCopy != NULL ) 
		m_lpDDSurface->BltFast( 0, 0, m_lpDDSurfaceCopy, NULL, DDBLTFAST_NOCOLORKEY ); 
 
	return true; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
DWORD CSurface::GetColorKey() 
{ 
	DDCOLORKEY ddck; 
	ddck.dwColorSpaceHighValue = 0x0000; 
 
	//if ( m_lpDDSurface != NULL ) 
	m_lpDDSurface->GetColorKey( DDCKEY_SRCBLT, &ddck ); 
 
	return ddck.dwColorSpaceHighValue & 0xffff; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::SetSurfaceColorKey( DWORD ColorKey ) 
{ 
	if ( !m_lpDDSurface == NULL ) 
	{ 
		ColorKey = GetEasyDrawPointer()->ChangeColorKey( ColorKey ); 
		SetColorKeyHelp( m_lpDDSurface, ColorKey ); 
		m_ColorKeyType = DDBLTFAST_SRCCOLORKEY; 
	} 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::AutoSetColorKey() 
{ 
	WORD *buf = BeginDraw( 0, 0, 0, 0 ); 
	WORD colorkey; 
	if ( buf != NULL ) 
	{ 
		colorkey = buf[0]; 
		EndDraw(); 
		SetSurfaceColorKey( colorkey ); 
	} 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::AutoClip() 
{ 
	if ( m_ColorKeyType == DDBLTFAST_NOCOLORKEY ) 
		return; 
	WORD colorkey = (WORD)GetColorKey(); 
	LPDIRECTDRAWSURFACE7 temp = GetEasyDrawPointer()->GetTempSurface(); 
	int width, height, pitch; 
	WORD *buf = BeginDraw( &width, &height, &pitch, 0 ); 
	RECT rc = {width, height, 0, 0 }; 
	int i,j; 
	//找出最靠左边的点 
	for ( i = 0; i < height; ++i ) 
	{ 
		for ( j = 0; j < width; ++j ) 
		{ 
			if ( buf[i*pitch + j] != colorkey ) 
			{ 
				if ( j > rc.right ) 
					rc.right = j; 
			} 
		} 
	} 
 
	for ( i = 0; i < height; ++i ) 
	{ 
		for ( j = width-1; j >= 0; --j ) 
		{ 
			if ( buf[i*pitch + j] != colorkey ) 
			{ 
				if ( j < rc.left ) 
					rc.left = j; 
			} 
		} 
	} 
 
	for ( i = 0; i < width; ++i ) 
	{ 
		for ( j = 0;  j < height; ++j ) 
		{ 
			if ( buf[j*pitch + i] != colorkey ) 
			{ 
				if ( j > rc.bottom ) 
					rc.bottom = j; 
			} 
		} 
	} 
 
	for ( i = 0; i < width; ++i ) 
	{ 
		for ( j = height-1; j >= 0; --j ) 
		{ 
			if ( buf[j*pitch + i] != colorkey ) 
			{ 
				if ( j < rc.top ) 
					rc.top = j; 
			} 
		} 
	} 
 
	EndDraw(); 
	if ( rc.right != 0 && rc.bottom != 0 ) 
	{ 
		rc.right += 1; 
		rc.bottom += 1; 
 
		temp->BltFast( rc.left, rc.top, m_lpDDSurface, &rc, DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT ); 
		CreateNullSurface( rc.right-rc.left, rc.bottom-rc.top, false, true, colorkey ); 
		m_lpDDSurface->BltFast( 0, 0, temp, &rc, DDBLTFAST_NOCOLORKEY ); 
		if ( m_lpDDSurfaceCopy != NULL ) 
			m_lpDDSurfaceCopy->BltFast( 0, 0, temp, &rc, DDBLTFAST_NOCOLORKEY ); 
	} 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CSurface::GetWH( int *pWidth, int *pHeight ) 
{ 
	DDSURFACEDESC2 ddsd; 
	ddsd.dwSize = sizeof( DDSURFACEDESC2 ); 
 
	if ( m_lpDDSurface != NULL ) 
	{ 
		if ( m_lpDDSurface->GetSurfaceDesc( &ddsd ) != DD_OK ) 
			return false; 
	} 
	else 
		return false; 
	 
	if ( pWidth != NULL ) 
		*pWidth = ddsd.dwWidth; 
 
	if ( pHeight != NULL ) 
		*pHeight= ddsd.dwHeight; 
	return true; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
int CSurface::GetWidth() 
{ 
	return m_iWidth; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
int CSurface::GetHeight( ) 
{ 
	return m_iHeight; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::AlphaBlendSurface( CSurface *pSrcSurf, RECT *rcSrc, RECT *rcDest, DWORD alpha ) 
{ 
	if ( pSrcSurf != NULL && pSrcSurf->m_lpDDSurface != NULL ) 
	{ 
		LPDIRECTDRAWSURFACE7 surfDest = m_lpDDSurfaceCopy; 
		if ( surfDest == NULL ) 
			surfDest = m_lpDDSurface; 
		 
		LPDIRECTDRAWSURFACE7 surfSrc = pSrcSurf->m_lpDDSurfaceCopy; 
		if ( surfSrc == NULL ) 
			surfSrc = pSrcSurf->m_lpDDSurface; 
		 
		if ( surfDest != NULL && surfSrc != NULL ) 
		{ 
			AlphaSurfaceRect16( surfSrc,  
				surfDest,  
				rcSrc, rcDest,  
				GetEasyDrawPointer()->Is565(), 
				false, 0, alpha 
				); 
		} 
	} 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::WriteText( const char *szText, int TextLen, int x, int y, DWORD Color ) 
{ 
	if ( m_lpDDSurfaceCopy != NULL ) 
	{ 
		DrawTextOnSurface( m_lpDDSurfaceCopy, szText, TextLen, x, y, Color );  
		Restore(); 
	} 
	else if ( m_lpDDSurface != NULL ) 
	{ 
		DrawTextOnSurface( m_lpDDSurface, szText, TextLen, x, y, Color );  
	} 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::WriteTextCenter( const char *szText, DWORD Color ) 
{ 
	HDC  hDC; 
	if ( m_lpDDSurface && m_lpDDSurface->GetDC( &hDC ) == DD_OK ) 
	{ 
		//SetBkColor( hDCBack, NULL ); 
		SetBkMode( hDC, TRANSPARENT );		//背景透明 
		SetTextColor( hDC, Color ); 
		SetTextAlign( hDC, TA_CENTER ); 
		HFONT hFont = (HFONT)GetStockObject(SYSTEM_FIXED_FONT); 
		SelectObject(g_hdc, hFont); 
		int y = m_iHeight/2 - CEasyDraw::g_CharHeight/2; 
		TextOut( hDC, m_iWidth/2, y, szText, strlen(szText) ); 
		DeleteObject( hFont ); 
		m_lpDDSurface->ReleaseDC( hDC ); 
	} 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CSurface::BeginDrawText( int x, int y ) 
{ 
	if ( m_lpDDSurface->GetDC( &g_hdc ) != DD_OK ) 
		return false; 
 
	g_hFont = (HFONT)GetStockObject(SYSTEM_FIXED_FONT); 
	if ( g_hFont == NULL ) 
		return false; 
	SelectObject(g_hdc, g_hFont); 
 
	g_TextOutX = x; 
	g_TextOutY = y; 
	g_TextRect.left = x; 
	g_TextRect.top	= y; 
	return true; 
} 
 
////////////////////////////////////////////////////////////////////// 
//绘制多行文本 
////////////////////////////////////////////////////////////////////// 
void CSurface::DrawText( const char *sz, DWORD color, bool isNextLine ) 
{ 
 
	int len_all = strlen(sz); 
 
	if ( isNextLine ) 
		g_TextOutY += CEasyDraw::g_CharHeight; 
 
	SetBkMode( g_hdc, TRANSPARENT );		//背景透明 
	SetTextColor( g_hdc, color ); 
 
	int last = len_all; 
	while ( len_all > 0 ) 
	{ 
		int len = last; 
		if ( (g_TextOutX + last * CEasyDraw::g_CharWidth) - m_iWidth > 0 ) 
			len = (m_iWidth - g_TextOutX) / CEasyDraw::g_CharWidth; 
			 
		TextOut( g_hdc, g_TextOutX, g_TextOutY, sz, len ); 
		last = len_all - len; 
		len_all -= len; 
		sz += len; 
		g_TextOutY += CEasyDraw::g_CharHeight; 
	} 
 
	g_TextRect.right = m_iWidth; 
	g_TextRect.bottom= g_TextOutY;  
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::EndDrawText() 
{ 
	DeleteObject( g_hFont ); 
	m_lpDDSurface->ReleaseDC( g_hdc ); 
	g_hdc = NULL; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::ClearSurface( DWORD color, RECT *pRect ) 
{ 
	if ( m_lpDDSurface != NULL ) 
		ClearSurfaceHelp( m_lpDDSurface, pRect, color ); 
	if ( m_lpDDSurfaceCopy != NULL ) 
		ClearSurfaceHelp( m_lpDDSurfaceCopy, pRect, color ); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::ClearCopySurface( DWORD color, RECT *pRect ) 
{ 
	if ( m_lpDDSurfaceCopy != NULL ) 
		ClearSurfaceHelp( m_lpDDSurfaceCopy, pRect, color ); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CSurface::CopySurfaceToBmp( char *szBmpName, RECT *pRect ) 
{ 
	if ( m_lpDDSurface != NULL ) 
	{ 
		return CopySurfaceToBmp16( m_lpDDSurface, szBmpName, pRect, GetEasyDrawPointer()->Is565() ); 
	} 
	else 
		return false; 
} 
 
////////////////////////////////////////////////////////////////////// 
//把一个页面保存到ECP文件中 
////////////////////////////////////////////////////////////////////// 
bool CSurface::SaveSurfaceToEcp( char *filename, RECT *pRect ) 
{ 
	FILE *fp = fopen( filename, "wb+" ); 
	if ( fp == NULL ) 
	{ 
		return false; 
	} 
	 
	bool b = (SaveSurfaceToEcpHelp( fp, 0, NULL, pRect ) != 0 ); 
 
	fclose(fp); 
	return b; 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
int CSurface::SaveSurfaceToEcpHelp( FILE *fp, int offset, const POINT *pPoint, RECT *pRect ) 
{ 
 
	WORD colorkey = 0; 
	if ( m_ColorKeyType == DDBLTFAST_SRCCOLORKEY ) 
		colorkey = (WORD)GetColorKey(); 
 
	int width, height, pitch; 
	WORD *buf16 = BeginDraw( &width, &height, &pitch, pRect ); 
	if ( buf16 == NULL ) 
	{ 
		return 0; 
	} 
	 
	fseek( fp, offset, SEEK_SET ); 
 
	ECPFILEHEADER efh; 
	efh.ecpFileType		= ECP; 
	efh.ecpFileSize		= 0; 
	efh.ecpHeight		= m_iHeight; 
	efh.ecpWidth		= m_iWidth; 
	efh.ecpColorKeyType = m_ColorKeyType; 
	efh.ecpColorKey     = colorkey; 
	efh.ecpBaseOffset.x  = 0; 
	efh.ecpBaseOffset.y  = 0; 
	efh.ecpIsCompress   = FALSE; 
 
	//压缩过的阴影图 
	if ( width != m_iWidth && height != m_iHeight) 
	{ 
		efh.ecpFileType = ECP_SHADOW; 
		efh.ecpWidth = ( ( m_iWidth << 16 ) & 0xffff0000 ) | ( width & 0xffff ); 
		efh.ecpHeight= ( ( m_iHeight<< 16 ) & 0xffff0000 ) | ( height & 0xffff ); 
	} 
 
	if ( pPoint != NULL ) 
	{ 
		efh.ecpBaseOffset.x  = pPoint->x; 
		efh.ecpBaseOffset.y  = pPoint->y; 
	} 
 
	if ( m_ColorKeyType == DDBLTFAST_SRCCOLORKEY ) 
	{ 
		efh.ecpIsCompress = TRUE; 
		if ( GetEasyDrawPointer()->Is565() == false ) 
			efh.ecpColorKey = CHANGE_555_TO_565( colorkey );			//存储的是565关健色 
	} 
			 
	fwrite( &efh, sizeof(efh), 1, fp );									//写入文件头 
	offset = sizeof(efh); 
	if ( efh.ecpIsCompress ) 
	{ 
		bool is_check_colorkey = false; 
		int  offset_colorkey = 0; 
		int  offset_pixel = 0; 
		int  num_colorkey = 0; 
		 
		 
		//检测第一个像素是否是关键色 
		WORD pixel = buf16[0]; 
		if ( pixel == colorkey ) 
		{ 
			is_check_colorkey = true; 
		} 
		 
		COMPRESS_DATA cd; 
		WORD *pixel_buf = new WORD[256]; 
		if ( pixel_buf == NULL ) 
		{ 
			return 0; 
		} 
 
		for ( int i = 0; i < height; ++i ) 
		{ 
			for ( int j = 0; j < width; ++j ) 
			{ 
				pixel = buf16[i * pitch + j]; 
				 
				if ( is_check_colorkey ) 
				{ 
					if ( pixel == colorkey ) 
					{ 
						++offset_colorkey; 
						if ( offset_colorkey == 255 ) 
						{		 
							cd.byte1 = COLORKEY_COUNT; 
							cd.byte2 = (BYTE)offset_colorkey; 
							fwrite( &cd, 2, 1, fp ); 
							offset_colorkey = 0; 
						} 
					} 
					else 
					{ 
						if ( offset_colorkey != 0 ) 
						{ 
							cd.byte1 = COLORKEY_COUNT; 
							cd.byte2 = (BYTE)offset_colorkey; 
							fwrite( &cd, 2, 1, fp ); 
							offset_colorkey = 0; 
						} 
						 
						is_check_colorkey = false; 
						pixel_buf[offset_pixel++] = pixel; 
 
					} 
				} 
				else 
				{ 
					if ( pixel == colorkey ) 
					{ 
						if ( offset_pixel != 0 ) 
						{ 
							cd.byte1 = PIXEL_COUNT; 
							cd.byte2 = offset_pixel; 
							fwrite( &cd, 2, 1, fp ); 
							fwrite( pixel_buf, offset_pixel * 2, 1, fp ); 
							offset_pixel = 0; 
						} 
						 
						is_check_colorkey = true; 
						offset_colorkey = 1; 
					} 
					else 
					{ 
						pixel_buf[offset_pixel++] = pixel; 
						if ( offset_pixel == 255 ) 
						{ 
							cd.byte1 = PIXEL_COUNT; 
							cd.byte2 = offset_pixel; 
							fwrite( &cd, 2, 1, fp ); 
							fwrite( pixel_buf, offset_pixel * 2, 1, fp ); 
							offset_pixel = 0; 
						} 
					} 
				} 
			}//for each pixel in a line 
			 
			if ( is_check_colorkey && offset_colorkey != 0 ) 
			{ 
				cd.byte1 = COLORKEY_COUNT; 
				cd.byte2 = (BYTE)offset_colorkey; 
				fwrite( &cd, 2, 1, fp ); 
				offset_colorkey = 0;		 
			} 
			else if ( !is_check_colorkey && offset_pixel != 0 ) 
			{ 
				cd.byte1 = PIXEL_COUNT; 
				cd.byte2 = offset_pixel; 
				fwrite( &cd, 2, 1, fp ); 
				fwrite( pixel_buf, offset_pixel * 2, 1, fp ); 
				offset_pixel = 0; 
			} 
			 
			cd.byte1 = LINE_END; 
			cd.byte2 = 0x00; 
			fwrite( &cd, 2, 1, fp );		//写入行结束符 
		}// for every line 
		 
		cd.byte1 = ECP_FILE_END; 
		cd.byte2 = ECP_FILE_END; 
		fwrite( &cd, 2, 1, fp );			//写入文件结束符 
		delete [] pixel_buf; 
 
 
	}			//非压缩数据 
	else 
	{ 
		WORD *pline = buf16; 
		for ( int i = 0; i < height; ++i ) 
		{ 
			fwrite( pline, width * 2, 1, fp ); 
			pline += pitch; 
		} 
	} 
 
	EndDraw(); 
 
	fpos_t pos = 0; 
	fgetpos(fp, &pos ); 
		 
	return (int)pos; 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
WORD * CSurface::BeginDraw( int *iWidthOut, int *iHeightOut, int *iPitchOut, RECT *pRectIn ) 
{ 
	if ( m_lpDDSurface == NULL ) 
		return NULL; 
 
	LPDIRECTDRAWSURFACE7 surf; 
	surf = m_lpDDSurface; 
	if ( m_lpDDSurfaceCopy != NULL ) 
		surf = m_lpDDSurfaceCopy; 
	 
	DDSURFACEDESC2 ddsd; 
	ddsd.dwSize = sizeof(ddsd); 
	if ( surf->Lock( pRectIn, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL ) != DD_OK ) 
		return NULL; 
 
	if ( iWidthOut != NULL ) 
	{ 
		if ( pRectIn == NULL ) 
			*iWidthOut = ddsd.dwWidth; 
		else 
			*iWidthOut = pRectIn->right - pRectIn->left; 
	} 
 
	if ( iHeightOut != NULL ) 
	{ 
		if ( pRectIn == NULL ) 
			*iHeightOut= ddsd.dwHeight; 
		else 
			*iHeightOut = pRectIn->bottom - pRectIn->top; 
	} 
 
	if ( iPitchOut != NULL ) 
		*iPitchOut = ddsd.lPitch >> 1; 
 
	return (WORD*)ddsd.lpSurface; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::EndDraw() 
{ 
	if ( m_lpDDSurfaceCopy != NULL ) 
	{ 
		m_lpDDSurfaceCopy->Unlock( 0 ); 
		Restore(); 
	} 
	else 
		m_lpDDSurface->Unlock( 0 ); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CSurface::CopySurface( CSurface *psurf ) 
{ 
	CreateNullSurface( psurf->GetWidth(), psurf->GetHeight(),  
					false, psurf->IsColorKey(), psurf->GetColorKey() ); 
	m_lpDDSurface->BltFast( 0, 0, psurf->m_lpDDSurface, 0, DDBLTFAST_NOCOLORKEY ); 
	CreateCopySurface(); 
} 
 
const WORD MASK_R_565 = 0xf800; 
const WORD MASK_G_565 = 0x07e0; 
const WORD MASK_B_565 = 0x001f; 
 
const WORD MASK_R_555 = 0x7c00; 
const WORD MASK_G_555 = 0x03e0; 
const WORD MASK_B_555 = 0x001f; 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CSurface::MagicSurface( enum SURF_MAGIC magic, WORD colorkey, WORD MaskColor, RECT *pRect ) 
{ 
	if ( m_lpDDSurface == NULL ) 
		return false; 
 
	colorkey = (WORD)GetEasyDrawPointer()->ChangeColorKey( colorkey ); 
	bool is565 = GetEasyDrawPointer()->Is565(); 
 
	int iw, ih, ipitch; 
	WORD *surf = NULL; 
 
	WORD colorkey2; 
	if ( m_ColorKeyType == DDBLTFAST_SRCCOLORKEY ) 
		colorkey2 = (WORD)GetColorKey(); 
 
	 
	if ( magic == HALF_ALPHA )					//半透明页面 
	{ 
		if ( m_ColorKeyType == DDBLTFAST_NOCOLORKEY ) 
		{ 
			return false; 
		} 
		 
		surf = BeginDraw( &iw, &ih, &ipitch, pRect ); 
		if ( surf == NULL ) 
			return false; 
		 
		WORD mask = 0x7bef; 
		if ( !is565 ) mask = 0x3def; 
		int i, j; 
		colorkey2 = ( ( colorkey2 >> 1 ) & mask ); 
 
		for ( i = 0; i < ih; i++ ) 
		{ 
			for ( j = 0; j < iw; j++ ) 
				surf[i * ipitch + j] = ( ( surf[i * ipitch + j] >> 1 ) & mask ); 
		} 
		 
		EndDraw(); 
		SetSurfaceColorKey( colorkey2 ); 
	} 
	else if ( magic == ALPHA_SHADOW ) 
	{ 
		surf = BeginDraw( &iw, &ih, &ipitch, 0 ); 
		if ( surf == NULL )		return false; 
		 
		WORD *buf_temp = new WORD[iw * ih]; 
		int index = 0; 
 
		if ( buf_temp == NULL )	 
		{ 
			return false; 
			EndDraw(); 
		} 
 
		bool is_check_color_key = false; 
		int num_shadow = 0; 
		int num_color_key = 0; 
 
		if ( (*surf) == colorkey2 )		is_check_color_key = true; 
 
		//压缩阴影 
		for ( int i = 0; i < ih; ++i ) 
		{ 
			for ( int j = 0; j < iw; ++j ) 
			{ 
				WORD data = surf[i * ipitch + j]; 
 
				if ( is_check_color_key ) 
				{ 
					if ( data == colorkey2 ) 
						++num_color_key; 
					else 
					{ 
						if ( num_color_key > 0 ) 
						{ 
							buf_temp[index++] = 0xffff;		//0xffff后跟的是透明色像素偏移 
							buf_temp[index++] = num_color_key;	//写入非阴影像素偏移 
						} 
						is_check_color_key = false; 
						num_color_key = 0; 
						num_shadow = 1; 
					} 
				} 
				else 
				{ 
					if ( data != colorkey2 ) 
						++num_shadow; 
					else 
					{ 
						if ( num_shadow > 0 ) 
						{ 
							buf_temp[index++] = 0xfffe;			//0xfffe表示后面跟的是阴影像素 
							buf_temp[index++] = num_shadow; 
						} 
 
						is_check_color_key = true; 
						num_shadow = 0; 
						num_color_key = 1; 
					} 
				} 
			}		// for every pixel in line 
 
			if ( is_check_color_key ) 
			{ 
				if ( num_color_key > 0 ) 
				{ 
					buf_temp[index++] = 0xffff;	 
					buf_temp[index++] = num_color_key; 
					num_color_key = 0; 
				} 
			} 
			else 
			{ 
				if ( num_shadow > 0 ) 
				{ 
					buf_temp[index++] = 0xfffe;	 
					buf_temp[index++] = num_shadow; 
					num_shadow = 0; 
				} 
			} 
			buf_temp[index++] = 0xfffd;				//换行符 
			 
		}	//for every line 
 
		buf_temp[index++] = 0x0000;			//结束符 
		EndDraw(); 
 
		FreeSurface(); 
		int w_new = index; 
		int h_new = 1;//index / w_new; 
		//if ( index % 16 != 0 )		h_new += 1; 
 
		if ( CreateNullSurface( w_new, h_new, true, false, 0 ) == false ) 
			return false; 
		surf = BeginDraw( &w_new, &h_new, &ipitch, 0 ); 
		if ( surf == NULL )		return false; 
		 
		int k = 0; 
		for ( i = 0; i < h_new; ++i ) 
		{ 
			for ( int j = 0; j < w_new; ++j ) 
			{ 
				if ( k < index ) 
					surf[i * ipitch + j] = buf_temp[k++]; 
				else 
					surf[i * ipitch + j] = 0x0000; 
			} 
		} 
		EndDraw(); 
		delete [] buf_temp; 
		m_iWidth = iw;		//宽和高还是原页面的宽高! 
		m_iHeight= ih; 
	} 
	else if ( magic == CONTOUR_IMAGE )				//带精灵轮廓的图片: 
	{ 
		surf = BeginDraw( &iw, &ih, &ipitch, pRect ); 
		if ( surf == NULL ) 
			return false; 
		 
		int i, j; 
		for ( i = 0; i < ih; ++i ) 
		{ 
			for ( j = 0; j < iw; ++j ) 
			{ 
				if ( surf[i * ipitch + j] != colorkey2 ) 
				{ 
					surf[i * ipitch + j] = colorkey;		// colorkey; 
					break; 
				} 
			} 
		} 
		for ( i = 0; i < ih; ++i ) 
		{ 
			for ( j = iw-1; j >= 0; --j ) 
			{ 
				if ( surf[i * ipitch + j] != colorkey2 ) 
				{ 
					surf[i * ipitch + j] = colorkey; 
					break; 
				} 
			} 
		} 
		for ( i = 0; i < iw; ++i ) 
		{ 
			for ( j = 0; j < ih; ++j ) 
			{ 
				if ( surf[j * ipitch + i] != colorkey2 ) 
				{ 
					surf[j * ipitch + i] = colorkey; 
					break; 
				} 
			} 
		} 
		for ( i = 0; i < iw; ++i ) 
		{ 
			for ( j = ih-1; j >= 0; --j ) 
			{ 
				if ( surf[j * ipitch + i] != colorkey2 ) 
				{ 
					surf[j * ipitch + i] = colorkey; 
					break; 
				} 
			} 
		} 
 
		EndDraw(); 
	} 
	else if ( magic == GRAY_IMAGE )					//灰度图制作#define RGB_TO_565(r,g,b)  ( (r << 11) | (g << 6 ) | b ) 
	{	 
															 
		surf = BeginDraw( &iw, &ih, &ipitch, pRect ); 
		if ( surf == NULL )		return false; 
 
		WORD r, g, b, t; 
		if ( is565 ) 
		{ 
			for ( int i = 0; i < ih; ++i ) 
			{ 
				for ( int j = 0; j < iw; ++j ) 
				{ 
					t = surf[i * ipitch + j]; 
					r = ( t >> 11 ); 
					g = ( t & MASK_G_565 ) >> 6; 
					b = ( t & MASK_B_565 ); 
					t = (r*3 + b*6+ g ) / 10; 
					//t = ( r + g + b ) / 3; 
					surf[i * ipitch + j] = ( (t << 11) | (t << 6 ) | t ); 
				} 
			} 
		} 
		else 
		{ 
			for ( int i = 0; i < ih; ++i ) 
			{ 
				for ( int j = 0; j < iw; ++j ) 
				{ 
					t = surf[i * ipitch + j]; 
					r = ( t >> 10 ); 
					g = ( t & MASK_G_555 ) >> 5; 
					b = ( t & MASK_B_555 ); 
					t = (r*3 + b*6+ g ) / 10; 
					//t = ( r + g + b ) / 3; 
					surf[i * ipitch + j] = ( (t << 10) | (t << 5 ) | t ); 
				} 
			} 
		} 
 
		EndDraw(); 
		if ( m_ColorKeyType == DDBLTFAST_SRCCOLORKEY ) 
		{ 
			if ( is565 ) 
			{ 
				r = colorkey2 >> 11; 
				g = ( colorkey2 & MASK_G_565 ) >> 6; 
				b = ( colorkey2 & MASK_B_565 ); 
				t = (r*3 + b*6+ g ) / 10; 
				colorkey2 = ( (t << 11) | (t << 6 ) | t ); 
			} 
			else 
			{ 
				r = colorkey2 >> 10; 
				g = ( colorkey2 & MASK_G_555 ) >> 5; 
				b = ( colorkey2 & MASK_B_555 ); 
				t = (r*3 + b*6+ g ) / 10; 
				colorkey2 = ( (t << 10) | (t << 5 ) | t ); 
			} 
			SetSurfaceColorKey( colorkey2 ); 
		} 
	} 
	else if ( magic >= 4 && magic <= 7 ) 
	{ 
		WORD mask; 
		switch ( magic ) 
		{ 
		case RED_IMAGE: 
			mask = MASK_R_565; 
			if ( !is565 ) mask = MASK_R_555; 
			break; 
		case GREEN_IMAGE: 
			mask = 0x3e0;		//MASK_G_565; 
			if ( !is565 ) mask = MASK_G_555; 
			break; 
		case BLUE_IMAGE: 
			mask = 0x1f; 
			break; 
		case MASK_OR: 
			mask = MaskColor; 
			break; 
		} 
 
		surf = BeginDraw( &iw, &ih, &ipitch, pRect ); 
		if ( surf == NULL )		return false; 
 
		for ( int i = 0; i < ih; ++i ) 
		{ 
			for ( int j = 0; j < iw; ++j ) 
				surf[i * ipitch + j] |= mask; 
		} 
		 
		EndDraw(); 
		colorkey2 = colorkey2 | mask; 
		SetSurfaceColorKey( colorkey2 ); 
	} 
	else if ( magic == MASK_AND ) 
	{ 
		surf = BeginDraw( &iw, &ih, &ipitch, pRect ); 
		if ( surf == NULL )		return false; 
 
		for ( int i = 0; i < ih; ++i ) 
		{ 
			for ( int j = 0; j < iw; ++j ) 
				surf[i * ipitch + j] &= MaskColor; 
		} 
		 
		EndDraw(); 
		colorkey2 = colorkey2 & MaskColor; 
		SetSurfaceColorKey( colorkey2 ); 
	} 
 
	return true; 
} 
 
////////////////////////////////////////////////////////////////////// 
//从ECP文件中载入不透明阴影,专门为低配置机器而写 
////////////////////////////////////////////////////////////////////// 
bool CSurface::LoadEcpShadowFromMemory( BYTE *pData, POINT *point ) 
{ 
	FreeSurface(); 
 
	ECPFILEHEADER efh; 
	efh = READ_MEMORY( pData, ECPFILEHEADER ); 
	pData += sizeof(efh); 
 
	int width, height; 
	if ( efh.ecpFileType == ECP_SHADOW ) 
	{ 
		width = ( efh.ecpWidth >> 16 ) & 0xffff; 
		height= ( efh.ecpHeight>> 16 ) & 0xffff; 
	} 
	else 
	{ 
		return false; 
	} 
 
	if ( CreateNullSurface( width, height, 0, true, 0xffff ) == false ) 
		return false; 
 
	ClearSurface( 0xffffff, 0 ); 
 
	if ( point != 0 ) 
	{ 
		point->x = efh.ecpBaseOffset.x; 
		point->y = efh.ecpBaseOffset.y; 
	} 
 
	int pitch; 
	WORD *buf = BeginDraw( &width, &height, &pitch, NULL ); 
	if ( buf == NULL ) 
		return false; 
 
	WORD *pline = buf; 
	WORD *pixel = buf; 
 
	while ( 1 ) 
	{ 
		WORD data = READ_MEMORY( pData, WORD ); 
		pData += sizeof(WORD); 
		switch ( data ) 
		{ 
		case 0xffff: 
			data = READ_MEMORY( pData, WORD ); 
			pData += sizeof(WORD); 
			pixel += data; 
			break; 
 
		case 0xfffe: 
			data = READ_MEMORY( pData, WORD ); 
			pData += sizeof(WORD); 
			memset( pixel, 0, data * 2 ); 
			pixel += data; 
			break; 
 
		case 0xfffd: 
			pline += pitch; 
			pixel = pline; 
			break; 
 
		case 0x0000: 
			goto exit_line; 
		} 
	} 
 
exit_line: 
	EndDraw(); 
	return true; 
}