📄 cbdrawot.cpp
字号:
/////////////
// CBDrawOT.cpp : v0010
// Written by : Liu Gang
// Compiler : Microsoft Visual C++ 4.0 & DirectX
// Library : DDraw.Lib
// Copyright (C) : 1996 WayAhead Corporation
// v0010 : Mar.29.1997, devided from CBDraw.cpp
/////////////
#include "stdafx.h"
#include "CBDraw.h"
#include "DDCompo.h"
#include "CBMap.h"
#include "CBOther.h"
//////////////////
// other map surfaces, in CBDraw.cpp
extern POINT DRAW_ptScreenOffset;
extern class CDDSurface DRAW_sOtherMap[MAP_OTHER_NUM];
//---------------LWC
#ifdef _MAP_COMPRESS_
#include "L_image.h"
// image compression library
extern class CPicture_image DRAW_ImageLib;
#endif
//---------------LWC
extern class CDDSurface DRAW_sMMX;
// defined in CBDraw.cpp
extern RECT DRAW_rcClient;
extern POINT MAP_ptLocation[2][MAP_LOCATION_MAX];
//////////////////
// 拷贝游戏背景面到地形背景面
// prcCut : 剪裁的范围,如果为NULL,则拷贝整个战场的区域
extern void DRAW_DrawBack2BkGround( CONST RECT *prcCut = NULL );
// 拷贝地形背景面到游戏背景面
// prcCut : 剪裁的范围,如果为NULL,则拷贝整个战场的区域
extern void DRAW_DrawBkGround2Back( CONST RECT *prcCut = NULL );
// draw one ground item
// 显示地形一个图素
// prcCut : 只更新此矩形区内的图像
// k,i,j : 图素的层号,行号,列号
// bFront : 是否直接更新到显示屏幕
extern void DRAW_DrawSingleG( CONST RECT *prcCut, int k, int i, int j, BOOL bFront );
//////////////////
//////////////////
// 显示一个,被DRAW_DrawOthers()调用
void DRAW_DrawOtherSingleBMP( CONST RECT* prcCut, int nIndex );
// 显示一个,被DRAW_DrawOthers()调用
void DRAW_DrawOtherSingleCOM( CONST RECT* prcCut, int nIndex );
//////////////////
//////////////////
// draw other maps
// prcCut : 剪切的矩形
// nFile : OTHER图素的文件号
// nFrame : 当前帧
// nZ,nX,nY : 格子坐标
void DRAW_OTHER_Draw( const RECT *prcCut, int nFile, int nFrame, int nZ, int nX, int nY )
{
RECT rect;
RECT rcCutS, rcCutSOld;
rcCutSOld = MAP_GetOtherRect( DRAW_ptScreenOffset, nZ, nX, nY, nFile );
if( IntersectRect( &rcCutS, &rcCutSOld, prcCut ) )
{
POINT ptTLOff, ptRBOff;
ptTLOff.x = rcCutSOld.left - rcCutS.left;
ptTLOff.y = rcCutSOld.top - rcCutS.top;
ptRBOff.x = rcCutSOld.right - rcCutS.right;
ptRBOff.y = rcCutSOld.bottom - rcCutS.bottom;
// calc source position and size
rect.left = 0-ptTLOff.x;
rect.right = (rcCutSOld.right - rcCutSOld.left) - ptRBOff.x;
rect.top = nFrame*(rcCutSOld.bottom - rcCutSOld.top) - ptTLOff.y;
rect.bottom = (nFrame+1)*(rcCutSOld.bottom - rcCutSOld.top) - ptRBOff.y;
// draw
POINT ptDest;
ptDest.x = rcCutS.left, ptDest.y = rcCutS.top;
DRAW_sOtherMap[nFile].BltToBack( ptDest, &rect );
}
}
//////////////////
//////////////////
// 当资源状态改变时(被砍伐,收割后),要更新该区域
#define MAP_OTHER_MAX 13
POINT MAP_ptSpecial[2][MAP_OTHER_MAX]=
{
{{0,-4},{-1,-3},{0,-3},{0,-2},{-1,-1},{0,-1},
{0,0},
{-1,1},{0,1},{0,2},{-1,3},{0,3},{0,4}
},
{{0,-4},{0,-3},{1,-3},{0,-2},{0,-1},{1,-1},
{0,0},
{0,1},{1,1},{0,2},{0,3},{1,3},{0,4}
}
}; // 单元所占地图位置数组(偶数)
// prcCut : 剪切的矩形
// nFile : OTHER图素的文件号
// nFrame : 当前帧
// nZ,nX,nY : 格子坐标
inline void DRAW_OTHER_UpdateResource( int nZ, int nX, int nY )
{
int bOdd = nY&1;
int nXNext, nYNext;
WORD codeG;
struct MAP_GROUND_CODE_STRUCT stctG;
int nA, nB, nC;
RECT rcCutS, rcCutSOld;
rcCutSOld = MAP_GetOtherRect( DRAW_ptScreenOffset, nZ, nX, nY, 7 );
if( IntersectRect( &rcCutS, &rcCutSOld, &DRAW_rcClient ) )
{ // 以自己的矩形和屏幕举行的交集为新的剪切矩形
// 更新到地形图素背景面上
DRAW_DrawBkGround2Back( &rcCutS );
// 画到背景面上
for( int i=0; i<13; i++ )
{
nXNext = nX + MAP_ptSpecial[bOdd][i].x;
nYNext = nY + MAP_ptSpecial[bOdd][i].y;
codeG = MAP_GetGroundData( nZ, nXNext, nYNext );
if( codeG == MAP_DATA_NONE ) continue;
MAP_GroundDeCode( codeG, &stctG );
DRAW_DrawSingleG( &rcCutS, nZ, nXNext, nYNext, FALSE );
if( stctG.nAttr != MAP_SPECIAL_NONE )
{
nA = stctG.nAttr%4;
nB = stctG.nAttr/4;
nC = 0;
if( nB == 2 ) nC = 1;
DRAW_OTHER_Draw( &rcCutS, 7, (nA<<1)+nC, nZ, nXNext, nYNext );
}
}
// 更新到地形图素背景面上
DRAW_DrawBack2BkGround( &rcCutS );
// DDC_FrameRect( &rcCutS, RGB(255,0,0), TRUE );
}
}
//////////////////
/////////////////////
inline void DRAW_DrawOtherSingleBMP( CONST RECT* prcCut, int nIndex )
{
// get update region
RECT rcCutGOld, rcCutG;
RECT rect;
POINT ptDest;
rcCutGOld = OTHER_GetRect( DRAW_ptScreenOffset, nIndex );
/*
Find a bug here, OTHER_GetRect() do not detect if the parameters are out of range
FILE *fp = fopen( "debug.lst", "at" );
fprintf( fp, "%d: %d,%d,%d,%d\n", nIndex, rcCutGOld.left,
rcCutGOld.top, rcCutGOld.right,
rcCutGOld.bottom );
fclose( fp );
*/
// test if needn't draw, outside client area
if( !IntersectRect( &rcCutG, &rcCutGOld, prcCut ) ) return;
// calc destination position
ptDest.x = rcCutG.left, ptDest.y = rcCutG.top;
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 = 0-ptTLOff.x;
rect.right = (rcCutGOld.right - rcCutGOld.left) - ptRBOff.x;
rect.top = OTHER[nIndex].nCol[OTHER[nIndex].nFrame]*(rcCutGOld.bottom - rcCutGOld.top) - ptTLOff.y;
rect.bottom = (OTHER[nIndex].nCol[OTHER[nIndex].nFrame]+1)*(rcCutGOld.bottom - rcCutGOld.top) - ptRBOff.y;
/*
{
FILE *fp = fopen( "debug.lst", "at" );
fprintf( fp, "Enter DDD\n" );
fclose( fp );
}
*/
DRAW_sOtherMap[OTHER[nIndex].nFile].BltToBack( ptDest, &rect );
/*
{
FILE *fp = fopen( "debug.lst", "at" );
fprintf( fp, "Leave DDD\n" );
fclose( fp );
}
*/
}
/////////////////////
/////////////////////
inline void DRAW_DrawOtherSingleCOM( CONST RECT* prcCut, int nIndex )
{
// get update region
RECT rcCutGOld, rcCutG;
RECT rcOff;
POINT ptDest;
rcCutGOld = OTHER_GetRect( DRAW_ptScreenOffset, nIndex );
// test if needn't draw, outside client area
if( !IntersectRect( &rcCutG, &rcCutGOld, prcCut ) ) return;
// 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;
// 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 );
int widthDest = 0;
DRAW_sMMX.Erase();
if( pSurDest->Lock( NULL, &ddsdDest, DDLOCK_WAIT, NULL ) == DD_OK )
{
DRAW_ImageLib.P_imageDirect(ptDestMMX.x, ptDestMMX.y, ddsdDest.dwWidth,
(char*)ddsdDest.lpSurface,
0, OTHER[nIndex].nCol[OTHER[nIndex].nFrame] );
pSurDest->Unlock( NULL );
}
DRAW_sMMX.BltToBack( ptDest, &rcSrcMMX );
}
else
{
LPDIRECTDRAWSURFACE2 pSurDest = DD_GetBackBuffer();
DDSURFACEDESC ddsdDest;
ddsdDest.dwSize = sizeof( ddsdDest );
int widthDest = 0;
if( pSurDest->Lock( NULL, &ddsdDest, DDLOCK_WAIT, NULL ) == DD_OK )
{
DRAW_ImageLib.P_imageDirect(ptDest.x, ptDest.y, ddsdDest.dwWidth,
(char*)ddsdDest.lpSurface,
0, OTHER[nIndex].nCol[OTHER[nIndex].nFrame] );
pSurDest->Unlock( NULL );
}
}
}
void DRAW_DrawOthersCOM( int nType )
{
// int nCounter = 0;
for(int i=0; i< OTHER_MAX; i++ )
{
if( OTHER[i].nType == nType )
{ // draw single
DRAW_DrawOtherSingleCOM( &DRAW_rcClient, i );
OTHER_Move( i ); // run once a time
// nCounter++;
// if( nCounter == OTHER_nCounter ) break;
}
}
}
void DRAW_DrawOthersBMP( int nType )
{
int nCounter = 0;
for(int i=0; i< OTHER_MAX; i++ )
{
if( OTHER[i].nType >= nType )
{ // draw single
DRAW_DrawOtherSingleBMP( &DRAW_rcClient, i );
OTHER_Move( i ); // run once a time
nCounter++;
//if( nCounter == OTHER_nCounter ) break;
}
}
}
extern int DRAW_OTHER_nMouseID; // declared in CBDraw.cpp
void DRAW_DrawOthersMouse()
{
if( DRAW_OTHER_nMouseID < 0 )
return;
DRAW_DrawOtherSingleBMP( &DRAW_rcClient, DRAW_OTHER_nMouseID );
if( OTHER_Move( DRAW_OTHER_nMouseID ) == TRUE )
{
DRAW_OTHER_nMouseID = -1; // 结束清除
}
}
/////////////////////
/////////////////////
// 显示计谋提示图标(血点)
// pUnit : 被显示的单元
// pRect : 该单元的矩形大小
// prcCut : 剪切的范围
void DRAW_Draw8x8( struct UNIT_STRUCT *pUnit, CONST RECT *pRect, CONST RECT *prcCut )
{
RECT rcCutG, rcSrc, rcDest;
POINT ptDest;
int nWidth = 10, nHeight = 10, nFile = 11;
int nJCounter = 0;
int nJs[8]={-1,-1,-1,-1,-1,-1,-1,-1};
int i;
//CTRL_JIMOU_MAX
for( i=0; i<8; i++ )
{
if( CTRL_GetSTG( &pUnit->Draw, CTRL_JIMOU( i ) ) == TRUE )
{
nJs[nJCounter] = i;
nJCounter++;
}
}
if( nJCounter == 0 ) return; // 没有计谋
for( i=0; i<nJCounter; i++ )
{
ptDest.x = pRect->left + ((pRect->right - pRect->left - nWidth*nJCounter)>>1)+nWidth*i;
ptDest.y = pRect->top;
rcDest.left = ptDest.x, rcDest.top = ptDest.y;
rcDest.right = ptDest.x + nWidth;
rcDest.bottom = ptDest.y + nHeight;
if( IntersectRect( &rcCutG, &rcDest, prcCut ) == FALSE )
return; // 不在屏幕(剪切的范围)内
// calc destination position
ptDest.x = rcCutG.left, ptDest.y = rcCutG.top;
// calc offset
POINT ptTLOff, ptRBOff;
ptTLOff.x = rcDest.left - rcCutG.left;
ptTLOff.y = rcDest.top - rcCutG.top;
ptRBOff.x = rcDest.right - rcCutG.right;
ptRBOff.y = rcDest.bottom - rcCutG.bottom;
// calc source position and size
rcSrc.left = 0-ptTLOff.x;
rcSrc.right = nWidth - ptRBOff.x;
rcSrc.top = nJs[i]*nHeight - ptTLOff.y;
rcSrc.bottom = (nJs[i]+1)*nHeight - ptRBOff.y;
DRAW_sOtherMap[nFile].BltToBack( ptDest, &rcSrc );
}
}
/////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -