📄 cbdraw.cpp
字号:
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 + -