1240 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1240 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
**	Command & Conquer Generals Zero Hour(tm)
 | 
						|
**	Copyright 2025 Electronic Arts Inc.
 | 
						|
**
 | 
						|
**	This program is free software: you can redistribute it and/or modify
 | 
						|
**	it under the terms of the GNU General Public License as published by
 | 
						|
**	the Free Software Foundation, either version 3 of the License, or
 | 
						|
**	(at your option) any later version.
 | 
						|
**
 | 
						|
**	This program is distributed in the hope that it will be useful,
 | 
						|
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
**	GNU General Public License for more details.
 | 
						|
**
 | 
						|
**	You should have received a copy of the GNU General Public License
 | 
						|
**	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
						|
*/
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////
 | 
						|
//																																						//
 | 
						|
//  (c) 2001-2003 Electronic Arts Inc.																				//
 | 
						|
//																																						//
 | 
						|
////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
// MessageStream.cpp
 | 
						|
// Implementation of the message stream
 | 
						|
// Author: Michael S. Booth, February 2001
 | 
						|
 | 
						|
#include "PreRTS.h"	// This must go first in EVERY cpp file int the GameEngine
 | 
						|
 | 
						|
#include "Common/MessageStream.h"
 | 
						|
#include "Common/Player.h"
 | 
						|
#include "Common/PlayerList.h"
 | 
						|
#include "Common/Recorder.h"
 | 
						|
 | 
						|
#include "GameClient/InGameUI.h"
 | 
						|
#include "GameLogic/GameLogic.h"
 | 
						|
 | 
						|
/// The singleton message stream for messages going to TheGameLogic
 | 
						|
MessageStream *TheMessageStream = NULL;
 | 
						|
CommandList *TheCommandList = NULL;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
#ifdef _INTERNAL
 | 
						|
// for occasional debugging...
 | 
						|
//#pragma optimize("", off)
 | 
						|
//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//------------------------------------------------------------------------------------------------
 | 
						|
// GameMessage
 | 
						|
//
 | 
						|
 | 
						|
/**
 | 
						|
 * Constructor
 | 
						|
 */
 | 
						|
GameMessage::GameMessage( GameMessage::Type type ) 
 | 
						|
{ 
 | 
						|
	m_playerIndex = ThePlayerList->getLocalPlayer()->getPlayerIndex();
 | 
						|
	m_type = type; 
 | 
						|
	m_argList = NULL;
 | 
						|
	m_argTail = NULL;
 | 
						|
	m_argCount = 0; 
 | 
						|
	m_list = 0; 
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * Destructor
 | 
						|
 */
 | 
						|
GameMessage::~GameMessage( ) 
 | 
						|
{ 
 | 
						|
	// free all arguments
 | 
						|
	GameMessageArgument *arg, *nextArg;
 | 
						|
 | 
						|
	for( arg = m_argList; arg; arg=nextArg )
 | 
						|
	{
 | 
						|
		nextArg = arg->m_next;
 | 
						|
		arg->deleteInstance();
 | 
						|
	}
 | 
						|
 | 
						|
	// detach message from list
 | 
						|
	if (m_list)
 | 
						|
		m_list->removeMessage( this );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Return the given argument union.
 | 
						|
 * @todo This should be a more list-like interface.  Very inefficient.
 | 
						|
 */
 | 
						|
const GameMessageArgumentType *GameMessage::getArgument( Int argIndex ) const
 | 
						|
{
 | 
						|
	static const GameMessageArgumentType junk = { 0 };
 | 
						|
 | 
						|
	int i=0;
 | 
						|
	for( GameMessageArgument *a = m_argList; a; a=a->m_next, i++ )
 | 
						|
		if (i == argIndex)
 | 
						|
			return &a->m_data;
 | 
						|
 | 
						|
	DEBUG_CRASH(("argument not found"));
 | 
						|
	return &junk;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Return the given argument data type
 | 
						|
 */
 | 
						|
GameMessageArgumentDataType GameMessage::getArgumentDataType( Int argIndex )
 | 
						|
{
 | 
						|
	if (argIndex >= m_argCount) {
 | 
						|
		return ARGUMENTDATATYPE_UNKNOWN;
 | 
						|
	}
 | 
						|
	int i=0;
 | 
						|
	for (GameMessageArgument *a = m_argList; a && (i < argIndex); a=a->m_next, ++i );
 | 
						|
 | 
						|
	if (a != NULL)
 | 
						|
	{
 | 
						|
		return a->m_type;
 | 
						|
	}
 | 
						|
	return ARGUMENTDATATYPE_UNKNOWN;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Allocate a new argument, add it to the argument list, and increment the total arg count
 | 
						|
 */
 | 
						|
GameMessageArgument *GameMessage::allocArg( void ) 
 | 
						|
{ 
 | 
						|
	// allocate a new argument
 | 
						|
	GameMessageArgument *arg = newInstance(GameMessageArgument); 
 | 
						|
 | 
						|
	// add to end of argument list
 | 
						|
	if (m_argTail)
 | 
						|
		m_argTail->m_next = arg;
 | 
						|
	else
 | 
						|
	{
 | 
						|
		m_argList = arg;
 | 
						|
		m_argTail = arg;
 | 
						|
	}
 | 
						|
 | 
						|
	arg->m_next = NULL;
 | 
						|
	m_argTail = arg;
 | 
						|
 | 
						|
	m_argCount++;
 | 
						|
 | 
						|
	return arg;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Append an integer argument
 | 
						|
 */
 | 
						|
void GameMessage::appendIntegerArgument( Int arg )
 | 
						|
{
 | 
						|
	GameMessageArgument *a = allocArg();
 | 
						|
	a->m_data.integer = arg;
 | 
						|
	a->m_type = ARGUMENTDATATYPE_INTEGER;
 | 
						|
}
 | 
						|
 | 
						|
void GameMessage::appendRealArgument( Real arg )
 | 
						|
{
 | 
						|
	GameMessageArgument *a = allocArg();
 | 
						|
	a->m_data.real = arg;
 | 
						|
	a->m_type = ARGUMENTDATATYPE_REAL;
 | 
						|
}
 | 
						|
 | 
						|
void GameMessage::appendBooleanArgument( Bool arg )
 | 
						|
{
 | 
						|
	GameMessageArgument *a = allocArg();
 | 
						|
	a->m_data.boolean = arg;
 | 
						|
	a->m_type = ARGUMENTDATATYPE_BOOLEAN;
 | 
						|
}
 | 
						|
 | 
						|
void GameMessage::appendObjectIDArgument( ObjectID arg )
 | 
						|
{
 | 
						|
	GameMessageArgument *a = allocArg();
 | 
						|
	a->m_data.objectID = arg;
 | 
						|
	a->m_type = ARGUMENTDATATYPE_OBJECTID;
 | 
						|
}
 | 
						|
 | 
						|
void GameMessage::appendDrawableIDArgument( DrawableID arg )
 | 
						|
{
 | 
						|
	GameMessageArgument *a = allocArg();
 | 
						|
	a->m_data.drawableID = arg;
 | 
						|
	a->m_type = ARGUMENTDATATYPE_DRAWABLEID;
 | 
						|
}
 | 
						|
 | 
						|
void GameMessage::appendTeamIDArgument( UnsignedInt arg )
 | 
						|
{
 | 
						|
	GameMessageArgument *a = allocArg();
 | 
						|
	a->m_data.teamID = arg;
 | 
						|
	a->m_type = ARGUMENTDATATYPE_TEAMID;
 | 
						|
}
 | 
						|
 | 
						|
void GameMessage::appendLocationArgument( const Coord3D& arg )
 | 
						|
{
 | 
						|
	GameMessageArgument *a = allocArg();
 | 
						|
	a->m_data.location = arg;
 | 
						|
	a->m_type = ARGUMENTDATATYPE_LOCATION;
 | 
						|
}
 | 
						|
 | 
						|
void GameMessage::appendPixelArgument( const ICoord2D& arg )
 | 
						|
{
 | 
						|
	GameMessageArgument *a = allocArg();
 | 
						|
	a->m_data.pixel = arg;
 | 
						|
	a->m_type = ARGUMENTDATATYPE_PIXEL;
 | 
						|
}
 | 
						|
 | 
						|
void GameMessage::appendPixelRegionArgument( const IRegion2D& arg )
 | 
						|
{
 | 
						|
	GameMessageArgument *a = allocArg();
 | 
						|
	a->m_data.pixelRegion = arg;
 | 
						|
	a->m_type = ARGUMENTDATATYPE_PIXELREGION;
 | 
						|
}
 | 
						|
 | 
						|
void GameMessage::appendTimestampArgument( UnsignedInt arg )
 | 
						|
{
 | 
						|
	GameMessageArgument *a = allocArg();
 | 
						|
	a->m_data.timestamp = arg;
 | 
						|
	a->m_type = ARGUMENTDATATYPE_TIMESTAMP;
 | 
						|
}
 | 
						|
 | 
						|
void GameMessage::appendWideCharArgument( const WideChar& arg )
 | 
						|
{
 | 
						|
	GameMessageArgument *a = allocArg();
 | 
						|
	a->m_data.wChar = arg;
 | 
						|
	a->m_type = ARGUMENTDATATYPE_WIDECHAR;
 | 
						|
}
 | 
						|
 | 
						|
AsciiString GameMessage::getCommandAsAsciiString( void )
 | 
						|
{
 | 
						|
	return getCommandTypeAsAsciiString(m_type);
 | 
						|
}
 | 
						|
 | 
						|
AsciiString GameMessage::getCommandTypeAsAsciiString(GameMessage::Type t)
 | 
						|
{
 | 
						|
#define CHECK_IF(x) if (t == x) { return #x; }
 | 
						|
	AsciiString commandName = "UnknownMessage";
 | 
						|
	if (t >= GameMessage::MSG_COUNT)
 | 
						|
	{
 | 
						|
		commandName = "Invalid command";
 | 
						|
	}
 | 
						|
	CHECK_IF(MSG_INVALID)
 | 
						|
	CHECK_IF(MSG_FRAME_TICK)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_BEGIN)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_POSITION)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_LEFT_BUTTON_DOWN)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_LEFT_DOUBLE_CLICK)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_LEFT_BUTTON_UP)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_LEFT_CLICK)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_LEFT_DRAG)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_MIDDLE_BUTTON_DOWN)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_MIDDLE_DOUBLE_CLICK)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_MIDDLE_BUTTON_UP)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_MIDDLE_DRAG)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_RIGHT_BUTTON_DOWN)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_RIGHT_DOUBLE_CLICK)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_RIGHT_BUTTON_UP)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_RIGHT_DRAG)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_WHEEL)
 | 
						|
	CHECK_IF(MSG_RAW_MOUSE_END)
 | 
						|
	CHECK_IF(MSG_RAW_KEY_DOWN)
 | 
						|
	CHECK_IF(MSG_RAW_KEY_UP)
 | 
						|
	CHECK_IF(MSG_MOUSE_LEFT_CLICK)
 | 
						|
	CHECK_IF(MSG_MOUSE_LEFT_DOUBLE_CLICK)
 | 
						|
	CHECK_IF(MSG_MOUSE_MIDDLE_CLICK)
 | 
						|
	CHECK_IF(MSG_MOUSE_MIDDLE_DOUBLE_CLICK)
 | 
						|
	CHECK_IF(MSG_MOUSE_RIGHT_CLICK)
 | 
						|
	CHECK_IF(MSG_MOUSE_RIGHT_DOUBLE_CLICK)
 | 
						|
	CHECK_IF(MSG_CLEAR_GAME_DATA)
 | 
						|
	CHECK_IF(MSG_NEW_GAME)
 | 
						|
	CHECK_IF(MSG_BEGIN_META_MESSAGES)
 | 
						|
	CHECK_IF(MSG_META_SAVE_VIEW1)
 | 
						|
	CHECK_IF(MSG_META_SAVE_VIEW2)
 | 
						|
	CHECK_IF(MSG_META_SAVE_VIEW3)
 | 
						|
	CHECK_IF(MSG_META_SAVE_VIEW4)
 | 
						|
	CHECK_IF(MSG_META_SAVE_VIEW5)
 | 
						|
	CHECK_IF(MSG_META_SAVE_VIEW6)
 | 
						|
	CHECK_IF(MSG_META_SAVE_VIEW7)
 | 
						|
	CHECK_IF(MSG_META_SAVE_VIEW8)
 | 
						|
	CHECK_IF(MSG_META_VIEW_VIEW1)
 | 
						|
	CHECK_IF(MSG_META_VIEW_VIEW2)
 | 
						|
	CHECK_IF(MSG_META_VIEW_VIEW3)
 | 
						|
	CHECK_IF(MSG_META_VIEW_VIEW4)
 | 
						|
	CHECK_IF(MSG_META_VIEW_VIEW5)
 | 
						|
	CHECK_IF(MSG_META_VIEW_VIEW6)
 | 
						|
	CHECK_IF(MSG_META_VIEW_VIEW7)
 | 
						|
	CHECK_IF(MSG_META_VIEW_VIEW8)
 | 
						|
	CHECK_IF(MSG_META_CREATE_TEAM0)
 | 
						|
	CHECK_IF(MSG_META_CREATE_TEAM1)
 | 
						|
	CHECK_IF(MSG_META_CREATE_TEAM2)
 | 
						|
	CHECK_IF(MSG_META_CREATE_TEAM3)
 | 
						|
	CHECK_IF(MSG_META_CREATE_TEAM4)
 | 
						|
	CHECK_IF(MSG_META_CREATE_TEAM5)
 | 
						|
	CHECK_IF(MSG_META_CREATE_TEAM6)
 | 
						|
	CHECK_IF(MSG_META_CREATE_TEAM7)
 | 
						|
	CHECK_IF(MSG_META_CREATE_TEAM8)
 | 
						|
	CHECK_IF(MSG_META_CREATE_TEAM9)
 | 
						|
	CHECK_IF(MSG_META_SELECT_TEAM0)
 | 
						|
	CHECK_IF(MSG_META_SELECT_TEAM1)
 | 
						|
	CHECK_IF(MSG_META_SELECT_TEAM2)
 | 
						|
	CHECK_IF(MSG_META_SELECT_TEAM3)
 | 
						|
	CHECK_IF(MSG_META_SELECT_TEAM4)
 | 
						|
	CHECK_IF(MSG_META_SELECT_TEAM5)
 | 
						|
	CHECK_IF(MSG_META_SELECT_TEAM6)
 | 
						|
	CHECK_IF(MSG_META_SELECT_TEAM7)
 | 
						|
	CHECK_IF(MSG_META_SELECT_TEAM8)
 | 
						|
	CHECK_IF(MSG_META_SELECT_TEAM9)
 | 
						|
	CHECK_IF(MSG_META_ADD_TEAM0)
 | 
						|
	CHECK_IF(MSG_META_ADD_TEAM1)
 | 
						|
	CHECK_IF(MSG_META_ADD_TEAM2)
 | 
						|
	CHECK_IF(MSG_META_ADD_TEAM3)
 | 
						|
	CHECK_IF(MSG_META_ADD_TEAM4)
 | 
						|
	CHECK_IF(MSG_META_ADD_TEAM5)
 | 
						|
	CHECK_IF(MSG_META_ADD_TEAM6)
 | 
						|
	CHECK_IF(MSG_META_ADD_TEAM7)
 | 
						|
	CHECK_IF(MSG_META_ADD_TEAM8)
 | 
						|
	CHECK_IF(MSG_META_ADD_TEAM9)
 | 
						|
	CHECK_IF(MSG_META_VIEW_TEAM0)
 | 
						|
	CHECK_IF(MSG_META_VIEW_TEAM1)
 | 
						|
	CHECK_IF(MSG_META_VIEW_TEAM2)
 | 
						|
	CHECK_IF(MSG_META_VIEW_TEAM3)
 | 
						|
	CHECK_IF(MSG_META_VIEW_TEAM4)
 | 
						|
	CHECK_IF(MSG_META_VIEW_TEAM5)
 | 
						|
	CHECK_IF(MSG_META_VIEW_TEAM6)
 | 
						|
	CHECK_IF(MSG_META_VIEW_TEAM7)
 | 
						|
	CHECK_IF(MSG_META_VIEW_TEAM8)
 | 
						|
	CHECK_IF(MSG_META_VIEW_TEAM9)
 | 
						|
	CHECK_IF(MSG_META_SELECT_MATCHING_UNITS)
 | 
						|
	CHECK_IF(MSG_META_SELECT_NEXT_UNIT)
 | 
						|
	CHECK_IF(MSG_META_SELECT_PREV_UNIT)
 | 
						|
	CHECK_IF(MSG_META_SELECT_NEXT_WORKER)
 | 
						|
	CHECK_IF(MSG_META_SELECT_PREV_WORKER)
 | 
						|
	CHECK_IF(MSG_META_VIEW_COMMAND_CENTER)
 | 
						|
	CHECK_IF(MSG_META_VIEW_LAST_RADAR_EVENT)
 | 
						|
	CHECK_IF(MSG_META_SELECT_HERO)
 | 
						|
	CHECK_IF(MSG_META_SELECT_ALL)
 | 
						|
	CHECK_IF(MSG_META_SELECT_ALL_AIRCRAFT)
 | 
						|
	CHECK_IF(MSG_META_SCATTER)
 | 
						|
	CHECK_IF(MSG_META_STOP)
 | 
						|
	CHECK_IF(MSG_META_DEPLOY)
 | 
						|
	CHECK_IF(MSG_META_CREATE_FORMATION)
 | 
						|
	CHECK_IF(MSG_META_FOLLOW)
 | 
						|
	CHECK_IF(MSG_META_CHAT_PLAYERS)
 | 
						|
	CHECK_IF(MSG_META_CHAT_ALLIES)
 | 
						|
	CHECK_IF(MSG_META_CHAT_EVERYONE)
 | 
						|
	CHECK_IF(MSG_META_DIPLOMACY)
 | 
						|
	CHECK_IF(MSG_META_OPTIONS)
 | 
						|
#if defined(_DEBUG) || defined(_INTERNAL)
 | 
						|
	CHECK_IF(MSG_META_HELP)
 | 
						|
#endif
 | 
						|
	CHECK_IF(MSG_META_TOGGLE_LOWER_DETAILS)
 | 
						|
	CHECK_IF(MSG_META_TOGGLE_CONTROL_BAR)
 | 
						|
	CHECK_IF(MSG_META_BEGIN_PATH_BUILD)
 | 
						|
	CHECK_IF(MSG_META_END_PATH_BUILD)
 | 
						|
	CHECK_IF(MSG_META_BEGIN_FORCEATTACK)
 | 
						|
	CHECK_IF(MSG_META_END_FORCEATTACK)
 | 
						|
	CHECK_IF(MSG_META_BEGIN_FORCEMOVE)
 | 
						|
	CHECK_IF(MSG_META_END_FORCEMOVE)
 | 
						|
	CHECK_IF(MSG_META_BEGIN_WAYPOINTS)
 | 
						|
	CHECK_IF(MSG_META_END_WAYPOINTS)
 | 
						|
	CHECK_IF(MSG_META_BEGIN_PREFER_SELECTION)
 | 
						|
	CHECK_IF(MSG_META_END_PREFER_SELECTION)
 | 
						|
	CHECK_IF(MSG_META_TAKE_SCREENSHOT)
 | 
						|
	CHECK_IF(MSG_META_ALL_CHEER)
 | 
						|
	CHECK_IF(MSG_META_TOGGLE_ATTACKMOVE)
 | 
						|
	CHECK_IF(MSG_META_BEGIN_CAMERA_ROTATE_LEFT)
 | 
						|
	CHECK_IF(MSG_META_END_CAMERA_ROTATE_LEFT)
 | 
						|
	CHECK_IF(MSG_META_BEGIN_CAMERA_ROTATE_RIGHT)
 | 
						|
	CHECK_IF(MSG_META_END_CAMERA_ROTATE_RIGHT)
 | 
						|
	CHECK_IF(MSG_META_BEGIN_CAMERA_ZOOM_IN)
 | 
						|
	CHECK_IF(MSG_META_END_CAMERA_ZOOM_IN)
 | 
						|
	CHECK_IF(MSG_META_BEGIN_CAMERA_ZOOM_OUT)
 | 
						|
	CHECK_IF(MSG_META_END_CAMERA_ZOOM_OUT)
 | 
						|
	CHECK_IF(MSG_META_CAMERA_RESET)
 | 
						|
	CHECK_IF(MSG_META_TOGGLE_CAMERA_TRACKING_DRAWABLE)
 | 
						|
	CHECK_IF(MSG_META_DEMO_INSTANT_QUIT)
 | 
						|
 | 
						|
 | 
						|
#if defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE)//may be defined in GameCommon.h
 | 
						|
    CHECK_IF(MSG_CHEAT_RUNSCRIPT1)
 | 
						|
		CHECK_IF(MSG_CHEAT_RUNSCRIPT2)
 | 
						|
		CHECK_IF(MSG_CHEAT_RUNSCRIPT3)
 | 
						|
		CHECK_IF(MSG_CHEAT_RUNSCRIPT4)
 | 
						|
		CHECK_IF(MSG_CHEAT_RUNSCRIPT5)
 | 
						|
		CHECK_IF(MSG_CHEAT_RUNSCRIPT6)
 | 
						|
		CHECK_IF(MSG_CHEAT_RUNSCRIPT7)
 | 
						|
		CHECK_IF(MSG_CHEAT_RUNSCRIPT8)
 | 
						|
		CHECK_IF(MSG_CHEAT_RUNSCRIPT9)
 | 
						|
		CHECK_IF(MSG_CHEAT_TOGGLE_SPECIAL_POWER_DELAYS)
 | 
						|
		CHECK_IF(MSG_CHEAT_SWITCH_TEAMS)							
 | 
						|
		CHECK_IF(MSG_CHEAT_KILL_SELECTION)						
 | 
						|
		CHECK_IF(MSG_CHEAT_TOGGLE_HAND_OF_GOD_MODE)	
 | 
						|
		CHECK_IF(MSG_CHEAT_INSTANT_BUILD)						
 | 
						|
		CHECK_IF(MSG_CHEAT_DESHROUD)									
 | 
						|
		CHECK_IF(MSG_CHEAT_ADD_CASH)									
 | 
						|
		CHECK_IF(MSG_CHEAT_GIVE_ALL_SCIENCES)				
 | 
						|
		CHECK_IF(MSG_CHEAT_GIVE_SCIENCEPURCHASEPOINTS)
 | 
						|
    CHECK_IF(MSG_CHEAT_SHOW_HEALTH)
 | 
						|
    CHECK_IF(MSG_CHEAT_TOGGLE_MESSAGE_TEXT)
 | 
						|
 | 
						|
 | 
						|
#endif
 | 
						|
    CHECK_IF(MSG_META_TOGGLE_FAST_FORWARD_REPLAY)
 | 
						|
    
 | 
						|
    
 | 
						|
#if defined(_DEBUG) || defined(_INTERNAL)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_BEHIND_BUILDINGS)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_LETTERBOX)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_MESSAGE_TEXT)
 | 
						|
	CHECK_IF(MSG_META_DEMO_LOD_DECREASE)
 | 
						|
	CHECK_IF(MSG_META_DEMO_LOD_INCREASE)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_ZOOM_LOCK)
 | 
						|
	CHECK_IF(MSG_META_DEMO_PLAY_CAMEO_MOVIE)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_SPECIAL_POWER_DELAYS)
 | 
						|
	CHECK_IF(MSG_META_DEMO_BATTLE_CRY)
 | 
						|
	CHECK_IF(MSG_META_DEMO_SWITCH_TEAMS)
 | 
						|
	CHECK_IF(MSG_META_DEMO_SWITCH_TEAMS_BETWEEN_CHINA_USA)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_PARTICLEDEBUG)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_SHADOW_VOLUMES)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_FOGOFWAR)
 | 
						|
	CHECK_IF(MSG_META_DEMO_KILL_ALL_ENEMIES)
 | 
						|
	CHECK_IF(MSG_META_DEMO_KILL_SELECTION)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_HURT_ME_MODE)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_HAND_OF_GOD_MODE)
 | 
						|
	CHECK_IF(MSG_META_DEMO_DEBUG_SELECTION)
 | 
						|
	CHECK_IF(MSG_META_DEMO_LOCK_CAMERA_TO_SELECTION)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_SOUND)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_TRACKMARKS)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_WATERPLANE)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TIME_OF_DAY)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_MUSIC)
 | 
						|
	CHECK_IF(MSG_META_DEMO_MUSIC_NEXT_TRACK)
 | 
						|
	CHECK_IF(MSG_META_DEMO_MUSIC_PREV_TRACK)
 | 
						|
	CHECK_IF(MSG_META_DEMO_NEXT_OBJECTIVE_MOVIE)
 | 
						|
	CHECK_IF(MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE1)
 | 
						|
	CHECK_IF(MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE2)
 | 
						|
	CHECK_IF(MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE3)
 | 
						|
	CHECK_IF(MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE4)
 | 
						|
	CHECK_IF(MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE5)
 | 
						|
	CHECK_IF(MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE6)
 | 
						|
	CHECK_IF(MSG_META_DEMO_BEGIN_ADJUST_PITCH)
 | 
						|
	CHECK_IF(MSG_META_DEMO_END_ADJUST_PITCH)
 | 
						|
	CHECK_IF(MSG_META_DEMO_BEGIN_ADJUST_FOV)
 | 
						|
	CHECK_IF(MSG_META_DEMO_END_ADJUST_FOV)
 | 
						|
	CHECK_IF(MSG_META_DEMO_LOCK_CAMERA_TO_PLANES)
 | 
						|
	CHECK_IF(MSG_META_DEMO_REMOVE_PREREQ)
 | 
						|
	CHECK_IF(MSG_META_DEMO_INSTANT_BUILD)
 | 
						|
	CHECK_IF(MSG_META_DEMO_FREE_BUILD)
 | 
						|
	CHECK_IF(MSG_META_DEMO_RUNSCRIPT1)
 | 
						|
	CHECK_IF(MSG_META_DEMO_RUNSCRIPT2)
 | 
						|
	CHECK_IF(MSG_META_DEMO_RUNSCRIPT3)
 | 
						|
	CHECK_IF(MSG_META_DEMO_RUNSCRIPT4)
 | 
						|
	CHECK_IF(MSG_META_DEMO_RUNSCRIPT5)
 | 
						|
	CHECK_IF(MSG_META_DEMO_RUNSCRIPT6)
 | 
						|
	CHECK_IF(MSG_META_DEMO_RUNSCRIPT7)
 | 
						|
	CHECK_IF(MSG_META_DEMO_RUNSCRIPT8)
 | 
						|
	CHECK_IF(MSG_META_DEMO_RUNSCRIPT9)
 | 
						|
	CHECK_IF(MSG_META_DEMO_ENSHROUD)
 | 
						|
	CHECK_IF(MSG_META_DEMO_DESHROUD)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_SHOW_EXTENTS)
 | 
						|
  CHECK_IF(MSG_META_DEBUG_SHOW_AUDIO_LOCATIONS)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_SHOW_HEALTH)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_GIVE_VETERANCY)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_TAKE_VETERANCY)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_AI_DEBUG)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_SUPPLY_CENTER_PLACEMENT)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_CAMERA_DEBUG)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_AVI)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_BW_VIEW)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_RED_VIEW)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_GREEN_VIEW)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_MOTION_BLUR_ZOOM)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_MILITARY_SUBTITLES)
 | 
						|
	CHECK_IF(MSG_META_DEMO_ADD_CASH)
 | 
						|
#ifdef ALLOW_SURRENDER
 | 
						|
	CHECK_IF(MSG_META_DEMO_TEST_SURRENDER)
 | 
						|
#endif
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_RENDER)
 | 
						|
	CHECK_IF(MSG_META_DEMO_KILL_AREA_SELECTION)
 | 
						|
	CHECK_IF(MSG_META_DEMO_CYCLE_LOD_LEVEL)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_INCR_ANIM_SKATE_SPEED)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_DECR_ANIM_SKATE_SPEED)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_CYCLE_EXTENT_TYPE)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_INCREASE_EXTENT_MAJOR)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_INCREASE_EXTENT_MAJOR_BIG)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_DECREASE_EXTENT_MAJOR)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_DECREASE_EXTENT_MAJOR_BIG)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_INCREASE_EXTENT_MINOR)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_INCREASE_EXTENT_MINOR_BIG)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_DECREASE_EXTENT_MINOR)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_DECREASE_EXTENT_MINOR_BIG)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_INCREASE_EXTENT_HEIGHT)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_INCREASE_EXTENT_HEIGHT_BIG)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_DECREASE_EXTENT_HEIGHT)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_DECREASE_EXTENT_HEIGHT_BIG)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_VTUNE_ON)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_VTUNE_OFF)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_TOGGLE_FEATHER_WATER)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_DUMP_ASSETS)
 | 
						|
	CHECK_IF(MSG_NO_DRAW)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_METRICS)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_PROJECTILEDEBUG)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_VISIONDEBUG)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_THREATDEBUG)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_CASHMAPDEBUG)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_GRAPHICALFRAMERATEBAR)
 | 
						|
	CHECK_IF(MSG_META_DEMO_GIVE_ALL_SCIENCES)
 | 
						|
	CHECK_IF(MSG_META_DEMO_GIVE_RANKLEVEL)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TAKE_RANKLEVEL)
 | 
						|
	CHECK_IF(MSG_META_DEMO_GIVE_SCIENCEPURCHASEPOINTS)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_TOGGLE_NETWORK)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_DUMP_PLAYER_OBJECTS)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_DUMP_ALL_PLAYER_OBJECTS)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_OBJECT_ID_PERFORMANCE)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_DRAWABLE_ID_PERFORMANCE)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_SLEEPY_UPDATE_PERFORMANCE)
 | 
						|
	CHECK_IF(MSG_META_DEBUG_WIN)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_DEBUG_STATS)
 | 
						|
#endif // defined(_DEBUG) || defined(_INTERNAL)
 | 
						|
 | 
						|
 | 
						|
#if defined(_INTERNAL) || defined(_DEBUG)
 | 
						|
	CHECK_IF(MSG_META_DEMO_TOGGLE_AUDIODEBUG)
 | 
						|
#endif//defined(_INTERNAL) || defined(_DEBUG)
 | 
						|
#ifdef DUMP_PERF_STATS
 | 
						|
	CHECK_IF(MSG_META_DEMO_PERFORM_STATISTICAL_DUMP)
 | 
						|
#endif//DUMP_PERF_STATS
 | 
						|
	CHECK_IF(MSG_META_PLACE_BEACON)
 | 
						|
	CHECK_IF(MSG_META_REMOVE_BEACON)
 | 
						|
	CHECK_IF(MSG_END_META_MESSAGES)
 | 
						|
	CHECK_IF(MSG_MOUSEOVER_DRAWABLE_HINT)
 | 
						|
	CHECK_IF(MSG_MOUSEOVER_LOCATION_HINT)
 | 
						|
	CHECK_IF(MSG_VALID_GUICOMMAND_HINT)
 | 
						|
	CHECK_IF(MSG_INVALID_GUICOMMAND_HINT)
 | 
						|
	CHECK_IF(MSG_AREA_SELECTION_HINT)
 | 
						|
	CHECK_IF(MSG_DO_ATTACK_OBJECT_HINT)
 | 
						|
	CHECK_IF(MSG_DO_ATTACK_OBJECT_AFTER_MOVING_HINT)
 | 
						|
	CHECK_IF(MSG_DO_FORCE_ATTACK_OBJECT_HINT)
 | 
						|
	CHECK_IF(MSG_DO_FORCE_ATTACK_GROUND_HINT)
 | 
						|
	CHECK_IF(MSG_GET_REPAIRED_HINT)
 | 
						|
	CHECK_IF(MSG_GET_HEALED_HINT)
 | 
						|
	CHECK_IF(MSG_DO_REPAIR_HINT)
 | 
						|
	CHECK_IF(MSG_RESUME_CONSTRUCTION_HINT)
 | 
						|
	CHECK_IF(MSG_ENTER_HINT)
 | 
						|
	CHECK_IF(MSG_DOCK_HINT)
 | 
						|
	CHECK_IF(MSG_DO_MOVETO_HINT)
 | 
						|
	CHECK_IF(MSG_DO_ATTACKMOVETO_HINT)
 | 
						|
	CHECK_IF(MSG_ADD_WAYPOINT_HINT)
 | 
						|
	CHECK_IF(MSG_HIJACK_HINT)
 | 
						|
	CHECK_IF(MSG_SABOTAGE_HINT)
 | 
						|
	CHECK_IF(MSG_FIREBOMB_HINT)
 | 
						|
	CHECK_IF(MSG_CONVERT_TO_CARBOMB_HINT)
 | 
						|
	CHECK_IF(MSG_CAPTUREBUILDING_HINT)
 | 
						|
	CHECK_IF(MSG_HACK_HINT)
 | 
						|
#ifdef ALLOW_SURRENDER
 | 
						|
	CHECK_IF(MSG_PICK_UP_PRISONER_HINT)
 | 
						|
#endif
 | 
						|
	CHECK_IF(MSG_SNIPE_VEHICLE_HINT)
 | 
						|
	CHECK_IF(MSG_DEFECTOR_HINT)
 | 
						|
	CHECK_IF(MSG_SET_RALLY_POINT_HINT)
 | 
						|
	CHECK_IF(MSG_DO_SALVAGE_HINT)
 | 
						|
	CHECK_IF(MSG_DO_INVALID_HINT)
 | 
						|
	CHECK_IF(MSG_BEGIN_NETWORK_MESSAGES)
 | 
						|
	CHECK_IF(MSG_CREATE_SELECTED_GROUP)
 | 
						|
	CHECK_IF(MSG_CREATE_SELECTED_GROUP_NO_SOUND)
 | 
						|
	CHECK_IF(MSG_DESTROY_SELECTED_GROUP)
 | 
						|
	CHECK_IF(MSG_REMOVE_FROM_SELECTED_GROUP)
 | 
						|
	CHECK_IF(MSG_SELECTED_GROUP_COMMAND)
 | 
						|
	CHECK_IF(MSG_CREATE_TEAM0)
 | 
						|
	CHECK_IF(MSG_CREATE_TEAM1)
 | 
						|
	CHECK_IF(MSG_CREATE_TEAM2)
 | 
						|
	CHECK_IF(MSG_CREATE_TEAM3)
 | 
						|
	CHECK_IF(MSG_CREATE_TEAM4)
 | 
						|
	CHECK_IF(MSG_CREATE_TEAM5)
 | 
						|
	CHECK_IF(MSG_CREATE_TEAM6)
 | 
						|
	CHECK_IF(MSG_CREATE_TEAM7)
 | 
						|
	CHECK_IF(MSG_CREATE_TEAM8)
 | 
						|
	CHECK_IF(MSG_CREATE_TEAM9)
 | 
						|
	CHECK_IF(MSG_SELECT_TEAM0)
 | 
						|
	CHECK_IF(MSG_SELECT_TEAM1)
 | 
						|
	CHECK_IF(MSG_SELECT_TEAM2)
 | 
						|
	CHECK_IF(MSG_SELECT_TEAM3)
 | 
						|
	CHECK_IF(MSG_SELECT_TEAM4)
 | 
						|
	CHECK_IF(MSG_SELECT_TEAM5)
 | 
						|
	CHECK_IF(MSG_SELECT_TEAM6)
 | 
						|
	CHECK_IF(MSG_SELECT_TEAM7)
 | 
						|
	CHECK_IF(MSG_SELECT_TEAM8)
 | 
						|
	CHECK_IF(MSG_SELECT_TEAM9)
 | 
						|
	CHECK_IF(MSG_ADD_TEAM0)
 | 
						|
	CHECK_IF(MSG_ADD_TEAM1)
 | 
						|
	CHECK_IF(MSG_ADD_TEAM2)
 | 
						|
	CHECK_IF(MSG_ADD_TEAM3)
 | 
						|
	CHECK_IF(MSG_ADD_TEAM4)
 | 
						|
	CHECK_IF(MSG_ADD_TEAM5)
 | 
						|
	CHECK_IF(MSG_ADD_TEAM6)
 | 
						|
	CHECK_IF(MSG_ADD_TEAM7)
 | 
						|
	CHECK_IF(MSG_ADD_TEAM8)
 | 
						|
	CHECK_IF(MSG_ADD_TEAM9)
 | 
						|
	CHECK_IF(MSG_DO_ATTACKSQUAD)
 | 
						|
	CHECK_IF(MSG_DO_WEAPON)
 | 
						|
	CHECK_IF(MSG_DO_WEAPON_AT_LOCATION)
 | 
						|
	CHECK_IF(MSG_DO_WEAPON_AT_OBJECT)
 | 
						|
	CHECK_IF(MSG_DO_SPECIAL_POWER)
 | 
						|
	CHECK_IF(MSG_DO_SPECIAL_POWER_AT_LOCATION)
 | 
						|
	CHECK_IF(MSG_DO_SPECIAL_POWER_AT_OBJECT)
 | 
						|
	CHECK_IF(MSG_SET_RALLY_POINT)
 | 
						|
	CHECK_IF(MSG_PURCHASE_SCIENCE)
 | 
						|
	CHECK_IF(MSG_QUEUE_UPGRADE)
 | 
						|
	CHECK_IF(MSG_CANCEL_UPGRADE)
 | 
						|
	CHECK_IF(MSG_QUEUE_UNIT_CREATE)
 | 
						|
	CHECK_IF(MSG_CANCEL_UNIT_CREATE)
 | 
						|
	CHECK_IF(MSG_DOZER_CONSTRUCT)
 | 
						|
	CHECK_IF(MSG_DOZER_CONSTRUCT_LINE)
 | 
						|
	CHECK_IF(MSG_DOZER_CANCEL_CONSTRUCT)
 | 
						|
	CHECK_IF(MSG_SELL)
 | 
						|
	CHECK_IF(MSG_EXIT)
 | 
						|
	CHECK_IF(MSG_EVACUATE)
 | 
						|
	CHECK_IF(MSG_EXECUTE_RAILED_TRANSPORT)
 | 
						|
	CHECK_IF(MSG_COMBATDROP_AT_LOCATION)
 | 
						|
	CHECK_IF(MSG_COMBATDROP_AT_OBJECT)
 | 
						|
	CHECK_IF(MSG_AREA_SELECTION)
 | 
						|
	CHECK_IF(MSG_DO_ATTACK_OBJECT)
 | 
						|
	CHECK_IF(MSG_DO_FORCE_ATTACK_OBJECT)
 | 
						|
	CHECK_IF(MSG_DO_FORCE_ATTACK_GROUND)
 | 
						|
	CHECK_IF(MSG_GET_REPAIRED)
 | 
						|
	CHECK_IF(MSG_GET_HEALED)
 | 
						|
	CHECK_IF(MSG_DO_REPAIR)
 | 
						|
	CHECK_IF(MSG_RESUME_CONSTRUCTION)
 | 
						|
	CHECK_IF(MSG_ENTER)
 | 
						|
	CHECK_IF(MSG_DOCK)
 | 
						|
	CHECK_IF(MSG_DO_MOVETO)
 | 
						|
	CHECK_IF(MSG_DO_ATTACKMOVETO)
 | 
						|
	CHECK_IF(MSG_DO_FORCEMOVETO)
 | 
						|
	CHECK_IF(MSG_ADD_WAYPOINT)
 | 
						|
	CHECK_IF(MSG_DO_GUARD_POSITION)
 | 
						|
	CHECK_IF(MSG_DO_GUARD_OBJECT)
 | 
						|
	CHECK_IF(MSG_DO_STOP)
 | 
						|
	CHECK_IF(MSG_DO_SCATTER)
 | 
						|
	CHECK_IF(MSG_INTERNET_HACK)
 | 
						|
	CHECK_IF(MSG_DO_CHEER)
 | 
						|
#ifdef ALLOW_SURRENDER
 | 
						|
	CHECK_IF(MSG_DO_SURRENDER)
 | 
						|
#endif
 | 
						|
	CHECK_IF(MSG_TOGGLE_OVERCHARGE)
 | 
						|
#ifdef ALLOW_SURRENDER
 | 
						|
	CHECK_IF(MSG_RETURN_TO_PRISON)
 | 
						|
#endif
 | 
						|
	CHECK_IF(MSG_SWITCH_WEAPONS)
 | 
						|
	CHECK_IF(MSG_CONVERT_TO_CARBOMB)
 | 
						|
	CHECK_IF(MSG_CAPTUREBUILDING)
 | 
						|
	CHECK_IF(MSG_DISABLEVEHICLE_HACK)
 | 
						|
	CHECK_IF(MSG_STEALCASH_HACK)
 | 
						|
	CHECK_IF(MSG_DISABLEBUILDING_HACK)
 | 
						|
	CHECK_IF(MSG_SNIPE_VEHICLE)
 | 
						|
#ifdef ALLOW_SURRENDER
 | 
						|
	CHECK_IF(MSG_PICK_UP_PRISONER)
 | 
						|
#endif
 | 
						|
	CHECK_IF(MSG_DO_SALVAGE)
 | 
						|
	CHECK_IF(MSG_CLEAR_INGAME_POPUP_MESSAGE)
 | 
						|
	CHECK_IF(MSG_PLACE_BEACON)
 | 
						|
	CHECK_IF(MSG_REMOVE_BEACON)
 | 
						|
	CHECK_IF(MSG_SET_BEACON_TEXT)
 | 
						|
	CHECK_IF(MSG_SET_REPLAY_CAMERA)
 | 
						|
	CHECK_IF(MSG_SELF_DESTRUCT)
 | 
						|
	CHECK_IF(MSG_CREATE_FORMATION)
 | 
						|
	CHECK_IF(MSG_LOGIC_CRC)
 | 
						|
#if defined(_DEBUG) || defined(_INTERNAL)  
 | 
						|
	CHECK_IF(MSG_DEBUG_KILL_SELECTION)
 | 
						|
	CHECK_IF(MSG_DEBUG_HURT_OBJECT)
 | 
						|
	CHECK_IF(MSG_DEBUG_KILL_OBJECT)
 | 
						|
#endif
 | 
						|
 | 
						|
	CHECK_IF(MSG_END_NETWORK_MESSAGES)
 | 
						|
	CHECK_IF(MSG_TIMESTAMP)
 | 
						|
	CHECK_IF(MSG_OBJECT_CREATED)
 | 
						|
	CHECK_IF(MSG_OBJECT_DESTROYED)
 | 
						|
	CHECK_IF(MSG_OBJECT_POSITION)
 | 
						|
	CHECK_IF(MSG_OBJECT_ORIENTATION)
 | 
						|
	CHECK_IF(MSG_OBJECT_JOINED_TEAM)
 | 
						|
	CHECK_IF(MSG_SET_MINE_CLEARING_DETAIL)
 | 
						|
	CHECK_IF(MSG_ENABLE_RETALIATION_MODE)
 | 
						|
	return commandName;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//------------------------------------------------------------------------------------------------
 | 
						|
// GameMessageList
 | 
						|
//
 | 
						|
 | 
						|
/**
 | 
						|
 * Constructor
 | 
						|
 */
 | 
						|
GameMessageList::GameMessageList( void )
 | 
						|
{
 | 
						|
	m_firstMessage = 0;
 | 
						|
	m_lastMessage = 0;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Destructor
 | 
						|
 */
 | 
						|
GameMessageList::~GameMessageList()
 | 
						|
{
 | 
						|
	// destroy all messages currently on the list
 | 
						|
	GameMessage *msg, *nextMsg;
 | 
						|
	for( msg = m_firstMessage; msg; msg = nextMsg )
 | 
						|
	{
 | 
						|
		nextMsg = msg->next();
 | 
						|
		// set list ptr to null to avoid it trying to remove itself from the list
 | 
						|
		// that we are in the process of nuking...
 | 
						|
		msg->friend_setList(NULL);
 | 
						|
		msg->deleteInstance();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Append message to end of message list
 | 
						|
 */
 | 
						|
void GameMessageList::appendMessage( GameMessage *msg )
 | 
						|
{
 | 
						|
	msg->friend_setNext(NULL);
 | 
						|
 | 
						|
	if (m_lastMessage)
 | 
						|
	{
 | 
						|
		m_lastMessage->friend_setNext(msg);
 | 
						|
		msg->friend_setPrev(m_lastMessage);
 | 
						|
		m_lastMessage = msg;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		// first message
 | 
						|
		m_firstMessage = msg;
 | 
						|
		m_lastMessage = msg;
 | 
						|
		msg->friend_setPrev(NULL);
 | 
						|
	}
 | 
						|
 | 
						|
	// note containment within message itself
 | 
						|
	msg->friend_setList(this);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Inserts the msg after messageToInsertAfter.
 | 
						|
 */
 | 
						|
void GameMessageList::insertMessage( GameMessage *msg, GameMessage *messageToInsertAfter )
 | 
						|
{
 | 
						|
	// First, set msg's next to be messageToInsertAfter's next.
 | 
						|
	msg->friend_setNext(messageToInsertAfter->next());
 | 
						|
	
 | 
						|
	// Next, set msg's prev to be messageToInsertAfter
 | 
						|
	msg->friend_setPrev(messageToInsertAfter);
 | 
						|
	
 | 
						|
	// Now update the next message's prev to be msg
 | 
						|
	if (msg->next())
 | 
						|
		msg->next()->friend_setPrev(msg);
 | 
						|
	else	// if the friend wasn't there, then messageToInsertAfter is the last message. Update it to be msg.
 | 
						|
		m_lastMessage = msg;
 | 
						|
 | 
						|
	// Finally, update the messageToInsertAfter's next to be msg
 | 
						|
	messageToInsertAfter->friend_setNext(msg);
 | 
						|
 | 
						|
	// note containment within the message itself
 | 
						|
	msg->friend_setList(this);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Remove given message from the list.
 | 
						|
 */
 | 
						|
void GameMessageList::removeMessage( GameMessage *msg )
 | 
						|
{
 | 
						|
	if (msg->next())
 | 
						|
		msg->next()->friend_setPrev(msg->prev());
 | 
						|
	else
 | 
						|
		m_lastMessage = msg->prev();
 | 
						|
 | 
						|
	if (msg->prev())
 | 
						|
		msg->prev()->friend_setNext(msg->next());
 | 
						|
	else
 | 
						|
		m_firstMessage = msg->next();
 | 
						|
 | 
						|
	msg->friend_setList(NULL);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Return whether or not a message of the given type is in the message list
 | 
						|
 */
 | 
						|
Bool GameMessageList::containsMessageOfType( GameMessage::Type type )
 | 
						|
{
 | 
						|
	GameMessage *msg = getFirstMessage();
 | 
						|
	while (msg) {
 | 
						|
		if (msg->getType() == type) {
 | 
						|
			return true;
 | 
						|
		}
 | 
						|
		msg = msg->next();
 | 
						|
	}
 | 
						|
	return false;
 | 
						|
}
 | 
						|
 | 
						|
//------------------------------------------------------------------------------------------------
 | 
						|
// MessageStream
 | 
						|
//
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * Constructor
 | 
						|
 */
 | 
						|
MessageStream::MessageStream( void )
 | 
						|
{
 | 
						|
	m_firstTranslator = 0;
 | 
						|
	m_nextTranslatorID = 1;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Destructor
 | 
						|
 */
 | 
						|
MessageStream::~MessageStream()
 | 
						|
{
 | 
						|
	// destroy all translators
 | 
						|
	TranslatorData *trans, *nextTrans;
 | 
						|
	for( trans=m_firstTranslator; trans; trans=nextTrans )
 | 
						|
	{
 | 
						|
		nextTrans = trans->m_next;
 | 
						|
		delete trans;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
	* Init
 | 
						|
	*/
 | 
						|
void MessageStream::init( void )
 | 
						|
{
 | 
						|
	// extend
 | 
						|
	GameMessageList::init();
 | 
						|
} 
 | 
						|
 | 
						|
/**
 | 
						|
	* Reset
 | 
						|
	*/
 | 
						|
void MessageStream::reset( void )
 | 
						|
{
 | 
						|
 | 
						|
	/// @todo Reset the MessageStream
 | 
						|
 | 
						|
	// extend
 | 
						|
	GameMessageList::reset();
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
	* Update
 | 
						|
	*/
 | 
						|
void MessageStream::update( void )
 | 
						|
{
 | 
						|
	// extend
 | 
						|
	GameMessageList::update();
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Create a new message of the given message type and append it
 | 
						|
 * to this message stream.  Return the message such that any data
 | 
						|
 * associated with this message can be attached to it.
 | 
						|
 */
 | 
						|
GameMessage *MessageStream::appendMessage( GameMessage::Type type )
 | 
						|
{
 | 
						|
	GameMessage *msg = newInstance(GameMessage)( type );
 | 
						|
 | 
						|
	// add message to list
 | 
						|
	GameMessageList::appendMessage( msg );
 | 
						|
 | 
						|
	return msg;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Create a new message of the given message type and insert it
 | 
						|
 * in the stream after messageToInsertAfter, which must not be NULL.
 | 
						|
 */
 | 
						|
GameMessage *MessageStream::insertMessage( GameMessage::Type type, GameMessage *messageToInsertAfter )
 | 
						|
{
 | 
						|
	GameMessage *msg = newInstance(GameMessage)(type);
 | 
						|
 | 
						|
	GameMessageList::insertMessage(msg, messageToInsertAfter);
 | 
						|
 | 
						|
	return msg;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Attach the given Translator to the message stream, and return a
 | 
						|
 * unique TranslatorID identifying it.
 | 
						|
 * Translators are placed on a list, sorted by priority order.  If two
 | 
						|
 * Translators share a priority, they are kept in the same order they
 | 
						|
 * were attached.
 | 
						|
 */
 | 
						|
TranslatorID MessageStream::attachTranslator( GameMessageTranslator *translator, 
 | 
						|
																							UnsignedInt priority)
 | 
						|
{
 | 
						|
	MessageStream::TranslatorData *newSS = NEW MessageStream::TranslatorData;
 | 
						|
	MessageStream::TranslatorData *ss;
 | 
						|
 | 
						|
	newSS->m_translator = translator;
 | 
						|
	newSS->m_priority = priority;
 | 
						|
	newSS->m_id = m_nextTranslatorID++;
 | 
						|
 | 
						|
	if (m_firstTranslator == NULL)
 | 
						|
	{
 | 
						|
		// first Translator to be attached
 | 
						|
		newSS->m_prev = NULL;
 | 
						|
		newSS->m_next = NULL;
 | 
						|
		m_firstTranslator = newSS;
 | 
						|
		m_lastTranslator = newSS;
 | 
						|
		return newSS->m_id;
 | 
						|
	}
 | 
						|
 | 
						|
	// seach the Translator list for our priority location
 | 
						|
	for( ss=m_firstTranslator; ss; ss=ss->m_next )
 | 
						|
		if (ss->m_priority > newSS->m_priority)
 | 
						|
			break;
 | 
						|
 | 
						|
	if (ss)
 | 
						|
	{
 | 
						|
		// insert new Translator just BEFORE this one,
 | 
						|
		// therefore, m_lastTranslator cannot be affected
 | 
						|
		if (ss->m_prev)
 | 
						|
		{
 | 
						|
			ss->m_prev->m_next = newSS;
 | 
						|
			newSS->m_prev = ss->m_prev;
 | 
						|
			newSS->m_next = ss;
 | 
						|
			ss->m_prev = newSS;
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			// insert at head of list
 | 
						|
			newSS->m_prev = NULL;
 | 
						|
			newSS->m_next = m_firstTranslator;
 | 
						|
			m_firstTranslator->m_prev = newSS;
 | 
						|
			m_firstTranslator = newSS;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		// append Translator to end of list
 | 
						|
		m_lastTranslator->m_next = newSS;
 | 
						|
		newSS->m_prev = m_lastTranslator;
 | 
						|
		newSS->m_next = NULL;
 | 
						|
		m_lastTranslator = newSS;
 | 
						|
	}
 | 
						|
 | 
						|
	return newSS->m_id;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
	* Find a translator attached to this message stream given the ID 
 | 
						|
	*/
 | 
						|
GameMessageTranslator* MessageStream::findTranslator( TranslatorID id )
 | 
						|
{
 | 
						|
	MessageStream::TranslatorData *translatorData;
 | 
						|
 | 
						|
	for( translatorData = m_firstTranslator; translatorData; translatorData = translatorData->m_next )
 | 
						|
	{
 | 
						|
 | 
						|
		if( translatorData->m_id == id )
 | 
						|
			return translatorData->m_translator;
 | 
						|
 | 
						|
	}
 | 
						|
 | 
						|
	return NULL;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Remove a previously attached translator.
 | 
						|
 */
 | 
						|
void MessageStream::removeTranslator( TranslatorID id )
 | 
						|
{
 | 
						|
	MessageStream::TranslatorData *ss;
 | 
						|
 | 
						|
	for( ss=m_firstTranslator; ss; ss=ss->m_next )
 | 
						|
		if (ss->m_id == id)
 | 
						|
		{
 | 
						|
			// found the translator - remove it
 | 
						|
			if (ss->m_prev)
 | 
						|
				ss->m_prev->m_next = ss->m_next;
 | 
						|
			else
 | 
						|
				m_firstTranslator = ss->m_next;
 | 
						|
 | 
						|
			if (ss->m_next)
 | 
						|
				ss->m_next->m_prev = ss->m_prev;
 | 
						|
			else
 | 
						|
				m_lastTranslator = ss->m_prev;
 | 
						|
 | 
						|
			// delete the translator data
 | 
						|
			delete ss;
 | 
						|
 | 
						|
			break;
 | 
						|
		}
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// ------------------------------------------------------------------------------------------------
 | 
						|
// ------------------------------------------------------------------------------------------------
 | 
						|
#if defined(_DEBUG) || defined(_INTERNAL)
 | 
						|
 | 
						|
Bool isInvalidDebugCommand( GameMessage::Type t )
 | 
						|
{
 | 
						|
	// see if this is something that should be prevented in multiplayer games
 | 
						|
	// Don't reject this stuff in skirmish games.
 | 
						|
	if (TheGameLogic && !TheGameLogic->isInSkirmishGame() && 
 | 
						|
			(TheRecorder && TheRecorder->isMultiplayer() && TheRecorder->getMode() == RECORDERMODETYPE_RECORD))
 | 
						|
	{
 | 
						|
		switch (t)
 | 
						|
		{
 | 
						|
		case GameMessage::MSG_META_DEMO_SWITCH_TEAMS:
 | 
						|
		case GameMessage::MSG_META_DEMO_SWITCH_TEAMS_BETWEEN_CHINA_USA:
 | 
						|
		case GameMessage::MSG_META_DEMO_KILL_ALL_ENEMIES:
 | 
						|
		case GameMessage::MSG_META_DEMO_KILL_SELECTION:
 | 
						|
		case GameMessage::MSG_META_DEMO_TOGGLE_HURT_ME_MODE:
 | 
						|
		case GameMessage::MSG_META_DEMO_TOGGLE_HAND_OF_GOD_MODE:
 | 
						|
		case GameMessage::MSG_META_DEMO_TOGGLE_SPECIAL_POWER_DELAYS:
 | 
						|
		case GameMessage::MSG_META_DEMO_TIME_OF_DAY:
 | 
						|
		case GameMessage::MSG_META_DEMO_LOCK_CAMERA_TO_PLANES:
 | 
						|
		case GameMessage::MSG_META_DEMO_REMOVE_PREREQ:
 | 
						|
		case GameMessage::MSG_META_DEMO_INSTANT_BUILD:
 | 
						|
		case GameMessage::MSG_META_DEMO_FREE_BUILD:
 | 
						|
		case GameMessage::MSG_META_DEMO_RUNSCRIPT1:
 | 
						|
		case GameMessage::MSG_META_DEMO_RUNSCRIPT2:
 | 
						|
		case GameMessage::MSG_META_DEMO_RUNSCRIPT3:
 | 
						|
		case GameMessage::MSG_META_DEMO_RUNSCRIPT4:
 | 
						|
		case GameMessage::MSG_META_DEMO_RUNSCRIPT5:
 | 
						|
		case GameMessage::MSG_META_DEMO_RUNSCRIPT6:
 | 
						|
		case GameMessage::MSG_META_DEMO_RUNSCRIPT7:
 | 
						|
		case GameMessage::MSG_META_DEMO_RUNSCRIPT8:
 | 
						|
		case GameMessage::MSG_META_DEMO_RUNSCRIPT9:
 | 
						|
		case GameMessage::MSG_META_DEMO_ENSHROUD:
 | 
						|
		case GameMessage::MSG_META_DEMO_DESHROUD:
 | 
						|
		case GameMessage::MSG_META_DEBUG_GIVE_VETERANCY:
 | 
						|
		case GameMessage::MSG_META_DEBUG_TAKE_VETERANCY:
 | 
						|
//#pragma MESSAGE ("WARNING - DEBUG key in multiplayer!")
 | 
						|
		case GameMessage::MSG_META_DEMO_ADD_CASH:
 | 
						|
		case GameMessage::MSG_META_DEBUG_INCR_ANIM_SKATE_SPEED:
 | 
						|
		case GameMessage::MSG_META_DEBUG_DECR_ANIM_SKATE_SPEED:
 | 
						|
		case GameMessage::MSG_META_DEBUG_CYCLE_EXTENT_TYPE:
 | 
						|
		case GameMessage::MSG_META_DEMO_TOGGLE_RENDER:
 | 
						|
		case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_MAJOR:
 | 
						|
		case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_MAJOR_BIG:
 | 
						|
		case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_MAJOR:
 | 
						|
		case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_MAJOR_BIG:
 | 
						|
		case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_MINOR:
 | 
						|
		case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_MINOR_BIG:
 | 
						|
		case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_MINOR:
 | 
						|
		case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_MINOR_BIG:
 | 
						|
		case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_HEIGHT:
 | 
						|
		case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_HEIGHT_BIG:
 | 
						|
		case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_HEIGHT:
 | 
						|
		case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_HEIGHT_BIG:
 | 
						|
		case GameMessage::MSG_META_DEMO_KILL_AREA_SELECTION:
 | 
						|
		case GameMessage::MSG_DEBUG_KILL_SELECTION:
 | 
						|
		case GameMessage::MSG_DEBUG_HURT_OBJECT:
 | 
						|
		case GameMessage::MSG_DEBUG_KILL_OBJECT:
 | 
						|
		case GameMessage::MSG_META_DEMO_GIVE_SCIENCEPURCHASEPOINTS:
 | 
						|
		case GameMessage::MSG_META_DEMO_GIVE_ALL_SCIENCES:
 | 
						|
		case GameMessage::MSG_META_DEMO_GIVE_RANKLEVEL:
 | 
						|
		case GameMessage::MSG_META_DEMO_TAKE_RANKLEVEL:
 | 
						|
		case GameMessage::MSG_META_DEBUG_WIN:
 | 
						|
 | 
						|
			return true;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return false;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
/**
 | 
						|
 * Propagate messages thru attached Translators, invoking each Translator's
 | 
						|
 * callback for each message in the stream.
 | 
						|
 * Once all Translators have evaluated the message stream, all messages
 | 
						|
 * in the stream are destroyed.
 | 
						|
 */
 | 
						|
void MessageStream::propagateMessages( void )
 | 
						|
{
 | 
						|
	MessageStream::TranslatorData *ss;
 | 
						|
	GameMessage *msg, *next;
 | 
						|
 | 
						|
	// process each Translator
 | 
						|
	for( ss=m_firstTranslator; ss; ss=ss->m_next )
 | 
						|
	{
 | 
						|
		for( msg=m_firstMessage; msg; msg=next )
 | 
						|
		{			
 | 
						|
			if (ss->m_translator 
 | 
						|
#if defined(_DEBUG) || defined(_INTERNAL)
 | 
						|
				&& !isInvalidDebugCommand(msg->getType())
 | 
						|
#endif
 | 
						|
				)
 | 
						|
			{
 | 
						|
				GameMessageDisposition disp = ss->m_translator->translateGameMessage(msg);
 | 
						|
				next = msg->next();
 | 
						|
				if (disp == DESTROY_MESSAGE)
 | 
						|
				{
 | 
						|
					msg->deleteInstance();
 | 
						|
				}
 | 
						|
			} 
 | 
						|
			else 
 | 
						|
			{
 | 
						|
				next = msg->next();
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	// transfer all messages that reached the end of the stream to TheCommandList
 | 
						|
	TheCommandList->appendMessageList( m_firstMessage );
 | 
						|
 | 
						|
	// clear the stream
 | 
						|
	m_firstMessage = NULL;
 | 
						|
	m_lastMessage = NULL;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//------------------------------------------------------------------------------------------------
 | 
						|
// CommandList
 | 
						|
//
 | 
						|
 | 
						|
/**
 | 
						|
 * Constructor
 | 
						|
 */
 | 
						|
CommandList::CommandList( void )
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Destructor
 | 
						|
 */
 | 
						|
CommandList::~CommandList()
 | 
						|
{
 | 
						|
	destroyAllMessages();
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
	* Init
 | 
						|
	*/
 | 
						|
void CommandList::init( void )
 | 
						|
{
 | 
						|
 | 
						|
	// extend
 | 
						|
	GameMessageList::init();
 | 
						|
 | 
						|
} 
 | 
						|
 | 
						|
/**
 | 
						|
	* Destroy all messages on the list, and reset list to empty
 | 
						|
	*/
 | 
						|
void CommandList::reset( void )
 | 
						|
{
 | 
						|
 | 
						|
	// extend
 | 
						|
	GameMessageList::reset();
 | 
						|
 | 
						|
	// destroy all messages
 | 
						|
	destroyAllMessages();
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
	* Update
 | 
						|
	*/
 | 
						|
void CommandList::update( void )
 | 
						|
{
 | 
						|
 | 
						|
	// extend
 | 
						|
	GameMessageList::update();
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
	* Destroy all messages on the command list, this will get called from the
 | 
						|
	* destructor and reset methods, DO NOT throw exceptions
 | 
						|
	*/
 | 
						|
void CommandList::destroyAllMessages( void )
 | 
						|
{
 | 
						|
	GameMessage *msg, *next;
 | 
						|
 | 
						|
	for( msg=m_firstMessage; msg; msg=next )
 | 
						|
	{
 | 
						|
		next = msg->next();
 | 
						|
		msg->deleteInstance();
 | 
						|
	}
 | 
						|
	
 | 
						|
	m_firstMessage = NULL;
 | 
						|
	m_lastMessage = NULL;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/** 
 | 
						|
 * Adds messages to the end of TheCommandList.
 | 
						|
 * Primarily used by TheMessageStream to put the final messages that reach the end of the 
 | 
						|
 * stream on TheCommandList. Since TheGameClient will update faster than TheNetwork 
 | 
						|
 * and TheGameLogic, messages will accumulate on this list.
 | 
						|
 */
 | 
						|
void CommandList::appendMessageList( GameMessage *list ) 
 | 
						|
{ 
 | 
						|
	GameMessage *msg, *next;
 | 
						|
 | 
						|
	for( msg = list; msg; msg = next )
 | 
						|
	{
 | 
						|
		next = msg->next();
 | 
						|
		appendMessage( msg );
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
/**
 | 
						|
 * Given an "anchor" point and the current mouse position (dest),
 | 
						|
 * construct a valid 2D bounding region.
 | 
						|
 */
 | 
						|
void buildRegion( const ICoord2D *anchor, const ICoord2D *dest, IRegion2D *region )
 | 
						|
{
 | 
						|
	// build rectangular region defined by the drag selection
 | 
						|
	if (anchor->x < dest->x)
 | 
						|
	{
 | 
						|
		region->lo.x = anchor->x;
 | 
						|
		region->hi.x = dest->x;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		region->lo.x = dest->x;
 | 
						|
		region->hi.x = anchor->x;
 | 
						|
	}
 | 
						|
 | 
						|
	if (anchor->y < dest->y)
 | 
						|
	{
 | 
						|
		region->lo.y = anchor->y;
 | 
						|
		region->hi.y = dest->y;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		region->lo.y = dest->y;
 | 
						|
		region->hi.y = anchor->y;
 | 
						|
	}
 | 
						|
}
 |