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

📄 cbdrawot.cpp

📁 网页游戏赤壁
💻 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 + -