📄 cbdraw.cpp
字号:
POINT pt;
int nX = pstctCF->nX;
int nY = pstctCF->nY;
// draw the first level
i = nY&1;
int nLayer = pstctCF->nLayer;
// for( k=0; k<6; k+=2 )
// for( j=0; j<9; j++ )
for( k=0; k<8; k+=2 )
for( j=0; j<11; j++ )
{
if( pstctCF->nLocationSize == 0 && j < 5 && k== 0 ) continue;
pt.x = nX+ptCovering[i][j].x;
pt.y = nY+ptCovering[i][j].y+k;
if( EYE_IfOutOfRange( pt.x, pt.y ) )
continue;
// draw special grounds around the unit
struct MAP_GROUND_CODE_STRUCT stctG;
WORD codeG = MAP_GetGroundData( nLayer, pt.x, pt.y );
MAP_GroundDeCode( codeG, &stctG );
if( stctG.nAttr == MAP_SPECIAL_NONE ) continue;
int nA = stctG.nAttr%4;
int nB = stctG.nAttr/4;
int nC = 0;
if( nB == 2 ) continue; // 如果是已经被砍伐过的资源则不画
DRAW_OTHER_Draw( prcCut, 7, (nA<<1)+nC, nLayer, pt.x, pt.y );
/* // get special code
struct CTRL_FRAME_STRUCT stctCF;
Assert( stctG.nAttr != MAP_SPECIAL_NONE );
if( !MAP_GetSpecFrameData( nLayer, pt.x, pt.y, stctG.nAttr, &stctCF ) )
continue;
// draw special unit in current position
DRAW_DrawUnitSingle( prcCut, &stctCF );
*/
}
// draw the second level
nLayer ++;
for( k=0; k<12; k+=2 )
for( j=0; j<11; j++ )
{
if( pstctCF->nLocationSize == 0 && j < 5 && k== 0 ) continue;
pt.x = nX+ptCovering[i][j].x;
pt.y = nY+ptCovering[i][j].y+k;
if( pt.x < 0 || pt.y < 0 || pt.x >= MAP_Lib.szNum.cx || pt.y >= MAP_Lib.szNum.cy )
continue;
// draw grounds around the unit
DRAW_DrawSingleG( prcCut, nLayer, pt.x, pt.y, FALSE );
}
if( nLayer == 2 ) return;
// draw the third level right above the unit
for( j=MAP_nLocationNum[pstctCF->nLocationSize]-1; j>=0; j-- )
{
pt.x = nX+MAP_ptLocation[i][j].x;
pt.y = nY+MAP_ptLocation[i][j].y;
// draw grounds above the unit
DRAW_DrawSingleG( prcCut, 2, pt.x, pt.y, FALSE );
}
// draw the third level
for( k=0; k<12; k+=2 )
for( j=0; j<11; j++ )
{
if( pstctCF->nLocationSize == 0 && j < 5 && k== 0 ) continue;
pt.x = nX+ptCovering[i][j].x;
pt.y = nY+ptCovering[i][j].y+k;
if( pt.x < 0 || pt.y < 0 || pt.x >= MAP_Lib.szNum.cx || pt.y >= MAP_Lib.szNum.cy )
continue;
// draw grounds around the unit
DRAW_DrawSingleG( prcCut, 2, pt.x, pt.y, FALSE );
}
}
// 显示一个单元,包含了更新其周围的单元的操作
// draw one unit item
// prcCut : 只更新此矩形区内的图像
// i,j : 图素的行号,列号
// bFront : 是否直接更新到显示屏幕
RECT DRAW_rcUpdate={0,0,0,0};
inline void DRAW_DrawSingleU( CONST RECT *prcCut, int i, int j, BOOL bFront )
{
//RECT rect; // source rectangle
RECT rcCutG, rcCutGSave; // update region for current position
// get code
struct CTRL_FRAME_STRUCT stctCF;
if( !MAP_GetUnitFrameData( i, j, &stctCF, FALSE ) )
return;
// 敌人正在埋伏,不显示出来
struct UNIT_STRUCT *pUnit = MAP_GetUnit( i,j );
Assert( pUnit );
if( pUnit->Status.nTaskID == MFU && pUnit->Draw.nPlayer != GAME.nMe )
return;
// debug
// if( pUnit->Status.nTaskID == MFU )
// return;
// test if should draw
// if( !stctCF.bUpdate ) return;
// below: same as DRAW_DrawSingleS()
// draw this unit in current position
BOOL bDraw = DRAW_DrawUnitSingle( prcCut, &stctCF );
// draw covering items, items which covering this unit
// get update region
rcCutGSave = ::MAP_GetUnitRect( DRAW_ptScreenOffset, &stctCF );
// 显示计谋提示图标(血点)
if( bDraw && pUnit->Draw.nFile > 28 ) // 建筑没有计谋
DRAW_Draw8x8( pUnit, &rcCutGSave, prcCut );
// draw covering
if( bDraw && stctCF.nLayer != 2
&& IntersectRect( &rcCutG, &rcCutGSave, prcCut ) )
DRAW_DrawUnitCovering( &rcCutG, &stctCF );
// calculate update region
// The mouse cursor is blinking, so do not use it
/* RECT rcCutGL, rcCutGLSave; // update region for previous position
rcCutGLSave = ::MAP_GetUnitRectLast( DRAW_ptScreenOffset, &stctCF );
IntersectRect( &rcCutGL, &rcCutGLSave, prcCut );
UnionRect( &DRAW_rcUpdate, &rcCutGL, &DRAW_rcUpdate );
UnionRect( &DRAW_rcUpdate, &rcCutG, &DRAW_rcUpdate );
*/
} // DRAW_DrawSingleU()
// 显示一个特殊图素,树木,麦田,陷阱等
// draw one special item
// prcCut : 只更新此矩形区内的图像
// i,j : 图素的行号,列号
// bFront : 是否直接更新到显示屏幕
// Attr : 特殊图素的属性,非0时有效
// k : 特殊图素的层号,nAttr非0时有效
inline void DRAW_DrawSingleS( CONST RECT *prcCut, int i, int j, BOOL bFront, int nAttr, int k )
{
//RECT rect; // source rectangle
// get code
// struct CTRL_FRAME_STRUCT stctCF;
Assert( nAttr != MAP_SPECIAL_NONE );
// if( !MAP_GetSpecFrameData( k, i, j , nAttr, &stctCF ) )
// return;
// below: same as DRAW_DrawSingleU()
// draw this unit in current position
//DRAW_DrawUnitSingle( prcCut, &stctCF );
int nA = nAttr%4;
int nB = nAttr/4;
int nC = 0;
if( nB == 2 ) nC = 1;
DRAW_OTHER_Draw( prcCut, 7, (nA<<1)+nC, k, i, j );
} // DRAW_DrawSingleS()
/////////////////////
/////////////////////
// 显示战场区域内的所有地形图素
// draw ground items
// rcCut : 只更新此矩形区内的图像
// k : 地形图素的层号
// bFront : 是否直接更新到显示屏幕
inline void DRAW_DrawGround( RECT rcCut, int k, BOOL bFront )
{
for( int j=DRAW_rcScreen.top; j<DRAW_rcScreen.bottom; j++ )
for( int i=DRAW_rcScreen.left; i<DRAW_rcScreen.right; i++ )
{
DRAW_DrawSingleG( &rcCut, k, i, j, bFront );
}
}
// 显示战场区域内的所有单元图素
// draw unit itmes
// rcCut : 只更新此矩形区内的图像
// bFront : 是否直接更新到显示屏幕
inline void DRAW_DrawUnit( RECT rcCut, BOOL bFront )
{
int i, j;
// 闪烁动画效果,计数
if( DRAW_BLINK_nID != MAP_DATA_NONE )
{
if( DRAW_BLINK_bDraw == TRUE )
{ // 显示延时
if( DRAW_BLINK_nDelay < DRAW_BLINK_DELAY1 )
{
DRAW_BLINK_nDelay++;
}
else
{ // 时间到
DRAW_BLINK_nDelay = 0;
DRAW_BLINK_bDraw = FALSE;
}
}
else
{ // 隐藏延时
if( DRAW_BLINK_nDelay < DRAW_BLINK_DELAY2 )
{
DRAW_BLINK_nDelay++;
}
else
{ // 时间到
DRAW_BLINK_nDelay = 0;
DRAW_BLINK_bDraw = TRUE;
DRAW_BLINK_nCounter++;
if( DRAW_BLINK_nCounter >= DRAW_BLINK_COUNT )
{ // 结束闪烁
struct UNIT_STRUCT *pU = MAP_GetUnit( DRAW_BLINK_nID );
Assert( pU );
DRAW_BLINK_nID = MAP_DATA_NONE;
pU->Draw.bUpdate = DRAW_BLINK_nSave;
}
}
}
}// End of if( DRAW_BLINK_nID != MAP_DATA_NONE )
// 显示战场区域内的所有单元
// ~40ms
for( j=DRAW_rcScreen.top; j<DRAW_rcScreen.bottom; j++ )
for( i=DRAW_rcScreen.left; i<DRAW_rcScreen.right; i++ )
{
DRAW_DrawSingleU( &rcCut, i, j, bFront );
}
}
// 是否是正式版
extern MAIN_bRelease; // defined in CBMain.cpp
void DrawHZ( class CDDSurface * pSurface )
{
HDC hdc=0;
BOOL bUpdate =FALSE;
static char strSave[20]="";
UpdateGFWI();
if( MAIN_bRelease == TRUE )
return;
if( strcmp( strSave, strCopyright )!= 0 )
{
tCopyright.GetDDSurface()->Erase();
bUpdate = TRUE;
OutputDebugString( strSave );
OutputDebugString( "," );
OutputDebugString( strCopyright );
OutputDebugString( "\n" );
tCopyright.MyTextOut( DD_GetBackBuffer(), 24, 460, strCopyright );
strcpy( strSave, strCopyright );
RECT rect;
rect.left = 24;
rect.top = 460;
rect.right = rect.left + tCopyright.GetDDSurface()->GetSize().cx;
rect.bottom = rect.top + tCopyright.GetDDSurface()->GetSize().cy;
if( bUpdate ) DDC_UpdateScreen( &rect );
}
}
/////////////////////
/////////////////////
// 拷贝游戏背景面到地形背景面
// prcCut : 剪裁的范围,如果为NULL,则拷贝整个战场的区域
void DRAW_DrawBack2BkGround( CONST RECT *prcCut /*=NULL */)
{
POINT ptDest;
RECT rcSrc;
if( prcCut == NULL )
{
ptDest.x = ptDest.y = 0;
SetRect( &rcSrc, DRAW_rcClient.left,
DRAW_rcClient.top,
DRAW_rcClient.right,
DRAW_rcClient.bottom );
}
else
{
ptDest.x = prcCut->left - DRAW_rcClient.left,
ptDest.y = prcCut->top - DRAW_rcClient.top;
SetRect( &rcSrc, prcCut->left,
prcCut->top,
prcCut->right,
prcCut->bottom );
}
// draw from backbuffer to bkGround surface
DD_BltSurface( ptDest, DRAW_sBkGround.GetSurface(), &rcSrc, DD_GetBackBuffer(), DDBLTFAST_NOCOLORKEY );
}
// 拷贝地形背景面到游戏背景面
// prcCut : 剪裁的范围,如果为NULL,则拷贝整个战场的区域
void DRAW_DrawBkGround2Back( CONST RECT *prcCut/*= NULL*/ )
{
// draw background
// ~2.8ms
POINT ptDest;
RECT rcSrc;
if( prcCut == NULL )
{
ptDest.x = DRAW_rcClient.left, ptDest.y = DRAW_rcClient.top;
rcSrc.left = rcSrc.top =0,
rcSrc.right = DRAW_rcClient.right - DRAW_rcClient.left,
rcSrc.bottom = DRAW_rcClient.bottom - DRAW_rcClient.top;
}
else
{
ptDest.x = prcCut->left, ptDest.y = prcCut->top;
SetRect( &rcSrc, prcCut->left,
prcCut->top,
prcCut->right,
prcCut->bottom );
OffsetRect( &rcSrc, -DRAW_rcClient.left, -DRAW_rcClient.top );
}
DD_BltSurface( ptDest, DD_GetBackBuffer(), &rcSrc, DRAW_sBkGround.GetSurface(), DDBLTFAST_NOCOLORKEY );
}
/////////////////////
/////////////////////
// 显示单元、阴影、水纹的效果、汉字、更新缩略图等
// 每秒钟要运行几十次
// draw maps in every program cycle
#define DRAW_CLOCK_CIRCLE 5
void DRAW_DrawMaps( void )
{
if( !DRAW_bLoadMaps ) return;
// draw background
// S->S, no colorkey, 5.13ms, 195 frames/sec
// 将原来保存的地形背景面显示到游戏的背景面上
DRAW_DrawBkGround2Back( &DRAW_rcClient );
// draw others lower than units
DRAW_DrawOthersCOM( OTHER_TYPE_BLOOD );
// draw units
// 27 frames/sec, 37 ms
DRAW_DrawUnit( DRAW_rcClient, TRUE );
// draw others upper than units
DRAW_DrawOthersBMP( OTHER_TYPE_FIRE );
//---
// draw blinking water
// 2500 frames/sec, 0.4 ms
#ifndef _DEBUG
DRAW_FlipWater();
#endif
// draw mouse dragging rectangle to back buffer
// 1550 frames/sec, 0.645ms
MOUSE_DrawDragRect();
// 在每轮的循环中,向游戏背景面上重画完地形和单元后,重画阴影,即将阴影背景面贴到游戏背
// 景面上.
// draw shadow,
// V->S, colorkey, 8.33ms, 120 frames/sec
SHADOW_Update2Back();
// 显示鼠标痕迹,当鼠标点击了地面之后,出现一个指示的手势
// 必须在最后,在最上面
DRAW_DrawOthersMouse();
// draw build surface
BUILD_Draw( &DRAW_rcClient );
// draw characters, should be at last
// English: 5080 frames/sec, nearly 0ms consumed
// Chinese: 4700 frames/sec, 0.213ms
DrawHZ( NULL );
//---- begin clock session
// 在此区域内只有满足时钟属性nClkAttr的函数才被运行
// 把缩略图画到背景面上
// July 23, 1997
static int nClock=0;
int nClkAttr = nClock%DRAW_CLOCK_CIRCLE;
if( nClkAttr == 1 )
{
// draw minimap only in back buffer
MINI_Update( 0 );
}
nClock++;
//---- end clock session
//---- network only
// July 23, 1997
// GAME.bNetwork = TRUE;
FACE_BlitCurrentMenu();
// 把缩略图更新到前屏幕上
// July 23, 1997
if( nClkAttr == 1 )
{
// draw minimap only in back buffer
MINI_Update( 2 );
}
// update to front buffer, S->S, no colorkey, 5.56ms, 180 frames/sec
DDC_UpdateScreen( &DRAW_rcClient );
// DDBLTFAST_NOCOLORKEY
} // DRAW_DrawMaps()
/////////////////////
void UpdateGFWI()
{
if( GFWI_bUpdate == TRUE )
{
char str[20];
int nColor=97;
itoa( GAME.Players[GAME.nMe].nGold, str, 10 );
tGold.GetDDSurface()->Erase( nColor );
tGold.MyTextOut( DD_GetBackBuffer(), 52, 21, str );
itoa( GAME.Players[GAME.nMe].nFood, str, 10 );
tFood.GetDDSurface()->Erase( nColor );
tFood.MyTextOut( DD_GetBackBuffer(), 155, 21, str );
itoa( GAME.Players[GAME.nMe].nWood, str, 10 );
tWood.GetDDSurface()->Erase( nColor );
tWood.MyTextOut( DD_GetBackBuffer(), 445, 21, str );
itoa( GAME.Players[GAME.nMe].nIron, str, 10 );
tIron.GetDDSurface()->Erase( nColor );
tIron.MyTextOut( DD_GetBackBuffer(), 548, 21, str );
RECT rect;
rect.left = 52;
rect.top = 21;
rect.right = rect.left + tGold.GetDDSurface()->GetSize().cx+16;
rect.bottom = rect.top + tGold.GetDDSurface()->GetSize().cy;
DDC_UpdateScreen( &rect );
rect.left = 155;
rect.top = 21;
rect.right = rect.left + tFood.GetDDSurface()->GetSize().cx+16;
rect.bottom = rect.top + tFood.GetDDSurface()->GetSize().cy;
DDC_UpdateScreen( &rect );
rect.left = 445;
rect.top = 21;
rect.right = rect.left + tWood.GetDDSurface()->GetSize().cx+16;
rect.bottom = rect.top + tWood.GetDDSurface()->GetSize().cy;
DDC_UpdateScreen( &rect );
rect.left = 548;
rect.top = 21;
rect.right = rect.left + tIron.GetDDSurface()->GetSize().cx+16;
rect.bottom = rect.top + tIron.GetDDSurface()->GetSize().cy;
DDC_UpdateScreen( &rect );
GFWI_bUpdate = FALSE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -