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

📄 cbmini.cpp

📁 网页游戏赤壁
💻 CPP
字号:
/////////////////
// CBMini.cpp	:	《赤壁》缩略图
// v0010		:	Jan.31.1997
// v0011		:	May.5.1997, add blinking on the map, add size of each unit
// written by	:	Liu Gang
// Compiler		:	Visual C++ 4.2 & DirectX
// Library		:	DDraw.lib
// Copyright	:	WayAhead Software Co.Ltd.	1996-1997
/////////////////
// 此文件包含所有对缩略图的操作

#include "stdafx.h"
#include "Assert.h"
#include "DDCompo.h"

#include "CBMini.h"
#include "CBMap.h"
#include "CBShadow.h"


/////////////////
// globals
// 地形图素数据数组
//extern WORD MAP_wGroundData[MAP_DATA_THICK][MAP_DATA_WIDTH][MAP_DATA_HEIGHT];
// 区域数据数组
//extern WORD MAP_wRegionData[MAP_DATA_WIDTH][MAP_DATA_HEIGHT];
// 战场窗口
extern RECT DRAW_rcScreen;		// defined in CBDraw.cpp

// Location Number
extern int MAP_nLocationNum[4];	// defined in CBMap.cpp
/////////////////

/////////////////
// internal variables
struct MAP_MINI_LIB_STRUCT MINI_Lib;	// 缩略图结构

// 缩略图的显示面
class CDDSurface	MINI_sMap;	// surface to display minimap

// 保存背景地图的缓冲区
BYTE *MINI_pBuffer;				// buffer for storing ground map

// 显示面的大小
int MINI_nWidth;
int MINI_nHeight;
int MINI_nBuffSize;

// 闪烁用数组
#define	MINI_BLINK_MAX		10
POINT MINI_ptBlink[MINI_BLINK_MAX];
void MINI_DrawBlink( int nCol, int nRow, int nColor );	// 显示闪烁效果,在MINI_Update()
/////////////////

/////////////////
// create mini map surface and buffer
// must read med file first
// 必须在打开战场图后使用,GAME_ReadMedfile()
// return :	TRUE if succeeded
BOOL MINI_Load()
{
	// test if has loaded before
	// test if has loaded before
	if( MINI_Lib.nType != -1 )
	{
		ErrorMessage( hwndGame, MINI_ERROR_ID+0, "Mini map has been created!" );
		OutputDebugString( "MINI_Load Error(0): Mini map has been created!\n" );
		return FALSE;	
	}

	// set mini map type
	switch( MAP_Lib.szNum.cx )
	{
	case	90:
		MINI_Lib.nType = 0;
		break;
	case	105:
		MINI_Lib.nType = 1;
		break;
	case	120:
		MINI_Lib.nType = 2;
		break;
	}


	// if do not read mini map data file yet
	if( MINI_Lib.nType == -1 )
	{
		ErrorMessage( hwndGame, MINI_ERROR_ID+1, "Load Minimap before load battle field!" );
		OutputDebugString( "MINI_Load Error(1): Load Minimap before load battle field!\n" );
		return FALSE;	
	}

	// create minimap surface
	// no color key, in system memory
	MINI_nWidth = MINI_Lib.rcMap[MINI_Lib.nType].right - 
					MINI_Lib.rcMap[MINI_Lib.nType].left;
	MINI_nHeight = MINI_Lib.rcMap[MINI_Lib.nType].bottom - 
					MINI_Lib.rcMap[MINI_Lib.nType].top;
	if( !MINI_sMap.Create( MINI_nWidth, MINI_nHeight, FALSE, FALSE ) )
	{
		ErrorMessage( hwndGame, MINI_ERROR_ID+2, "Cannot create minimap surface!" );
		OutputDebugString( "MINI_Load Error(2): Cannot create minimap surface!\n" );
		return FALSE;	
	}

	MINI_sMap.Erase( 0 );

	// create buffer
	MINI_nBuffSize = MINI_nWidth*MINI_nHeight;
	MINI_pBuffer = (BYTE*)malloc( MINI_nBuffSize );
	if( !MINI_pBuffer )
	{
		ErrorMessage( hwndGame, MINI_ERROR_ID+3, "Cannot create minimap buffer!" );
		OutputDebugString( "MINI_Load Error(3): Cannot create minimap buffer!\n" );
		return FALSE;	
	}
	memset( MINI_pBuffer, 0, MINI_nBuffSize );

// initialize blink point array
	memset( MINI_ptBlink, 0, sizeof( POINT )*MINI_BLINK_MAX );

	return TRUE;
}

// release minimap surface and buffer
void MINI_Release()
{
	if( MINI_Lib.nType == -1 )
	{
		ErrorMessage( hwndGame, MINI_ERROR_ID+10, "Try to release minimap surface before load it!" );
		OutputDebugString( "MINI_Load Error(10): Try to release minimap surface before load it!\n" );
		return ;
	}

	MINI_sMap.Release();

	//GlobalFree( MINI_pBuffer );
	free( MINI_pBuffer );
	MINI_pBuffer = NULL;

	DD_EraseBackScreen( 1, &MINI_Lib.rcMap[2] );
	DDC_UpdateScreen( &MINI_Lib.rcMap[2] );

	MINI_Lib.nType = -1;
}

POINT ptLocation[16]={
	{0,0},{1,0},{0,-1},{1,-1},
	{-1,0},{-1,-1},{-1,-2},{0,-2},
	{1,-2},{-2,0},{-2,-1},{-2,-2},
	{-2,-3},{-1,-3},{0,-3},{1,-3}};

// set unit data to buffer
void MINI_SetUnitData( int nCol, int nRow, int nType, int nLocationSize )
{
	int nBase = 15;
	int nX, nY;
	int nOffset;
	BYTE *pBuffer=NULL;
	if( SHADOW_IfBlanked( nCol, nRow ) != 0 )
		return;	// 被任何阴影遮挡则不画
		
	for( int x=0; x<MAP_nLocationNum[nLocationSize]; x++ )
	{
		nX = nCol+ptLocation[x].x, nY = nRow+ptLocation[x].y;
		nOffset = MINI_nWidth*(nY>>2)+nX;
		if( nOffset < 0 || nOffset > MINI_nBuffSize )
			continue;	// 出界
		pBuffer = MINI_pBuffer+nOffset;
		*pBuffer=(BYTE)MINI_Lib.nColorTable[nBase+nType];
	}
}

// set ground data to buffer
void MINI_SetGroundData( int nCol, int nRow, int nLocationSize )
{
	int nX, nY;
	int nOffset;
	BYTE *pBuffer=NULL;

	if( SHADOW_IfBlanked( nCol, nRow ) == MAP_SHADOW_NONE )
		return;	// 被实心阴影遮挡则不画
	
	for( int x=0; x<MAP_nLocationNum[nLocationSize]; x++ )
	{
		nX = nCol+ptLocation[x].x, nY = nRow+ptLocation[x].y;
		for( int i=MAP_DATA_THICK-1; i>=0; i-- )
		{
			WORD codeG = MAP_GetGroundData( i, nX, nY );
			if( codeG != MAP_DATA_NONE )
			{
				nOffset = MINI_nWidth*(nY>>2)+nX;
			if( nOffset < 0 || nOffset > MINI_nBuffSize )
				continue;	// 出界
				pBuffer = MINI_pBuffer+nOffset;
				struct MAP_GROUND_CODE_STRUCT stctG;
				MAP_GroundDeCode( codeG, &stctG );
				if( stctG.nAttr == 0 || stctG.nAttr == 1 )
				{
					*pBuffer=(BYTE)MINI_Lib.nColorTable[13+stctG.nAttr]; 
				}
				else if( stctG.nFile == 3 && stctG.nCol == 13 )
				{
					*pBuffer=(BYTE)MINI_Lib.nColorTable[0];	// special condition, in water range but it is land
				}
				else
				{
					*pBuffer=(BYTE)MINI_Lib.nColorTable[stctG.nFile];
				}
				break;
			}
		}
	}
}


// draw all the items on the battlefield to buffer
// bDraw	:	TRUE if Draw data from ground data to buffer
//				else erase buffer with black
void MINI_DrawAll( BOOL bDraw /*= TRUE */)
{
	// 必须在给MINI_pBuffer申请内存后使用
#ifdef	_DEBUG
	if( !MINI_pBuffer )
	{
		ErrorMessage( hwndGame, MINI_ERROR_ID+10, "Try to read map data before create buffer surface!" );
		return;
	}
#endif // _DEBUG
	int i,j,k;

	if( bDraw )
	{	// draw
		memset( MINI_pBuffer, 0, MINI_nBuffSize );
	
		// draw ground
		int nHeight = MINI_nHeight<<2;
		BYTE *pBuffer = (BYTE*)MINI_pBuffer;
		for( j=0; j<nHeight; j+=4 )
		for( k=0; k<MINI_nWidth; k++ )
		{
			int ret = SHADOW_IfBlanked( k, j );
			if( ret != MAP_SHADOW_NONE )//|| (ret==1 && (k&1)==0 && (j&7)==0) )
			{
				for( i=MAP_DATA_THICK-1; i>=0; i-- )
				{
					WORD codeG = MAP_GetGroundData( i, k, j );
					if( codeG != MAP_DATA_NONE )
					{	// 没有被实心阴影所遮挡
						struct MAP_GROUND_CODE_STRUCT stctG;
						MAP_GroundDeCode( codeG, &stctG );
						if( stctG.nAttr == 0 || stctG.nAttr == 1 )
						{
							*pBuffer=(BYTE)MINI_Lib.nColorTable[13+stctG.nAttr];
						}
						else if( stctG.nFile == 3 && stctG.nCol == 13 )
						{
							*pBuffer=(BYTE)MINI_Lib.nColorTable[0];	// special condition, in water range but it is land
						}
						else
						{
							*pBuffer=(BYTE)MINI_Lib.nColorTable[stctG.nFile];
						}
						break;
					}
				}
			}
			pBuffer++;
		}

		// draw unit
		for( i=0; i<GAME_PLAYER_MAX; i++ )
		{
			int nCounter = 0;
			for( j=0; j<PLAYER_UNIT_MAX; j++ )
			{
				struct UNIT_STRUCT *pUnit = &GAME.Players[i].Unit[j];
				if( pUnit->nType != MAP_UNIT_TYPE_NONE )
				{
					MINI_SetUnitData( pUnit->Draw.nX, pUnit->Draw.nY,
						pUnit->Draw.nPlayer, pUnit->Draw.nLocationSize );
				}
			}
		}
	}
	else	// erase
	{
		int nHeight = MINI_nHeight<<2;
		BYTE *pBuffer = (BYTE*)MINI_pBuffer;
		for( int j=0; j<nHeight; j+=4 )
		for( int k=0; k<MINI_nWidth; k++ )
		{
			WORD codeR = MAP_GetRegionData( k, j );
			struct MAP_REGION_CODE_STRUCT stctR;
			MAP_RegionDeCode( codeR, &stctR );
			if( stctR.nShadow == MAP_SHADOW_NONE )
				*pBuffer=0;
			pBuffer++;
		}
	}
}	// end of MINI_DrawAll()

// July 23, 1997
// draw from mini surface to back buffer , and to front buffer
// bFront	:	1 for draw to front buffer, 
//				2 for only update to front buffer
//				0 for do not draw to front buffer
// bClearBlink	:	TRUE if should erase blink point array right after drawing blink
void MINI_Update( BOOL bFront/* = TRUE*/, BOOL bClearBlink/* = TRUE*/ )
{

	// draw to front
	// July 23, 1997
	if( bFront == 2 )
	{
		RECT rcScreen;
		SetRect( &rcScreen, 
			DRAW_rcScreen.left, DRAW_rcScreen.top>>2,
			DRAW_rcScreen.right, DRAW_rcScreen.bottom>>2 );
		OffsetRect( &rcScreen, 
			MINI_Lib.rcMap[MINI_Lib.nType].left, 
			MINI_Lib.rcMap[MINI_Lib.nType].top );
		DDC_FrameRect( &rcScreen, RGB(240,240,240) );
		DDC_UpdateScreen( &MINI_Lib.rcMap[MINI_Lib.nType] );
		return;
	}

	// copy buffer
	DDSURFACEDESC       ddsd;
	ddsd.dwSize = sizeof( ddsd );
	if( MINI_sMap.GetSurface()->Lock( NULL, &ddsd, DDLOCK_WAIT, NULL ) == DD_OK )
	{
		memcpy( ddsd.lpSurface, MINI_pBuffer, ddsd.dwWidth*ddsd.dwHeight );
		MINI_sMap.GetSurface()->Unlock( NULL );
	}

	// draw screen rectangle
	if( bFront == 1 )
	{
		RECT rcScreen;
		SetRect( &rcScreen, 
			DRAW_rcScreen.left, DRAW_rcScreen.top>>2,
			DRAW_rcScreen.right, DRAW_rcScreen.bottom>>2 );
		DDC_FrameRect( MINI_sMap.GetSurface(), &rcScreen, RGB(240,240,240) );
	}
	// draw blinking crosses
	static int nC=0;
	int arColor[2]={83, 95};
	nC = (nC+1)%2;
	for( int i=0; i<MINI_BLINK_MAX; i++ )
	{
		if( MINI_ptBlink[i].x != 0 && MINI_ptBlink[i].y != 0 )
		{
			MINI_DrawBlink( MINI_ptBlink[i].x, MINI_ptBlink[i].y, arColor[nC] );
		}
	}
	if( bClearBlink )
	{
		// initialize blink point array
		memset( MINI_ptBlink, 0, sizeof( POINT )*MINI_BLINK_MAX );
	}

	// draw to back
	POINT ptDest;
	RECT rcSrc;
	ptDest.x = MINI_Lib.rcMap[MINI_Lib.nType].left;
	ptDest.y = MINI_Lib.rcMap[MINI_Lib.nType].top;
	rcSrc.left = rcSrc.top = 0;
	rcSrc.right = MINI_Lib.rcMap[MINI_Lib.nType].right - 
					MINI_Lib.rcMap[MINI_Lib.nType].left;
	rcSrc.bottom = MINI_Lib.rcMap[MINI_Lib.nType].bottom - 
					MINI_Lib.rcMap[MINI_Lib.nType].top;
	MINI_sMap.BltToBack( ptDest, &rcSrc );

	// draw to front
	if( bFront == 1 )
		DDC_UpdateScreen( &MINI_Lib.rcMap[MINI_Lib.nType] );
}

// if there is a war draw blinking cross on the map
void MINI_SetBlink( int nCol, int nRow )
{
	nRow = nRow>>2;
	RECT rect;
	int nRange=4;
	rect.left = nCol-nRange;
	rect.top = nRow-nRange;
	rect.right = nCol+nRange;
	rect.bottom = nRow+nRange;
	for( int i=0; i<MINI_BLINK_MAX; i++ )
	{
//		if( MINI_ptBlink[i].x != nCol
//			|| MINI_ptBlink[i].y != nRow )
//		if( PtInRect( MINI_ptBlink[i], &rect ) )
		if( MINI_ptBlink[i].x >rect.right 
			|| MINI_ptBlink[i].x<=rect.left
			|| MINI_ptBlink[i].y>rect.top
			|| MINI_ptBlink[i].y<=rect.bottom )
		{
			MINI_ptBlink[i].x = nCol;
			MINI_ptBlink[i].y = nRow;
			break;
		}
	}
}

void MINI_DrawBlink( int nCol, int nRow, int nColor )
{
	//int nColor = 88;
	// draw to surface directly
	DDSURFACEDESC       ddsd;
	BYTE *pBuffer = NULL;
	int nOff;
	POINT ptCross[9]={{-2,-2,},{2,-2},{-1,-1},{1,-1},{0,0},{-1,1},{1,1},{-2,2},{2,2}};

	ddsd.dwSize = sizeof( ddsd );
	if( MINI_sMap.GetSurface()->Lock( NULL, &ddsd, DDLOCK_WAIT, NULL ) == DD_OK )
	{
		for( int i=0; i<9; i++ )
		{
			pBuffer = (BYTE*)ddsd.lpSurface;
			nOff = ddsd.lPitch*(nRow+ptCross[i].y)+nCol+ptCross[i].x;
			if( nOff<0 || nOff>=int(ddsd.lPitch*ddsd.dwHeight) )
				continue;
			pBuffer += nOff;
			*pBuffer = nColor;
		}

		MINI_sMap.GetSurface()->Unlock( NULL );
	}

}
/////////////////

⌨️ 快捷键说明

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