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

📄 cbdraw.cpp

📁 赤壁之战的游戏源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	DRAW_rcScreen.top = nOffY;
	DRAW_rcScreen.bottom = DRAW_rcScreen.top + height;

	// if need't move
	if( DRAW_rcScreen.left == ptTopLeft.x && DRAW_rcScreen.top == ptTopLeft.y )
		return FALSE;

	// set screen offset
	DRAW_ptScreenOffset.x = (DRAW_rcScreen.left+DRAW_SCREEN_ADJUST)*MAP_Lib.szItem.cx;
	DRAW_ptScreenOffset.y = DRAW_rcScreen.top*(MAP_Lib.szItem.cy>>1);

	// update screen in new position
	DRAW_UpdateScreen();
	return TRUE;
}	// DRAW_JumpScreen()

// draw all the user defined maps to screen
// 更新屏幕
// bFront		:	TRUE如果贴图到屏幕的前缓冲区内
void DRAW_UpdateScreen( BOOL bFront/*=TRUE*/ )
{
	if( !DRAW_bLoadMaps )	return;
	DRAW_DrawGround( DRAW_rcClient, 0, FALSE );
	DRAW_DrawGround( DRAW_rcClient, 1, FALSE );
	DRAW_DrawGround( DRAW_rcClient, 2, FALSE );
	DRAW_DrawBack2BkGround();
	DRAW_DrawUnit( DRAW_rcClient, FALSE );

	// draw shadow
	SHADOW_DrawAll();
	// draw shadow
	SHADOW_Update2Back();

	// draw minimap
	MINI_Update( FALSE );	// to front buffer

	GFWI_bUpdate = TRUE;
//	DrawHZ( NULL );

	if( bFront )
		DDC_UpdateScreen( &DRAW_rcClient );
}	// DRAW_UpdateScreen()
/////////////////////

/////////////////////
// draw one ground item
// 显示地形一个图素
// prcCut	:	只更新此矩形区内的图像
// k,i,j	:	图素的层号,行号,列号
// bFront	:	是否直接更新到显示屏幕
inline void DRAW_DrawSingleG( CONST RECT *prcCut, int k, int i, int j, BOOL bFront )
{
	RECT rect;
	RECT rcCutG;

	// decode
	WORD code = MAP_GetGroundData( k, i, j );
	if( code == MAP_DATA_NONE ) return;
	struct MAP_GROUND_CODE_STRUCT stctG;
	MAP_GroundDeCode( code, &stctG );

	// get update region
	RECT rcCutGOld = ::MAP_GetGroundRect( DRAW_ptScreenOffset, k, i, j, stctG.nFile );
	if( IntersectRect( &rcCutG, &rcCutGOld, prcCut ) )
	{
		POINT ptTLOff, ptRBOff;
		ptTLOff.x = rcCutGOld.left - rcCutG.left;
		ptTLOff.y = rcCutGOld.top - rcCutG.top;
		ptRBOff.x = rcCutGOld.right - rcCutG.right;
		ptRBOff.y = rcCutGOld.bottom - rcCutG.bottom;

		// calc source position and size
		rect.left = stctG.nCol*(rcCutGOld.right - rcCutGOld.left) - ptTLOff.x;
		rect.right = (stctG.nCol+1)*(rcCutGOld.right - rcCutGOld.left) - ptRBOff.x;
		rect.top = stctG.nRow*(rcCutGOld.bottom - rcCutGOld.top) - ptTLOff.y;
		rect.bottom = (stctG.nRow+1)*(rcCutGOld.bottom - rcCutGOld.top) - ptRBOff.y;

		// draw
		POINT ptDest;
		ptDest.x = rcCutG.left, ptDest.y = rcCutG.top;
	//	class CDDSurface *pSurface = &DRAW_sGroundMap[stctG.nFile];
	//	pSurface->BltToBack( ptDest, &rect );
		DRAW_sGroundMap[stctG.nFile].BltToBack( ptDest, &rect );
		}

	// draw special ground item
	if( stctG.nAttr != MAP_SPECIAL_NONE )
	{
		DRAW_DrawSingleS( prcCut, i, j, bFront, stctG.nAttr, k );
	}

	if( bFront )
	{
#ifdef	_CURSOR_OLD_VERSION_
		DDC_UpdateSprite( &rcCutG, &rcCutG );
#endif	// 	_CURSOR_OLD_VERSION_
	}

} // DRAW_DrawSingleG()

// 显示某单元
// prcCut	:	只更新此矩形区内的图像
// pstctCF	:	单元图素显示帧结构
inline BOOL DRAW_DrawUnitSingle( CONST RECT *prcCut, const struct CTRL_FRAME_STRUCT *pstctCF )
{
// if hide by shadow do not draw it
	{
	if( SHADOW_IfEnabled() )
	{
		BOOL bOdd = pstctCF->nY&1;
		int nX, nY;
		WORD codeR;
		struct MAP_REGION_CODE_STRUCT stctR;
		int nNotDraw=0;
		for( int x=0; x<MAP_nLocationNum[pstctCF->nLocationSize]; x++ )
		{
			nX = pstctCF->nX + MAP_ptLocation[bOdd][x].x,
			nY = pstctCF->nY + MAP_ptLocation[bOdd][x].y;
			Assert( !EYE_IfOutOfRange( nX, nY ) );
			codeR = MAP_GetRegionData( nX, nY );
			MAP_RegionDeCode( codeR, &stctR );
			if( stctR.nShadow == MAP_SHADOW_NONE 
				// 对于士兵半透明阴影也要隐藏
				|| ( stctR.nShadowEx == 1 && pstctCF->nFile >= 27 ) )
				nNotDraw++;
			else break;
		}
		if( nNotDraw == MAP_nLocationNum[pstctCF->nLocationSize] )
			return FALSE;	// 全部被阴影盖住,不画
	}
	}
#ifdef	_MAP_COMPRESS_
	// get update region
	RECT rcCutGOld, rcCutG;
	RECT rcOff;
	POINT ptDest;

	rcCutGOld = ::MAP_GetUnitRect( DRAW_ptScreenOffset, pstctCF );

	// test if needn't draw, outside client area
	if( !IntersectRect( &rcCutG, &rcCutGOld, prcCut ) )	
	{
		return FALSE;
	}

	// calc offset
	rcOff.left = rcCutGOld.left - rcCutG.left;
	rcOff.top = rcCutGOld.top - rcCutG.top;
	rcOff.right = rcCutGOld.right - rcCutG.right;
	rcOff.bottom = rcCutGOld.bottom - rcCutG.bottom;

	// calc destination position
	ptDest.x = rcCutG.left, ptDest.y = rcCutG.top;

		//-
//		char * pBuffer = NULL;
		//-

	// test if should cut edge
	if( rcOff.left!=0 || rcOff.top!=0 || rcOff.right !=0 || rcOff.bottom !=0 )
	{	// cut edge
		RECT rcSrcMMX;
		POINT ptDestMMX;
		
		// for blting on MMX surface
		ptDestMMX.x = ptDestMMX.y = 0;
		rcSrcMMX.left = 0 - rcOff.left;
		rcSrcMMX.top = 0 - rcOff.top;
		rcSrcMMX.right = rcCutGOld.right - rcCutGOld.left - rcOff.right;
		rcSrcMMX.bottom = rcCutGOld.bottom - rcCutGOld.top - rcOff.bottom;

		LPDIRECTDRAWSURFACE2 pSurDest = DRAW_sMMX.GetSurface();
		DDSURFACEDESC       ddsdDest;
		ddsdDest.dwSize = sizeof( ddsdDest );

		// for change color
		short colorSub[4] = {0 , -57, 90, 53 };
		short ncolorIdx;

		int widthDest = 0;
		DRAW_sMMX.Erase();
		if( pSurDest->Lock( NULL, &ddsdDest, DDLOCK_WAIT, NULL ) == DD_OK )
		{

			// 闪烁显示被选中的单元A
			if( pstctCF->bUpdate >= 5 )
			{
				if( DRAW_BLINK_bDraw == TRUE )
				{
					DRAW_drawBorderTop( &ptDestMMX, ddsdDest.dwWidth, (BYTE*)ddsdDest.lpSurface, 
						&rcCutGOld, pstctCF->nLocationSize, pstctCF->bUpdate-1-5 );
				}
			}
			else if( pstctCF->bUpdate>0 )
			{
				DRAW_drawBorderTop( &ptDestMMX, ddsdDest.dwWidth, (BYTE*)ddsdDest.lpSurface, 
					&rcCutGOld, pstctCF->nLocationSize, pstctCF->bUpdate-1 );
			}
	//-
//				pBuffer = (char *)malloc( ddsdDest.dwWidth*ddsdDest.dwHeight );
//				if( pBuffer != NULL )
//					memcpy( pBuffer, ddsdDest.lpSurface, ddsdDest.dwWidth*ddsdDest.dwHeight );
	//-
			ncolorIdx = pstctCF->nPlayer-1;
			if( ncolorIdx <0 ) ncolorIdx = 0;
			Assert( ncolorIdx < 4 );
			if( MAIN_bMMX )
			{	//-- MMX extension
				DRAW_ImageLib.P_imageMMX(ptDestMMX.x, ptDestMMX.y, ddsdDest.dwWidth, 
						(char*)ddsdDest.lpSurface,
						ncolorIdx, pstctCF->nCol );
				//-- MMX extension
			}
			else
			{
				ncolorIdx = colorSub[ncolorIdx];	// 把颜色序号变为颜色
				if( ncolorIdx == 0 )
				{	// 不变色
					DRAW_ImageLib.P_imageDirect(ptDestMMX.x, ptDestMMX.y, ddsdDest.dwWidth, 
							(char*)ddsdDest.lpSurface,
							ncolorIdx, pstctCF->nCol );
				}
				else
				{
					DRAW_ImageLib.P_image(ptDestMMX.x, ptDestMMX.y, ddsdDest.dwWidth, 
							(char*)ddsdDest.lpSurface,
							ncolorIdx, pstctCF->nCol );
				}
			}

			// 闪烁显示被选中的单元B
			if( pstctCF->bUpdate >= 5 )
			{
				if( DRAW_BLINK_bDraw == TRUE )
				{
					DRAW_drawBorderBottom( &ptDestMMX, ddsdDest.dwWidth, (BYTE*)ddsdDest.lpSurface, 
						&rcCutGOld, pstctCF->nLocationSize, pstctCF->bUpdate-1-5 );
				}
			}
			else if( pstctCF->bUpdate>0 )
			{
				DRAW_drawBorderBottom( &ptDestMMX, ddsdDest.dwWidth, (BYTE*)ddsdDest.lpSurface, 
					&rcCutGOld, pstctCF->nLocationSize, pstctCF->bUpdate-1 );
			}
			pSurDest->Unlock( NULL );
		}
		DRAW_sMMX.BltToBack( ptDest, &rcSrcMMX );
	}
	else
	{
		LPDIRECTDRAWSURFACE2 pSurDest = DD_GetBackBuffer();
		DDSURFACEDESC       ddsdDest;
		ddsdDest.dwSize = sizeof( ddsdDest );

		// for change color
		int colorSub[4] = {0 , -57, 90, 53 };
		int ncolorIdx;

		int widthDest = 0;
		if( pSurDest->Lock( NULL, &ddsdDest, DDLOCK_WAIT, NULL ) == DD_OK )
		{
			// 闪烁显示被选中的单元A
			if( pstctCF->bUpdate >= 5 )
			{
				if( DRAW_BLINK_bDraw == TRUE )
				{
					DRAW_drawBorderTop( &ptDest, ddsdDest.dwWidth, (BYTE*)ddsdDest.lpSurface, 
						&rcCutGOld, pstctCF->nLocationSize, pstctCF->bUpdate-1-5 );
				}
			}
			else if( pstctCF->bUpdate>0 )
				DRAW_drawBorderTop( &ptDest, ddsdDest.dwWidth, (BYTE*)ddsdDest.lpSurface, 
					&rcCutGOld, pstctCF->nLocationSize, pstctCF->bUpdate-1 );

	//-
//				pBuffer = (char *)malloc( ddsdDest.dwWidth*ddsdDest.dwHeight );
//				if( pBuffer != NULL )
//					memcpy( pBuffer, ddsdDest.lpSurface, ddsdDest.dwWidth*ddsdDest.dwHeight );
	//-

			ncolorIdx = pstctCF->nPlayer-1;
			if( ncolorIdx <0 ) ncolorIdx = 0;
			Assert( ncolorIdx < 4 );
			if( MAIN_bMMX )
			{	//-- MMX extension
				DRAW_ImageLib.P_imageMMX(ptDest.x, ptDest.y, ddsdDest.dwWidth, 
						(char*)ddsdDest.lpSurface,
						ncolorIdx, pstctCF->nCol );
				//-- MMX extension
			}
			else
			{
				ncolorIdx = colorSub[ncolorIdx];	// 把颜色序号变为颜色
				if( ncolorIdx == 0 )
				{	// 不变色
					DRAW_ImageLib.P_imageDirect(ptDest.x, ptDest.y, ddsdDest.dwWidth, 
							(char*)ddsdDest.lpSurface,
							ncolorIdx, pstctCF->nCol );
				}
				else
				{
					DRAW_ImageLib.P_image(ptDest.x, ptDest.y, ddsdDest.dwWidth, 
							(char*)ddsdDest.lpSurface,
							ncolorIdx, pstctCF->nCol );
				}
			}

			// 闪烁显示被选中的单元B
			if( pstctCF->bUpdate >= 5 )
			{
				if( DRAW_BLINK_bDraw == TRUE )
				{
					DRAW_drawBorderBottom( &ptDest, ddsdDest.dwWidth, (BYTE*)ddsdDest.lpSurface, 
						&rcCutGOld, pstctCF->nLocationSize, pstctCF->bUpdate-1-5 );
				}
			}
			else if( pstctCF->bUpdate>0 )
				DRAW_drawBorderBottom( &ptDest, ddsdDest.dwWidth, (BYTE*)ddsdDest.lpSurface, 
					&rcCutGOld, pstctCF->nLocationSize, pstctCF->bUpdate-1 );

			pSurDest->Unlock( NULL );
		}
	//-
/*
		if( pBuffer )
		{
			DRAW_ImageLib.P_image(100, 100, ddsdDest.dwWidth, 
				pBuffer, 0, 0 );

			free( pBuffer );
		}
		else
		{
			OutputDebugString( "Not enough memory!\n" );
		}
*/
	//-
	}
	return TRUE;
#endif //_MAP_COMPRESS_
}

// 显示菱形框的上半部分,应该被该单元遮挡
// pptDest		:	目的地坐标,左上角
// dwWidthDest	:	目的地缓冲区的宽度
// pDest		:	目的地数据指针
// prcCutGOld	:	该单元的矩形大小和位置
// nSize		:	该单元所占位置的大小(格子)
// nColorIndex	:	应该贴成什么样的颜色
void DRAW_drawBorderTop( CONST POINT *pptDest, DWORD dwWidthDest, BYTE *pDest, 
						CONST RECT *prcCutGOld, int nSize, int nColorIndex )
{
	int i;
	if( nSize == 3 ) nSize = 2;
	
	// colors
	int nColor = DRAW_nBdrColors[nColorIndex];

	// loop number
	int nLoopNum = (MAP_Lib.szItem.cy>>1)*(nSize+1);
	// source rectangle size
	int nSrcWidth = prcCutGOld->right - prcCutGOld->left;
	int nSrcHeight = prcCutGOld->bottom - prcCutGOld->top;
	// border size
	int nBdrWidth = (nSize+1)*MAP_Lib.szItem.cx;
	int nBdrHeight = (nSize+1)*MAP_Lib.szItem.cy;
	// Top-left point of border
	int nBdrLeft = pptDest->x + ((nSrcWidth - nBdrWidth)>>1);
	int nBdrTop = pptDest->y + nSrcHeight - nBdrHeight;

	// destination buffer pointer
	BYTE * pBytesDest;	
	// left part, calculate begin and end value for loop
	// draw left part, from bottom to top, left to right
	pBytesDest = pDest + dwWidthDest*(nBdrTop+(nBdrHeight>>1)) + nBdrLeft;
	for (i=0; i<nLoopNum; i++ )
	{
		memset( pBytesDest, nColor, 2 );
		pBytesDest -= dwWidthDest-2;
	}

	// right part, calculate begin and end value for loop
	// draw right part
	pBytesDest = pDest + dwWidthDest*(nBdrTop+2) + nBdrLeft + (nBdrWidth>>1);
	for (i=0; i<nLoopNum-1; i++ )
	{
		memset( pBytesDest, nColor, 2 );
		pBytesDest += dwWidthDest+2;
	}
}

// 显示菱形框的下半部分,应该遮挡该单元
// pptDest		:	目的地坐标,左上角
// dwWidthDest	:	目的地缓冲区的宽度
// pDest		:	目的地数据指针
// prcCutGOld	:	该单元的矩形大小和位置
// nSize		:	该单元所占位置的大小(格子)
// nColorIndex	:	应该贴成什么样的颜色
void DRAW_drawBorderBottom( CONST POINT *pptDest, DWORD dwWidthDest, BYTE *pDest, 
						CONST RECT *prcCutGOld, int nSize, int nColorIndex )
{
	int i;
	if( nSize == 3 ) nSize = 2;

	// colors
	int nColor = DRAW_nBdrColors[nColorIndex];

	// loop number
	int nLoopNum = (MAP_Lib.szItem.cy>>1)*(nSize+1);
	// source rectangle size
	int nSrcWidth = prcCutGOld->right - prcCutGOld->left;
	int nSrcHeight = prcCutGOld->bottom - prcCutGOld->top;
	// border size
	int nBdrWidth = (nSize+1)*MAP_Lib.szItem.cx;
	int nBdrHeight = (nSize+1)*MAP_Lib.szItem.cy;
	// Top-left point of border
	int nBdrLeft = pptDest->x + ((nSrcWidth - nBdrWidth)>>1);
	int nBdrTop = pptDest->y + nSrcHeight - nBdrHeight;

	// destination buffer pointer
	BYTE * pBytesDest;
	// left part, calculate begin and end value for loop
	// draw left part
	pBytesDest = pDest + dwWidthDest*(nBdrTop+(nBdrHeight>>1)) + nBdrLeft;
	for (i=0; i<nLoopNum; i++ )
	{
		memset( pBytesDest, nColor, 2 );
		pBytesDest += dwWidthDest+2;
	}

	// right part, calculate begin and end value for loop
	// draw right part
	pBytesDest = pDest + dwWidthDest*(nBdrTop+nBdrHeight-2) + nBdrLeft + (nBdrWidth>>1);
	for (i=0; i<nLoopNum-1; i++ )
	{
		memset( pBytesDest, nColor, 2 );
		pBytesDest -= dwWidthDest-2;
	}
}

// 显示被某单元遮挡的所有地形,实际上是重新画该矩形区域内的地形
// 从背景面上拷贝出一块区域贴图
// darw other things
// prcCut	:	只更新此矩形区内的图像
// pstctCF	:	单元图素显示帧结构
inline void DRAW_DrawUnitCovered( CONST RECT *prcCut, const struct CTRL_FRAME_STRUCT *pstctCF )
{
	POINT ptDest;
	RECT rcSrc;
	ptDest.x = prcCut->left, ptDest.y = prcCut->top;
	rcSrc.left = prcCut->left - DRAW_rcClient.left;
	rcSrc.top = prcCut->top - DRAW_rcClient.top;
	rcSrc.right = prcCut->right - DRAW_rcClient.left;
	rcSrc.bottom = prcCut->bottom - DRAW_rcClient.top;
	DD_BltSurface( ptDest, DD_GetBackBuffer(), &rcSrc, DRAW_sBkGround.GetSurface(), DDBLTFAST_NOCOLORKEY );
}

// 显示遮挡某单元的所有单元
// prcCut	:	只更新此矩形区内的图像
// pstctCF	:	单元图素显示帧结构
inline void DRAW_DrawUnitCovering( CONST RECT *prcCut, const struct CTRL_FRAME_STRUCT *pstctCF )
{
	int i, j, k;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -