?? cbbuild.cpp
字號:
/////////////
// CBBuild.cpp : v0011
// Written by : Liu Gang
// Compiler : Microsoft Visual C++ 4.0 & DirectX
// Library : DDraw.Lib
// Copyright (C) : 1996 WayAhead Corporation
// v0010 : Mar.7.1997
// v0011 : Mar.28.1997, changed BUILD_sBorder to BUILD_ptBorder
/////////////
// implementation file
// display build maps when placing buildings
// 當建造建筑時,點擊一個建筑按鈕后,鼠標變成一個建筑的影象,
// 隨著鼠標移動,戰場上能夠建造建筑的地方(格子)為綠色網格覆蓋,
// 不能建造的地方為紅色網格覆蓋,本文件就是顯示這個部分。
#include "stdafx.h"
#include "Assert.h"
#include "CBBuild.h"
#include "DDCompo.h"
#include "CBMAP.h"
#include "CBMouse.h"
#include "CBDraw.h"
#include<stdio.h>
/////////////
// members, globals
BOOL BUILD_bEnable = FALSE;
class CDDSurface BUILD_sBack, *BUILD_psBorder;
BOOL BUILD_bCreated = FALSE;
SIZE BUILD_szBack = {144, 120}; // 背景面的大小
SIZE BUILD_szItem = {0, 0}; // 圖素的大小
SIZE BUILD_szBorder = {0, 0}; // 圖素邊界的大小
int BUILD_nSize=0; // 圖素的大小類型
int BUILD_nLocationNum[4] = { 1, 4, 9, 16 };
/////////////
//////////////////
// other map surfaces, in CBDraw.cpp
extern class CDDSurface DRAW_sOtherMap[MAP_OTHER_NUM];
//////////////////
/////////////
DWORD BUILD_nCode;
BOOL BUILD_bLocation[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
/////////////
//---------------LWC
#ifdef _MAP_COMPRESS_
#include "L_image.h"
extern class CPicture_image DRAW_ImageLib; // CBDraw.cpp
extern RECT DRAW_rcClient; // CBDraw.cpp
extern POINT MAP_ptLocation[2][MAP_LOCATION_MAX]; // CBMap.cpp
#endif
//---------------LWC
/////////////
// declared in CBDraw.cpp
extern POINT DRAW_ptScreenOffset;
/////////////
void BUILD_draw2Back( LPRECT prcCut, int nLayer, POINT ptPosG, BOOL bFront = FALSE );
void BUILD_drawBorders( LPRECT prcCut, POINT ptPosG );
void BUILD_drawBorder( LPRECT prcCut, int nLayer, POINT ptTopLeftG, int nType );
/////////////
BOOL BUILD_Load()
{
#ifdef _DEBUG
if( BUILD_bCreated )
{
ErrorMessage( hwndGame, BUILD_ERROR_ID+0, "Shadow surfaces have been created!" );
return FALSE;
}
#endif
// has color key , in system memory
if( !BUILD_sBack.Create( BUILD_szBack.cx, BUILD_szBack.cy, TRUE, FALSE ) )
{
// OutputDebugString( "BUILD_Load: Cannot create back surface in video memory!\n" );
// if( !BUILD_sBack.Create( BUILD_szBack.cx, BUILD_szBack.cy, TRUE, FALSE ) )
{
ErrorMessage( hwndGame, BUILD_ERROR_ID+1, "Cannot create build background surface!" );
return FALSE;
}
}
// load shadow source image file
// color key, system memory
//if( !BUILD_sBorder.LoadBitmap( filename, TRUE, FALSE ) )
BUILD_psBorder = &DRAW_sOtherMap[5];
if( BUILD_psBorder == NULL || BUILD_psBorder->GetSurface() == NULL )
{
ErrorMessage( hwndGame, BUILD_ERROR_ID+2, "Cannot create build border surface!" );
return FALSE;
}
BUILD_bCreated = TRUE;
return TRUE;
}
void BUILD_Release()
{
#ifdef _DEBUG
if( !BUILD_bCreated )
{
ErrorMessage( hwndGame, BUILD_ERROR_ID+10, "Try to release build surfaces before load them!" );
return;
}
#endif
BUILD_sBack.Release();
//BUILD_sBorder.Release();
BUILD_bCreated = FALSE;
}
/////////////
/////////////
// 把建筑的影像貼到建造背景面中
void BUILD_Set( DWORD codeU )
{
#ifdef _DEBUG
if( BUILD_bCreated == FALSE )
OutputDebugString( "BUILD_Set Error(0): the surfaces have not been created!\n" );
if( codeU == MAP_DATA_NONE )
OutputDebugString( "BUILD_Set Error(0): code is invalid!\n" );
#endif
struct MAP_UNIT_CODE_STRUCT stctU;
MAP_UnitDeCode( codeU, &stctU );
BUILD_nCode = codeU;
// set size
BUILD_nSize = MAP_Lib.Unit[stctU.nFile].nLocationSize;
int nFrame = MAP_Lib.AniSeq[stctU.nFile].nOffset;
// set size of item
BUILD_szItem = MAP_Lib.Unit[stctU.nFile].szItem;
// calc border size
BUILD_szBorder.cx = (BUILD_nSize+1)*MAP_Lib.szItem.cx;
BUILD_szBorder.cy = (BUILD_nSize+1)*MAP_Lib.szItem.cy;
// clear the background surface
BUILD_sBack.Erase();
LPDIRECTDRAWSURFACE2 pSurDest = BUILD_sBack.GetSurface();
DDSURFACEDESC ddsdDest;
ddsdDest.dwSize = sizeof( ddsdDest );
// 注意:這里有一個容易引起錯誤的地方:
// P_image()的第三個參數,不應該是ddsdDest.dwWidth,而應該是
// ddsdDest.lPitch,這是指指針換行所應跳過的距離
// 在很多情況下,這兩個值是相等,而在這里第一次貼圖時不是。
if( pSurDest->Lock( NULL, &ddsdDest, DDLOCK_WAIT, NULL ) == DD_OK )
{
DRAW_ImageLib.P_image(0, 0, ddsdDest.lPitch,
(char*)ddsdDest.lpSurface,
0, nFrame );
pSurDest->Unlock( NULL );
}
}
void BUILD_draw2Back( LPRECT prcCut, int nLayer, POINT ptPosG, BOOL bFront )
{
POINT ptPos;
RECT rcCutOld, rcCut;
POINT ptTopLeft;
POINT ptDest;
RECT rcSrc;
#ifdef _DEBUG
if( BUILD_bCreated == FALSE )
OutputDebugString( "BUILD_Set Error(0): the surfaces have not been created!\n" );
#endif
// change grid to point
ptPos = MOUSE_Grid2Point( nLayer, ptPosG );
// get origenal destination rectangle on screen
ptTopLeft.x = ptPos.x - (BUILD_szItem.cx>>1);
ptTopLeft.y = ptPos.y + (MAP_Lib.szItem.cy>>1) - BUILD_szItem.cy;
SetRect( &rcCutOld, ptTopLeft.x, ptTopLeft.y,
ptTopLeft.x+BUILD_szItem.cx, ptTopLeft.y+BUILD_szItem.cy );
if( !IntersectRect( &rcCut, &rcCutOld, prcCut ) )
return;
// calc positions
ptDest.x = rcCut.left, ptDest.y = rcCut.top;
rcSrc.left = rcCut.left - rcCutOld.left;
rcSrc.top = rcCut.top - rcCutOld.top;
rcSrc.right = BUILD_szItem.cx - (rcCutOld.right - rcCut.right);
rcSrc.bottom = BUILD_szItem.cy - (rcCutOld.bottom - rcCut.bottom);
// draw to back
BUILD_sBack.BltToBack( ptDest, &rcSrc );
// draw from back buffer to front buffer
if( bFront )
DDC_UpdateScreen( prcCut );
}
void BUILD_drawBorder( LPRECT prcCut, POINT ptTopLeft, int nType )
{
RECT rcCutGOld, rcCutG;
POINT ptDest;
RECT rcSrc;
SetRect( &rcCutGOld, ptTopLeft.x, ptTopLeft.y,
ptTopLeft.x+MAP_Lib.szItem.cx, ptTopLeft.y+MAP_Lib.szItem.cy );
if( !IntersectRect( &rcCutG, &rcCutGOld, prcCut ) )
return;
ptDest.x = rcCutG.left, ptDest.y = rcCutG.top;
rcSrc.left = rcCutG.left - rcCutGOld.left;
rcSrc.top = rcCutG.top - rcCutGOld.top + nType*MAP_Lib.szItem.cy;
rcSrc.right = MAP_Lib.szItem.cx + ( rcCutG.right - rcCutGOld.right );
rcSrc.bottom = MAP_Lib.szItem.cy + ( rcCutG.bottom - rcCutGOld.bottom )
+ nType*MAP_Lib.szItem.cy;
//BUILD_sBorder.BltToBack( ptDest, &rcSrc );
BUILD_psBorder->BltToBack( ptDest, &rcSrc );
}
void BUILD_drawBorders( LPRECT prcCut, int nLayer, POINT ptPosG )
{
POINT ptTopLeft, ptPosGNext;
int bOdd = ptPosG.y%2;
for( int i=0; i< BUILD_nLocationNum[BUILD_nSize]; i++ )
{
// get positions in this location
ptPosGNext.x = ptPosG.x + MAP_ptLocation[bOdd][i].x;
ptPosGNext.y = ptPosG.y + MAP_ptLocation[bOdd][i].y;
// change grid to point
ptTopLeft = MOUSE_Grid2Point( nLayer, ptPosGNext );
ptTopLeft.x -= MAP_Lib.szItem.cx>>1;
ptTopLeft.y -= MAP_Lib.szItem.cy>>1;
if( BUILD_bLocation[i] == MAP_REGION_SUCCESS )
{
BUILD_drawBorder( prcCut, ptTopLeft, 1 );
}
else
{
BUILD_drawBorder( prcCut, ptTopLeft, 0 );
}
}
}
void BUILD_Enable( BOOL bEnable/* = TRUE*/ )
{
BUILD_bEnable = bEnable;
}
inline BOOL BUILD_IfEnable()
{
return BUILD_bEnable;
}
void BUILD_Draw( LPRECT prcCut/*=NULL*/ )
{
POINT ptPos, ptPosG;
if( !BUILD_bEnable ) return;
// get mouse cursor position
GetCursorPos( &ptPos );
// change positoin to grids
struct MOUSE_HITRESULT_STRUCT hit;
if( !MOUSE_HitTestG( ptPos, &hit, 0 ) ) return;
Assert( hit.nType == MOUSE_HITRESULT_GROUND );
ptPosG = hit.ptHit;
// draw building image to back buffer
BUILD_draw2Back( prcCut, 0, ptPosG );
// draw border indicate can build or not
// calc points
MAP_TestRegionBuild( 0, ptPosG, BUILD_nCode, BUILD_bLocation, BUILD_nLocationNum[BUILD_nSize] );
// draw
BUILD_drawBorders( prcCut, 0, ptPosG );
}
int BUILD_IfCan()
{
if( !BUILD_bEnable )
{
OutputDebugString( "CBBuild BUILD_IfCan() Warning(1): test build result before set it!\n" );
return FALSE;
}
for( int i=0; i<BUILD_nLocationNum[BUILD_nSize]; i++ )
{
if( BUILD_bLocation[i] != MAP_REGION_SUCCESS )
return BUILD_bLocation[i];
}
return MAP_REGION_SUCCESS;
}
/////////////
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -