Initial commit of Command & Conquer Generals and Command & Conquer Generals Zero Hour source code.

This commit is contained in:
LFeenanEA 2025-02-27 17:34:39 +00:00
parent 2e338c00cb
commit 3d0ee53a05
No known key found for this signature in database
GPG key ID: C6EBE8C2EA08F7E0
6072 changed files with 2283311 additions and 0 deletions

View file

@ -0,0 +1,458 @@
/*
** Command & Conquer Generals(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. //
// //
////////////////////////////////////////////////////////////////////////////////
// FILE: TerrainRoads.cpp /////////////////////////////////////////////////////////////////////////
// Author: Colin Day, December 2001
// Desc: Terrain road/bridge descriptions
///////////////////////////////////////////////////////////////////////////////////////////////////
// INCLDUES ///////////////////////////////////////////////////////////////////////////////////////
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
#define DEFINE_BODYDAMAGETYPE_NAMES
#include "Common/INI.h"
#include "GameClient/TerrainRoads.h"
// PUBLIC DATA ////////////////////////////////////////////////////////////////////////////////////
TerrainRoadCollection *TheTerrainRoads = NULL;
// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
UnsignedInt TerrainRoadCollection::m_idCounter = 0;
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
const FieldParse TerrainRoadType::m_terrainRoadFieldParseTable[] =
{
{ "Texture", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_texture ) },
{ "RoadWidth", INI::parseReal, NULL, offsetof( TerrainRoadType, m_roadWidth ) },
{ "RoadWidthInTexture", INI::parseReal, NULL, offsetof( TerrainRoadType, m_roadWidthInTexture ) },
{ NULL, NULL, NULL, 0 },
};
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
const FieldParse TerrainRoadType::m_terrainBridgeFieldParseTable[] =
{
{ "BridgeScale", INI::parseReal, NULL, offsetof( TerrainRoadType, m_bridgeScale ) },
{ "ScaffoldObjectName", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_scaffoldObjectName ) },
{ "ScaffoldSupportObjectName", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_scaffoldSupportObjectName ) },
{ "RadarColor", INI::parseRGBColor, NULL, offsetof( TerrainRoadType, m_radarColor ) },
{ "TransitionEffectsHeight", INI::parseReal, NULL, offsetof( TerrainRoadType, m_transitionEffectsHeight ) },
{ "NumFXPerType", INI::parseInt, NULL, offsetof( TerrainRoadType, m_numFXPerType ) },
{ "BridgeModelName", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_bridgeModelName ) },
{ "Texture", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_texture ) },
{ "BridgeModelNameDamaged", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_bridgeModelNameDamaged ) },
{ "TextureDamaged", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_textureDamaged ) },
{ "BridgeModelNameReallyDamaged", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_bridgeModelNameReallyDamaged ) },
{ "TextureReallyDamaged", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_textureReallyDamaged ) },
{ "BridgeModelNameBroken", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_bridgeModelNameBroken ) },
{ "TextureBroken", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_textureBroken ) },
{ "TowerObjectNameFromLeft", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_towerObjectName[ BRIDGE_TOWER_FROM_LEFT ] ) },
{ "TowerObjectNameFromRight", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_towerObjectName[ BRIDGE_TOWER_FROM_RIGHT ] ) },
{ "TowerObjectNameToLeft", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_towerObjectName[ BRIDGE_TOWER_TO_LEFT ] ) },
{ "TowerObjectNameToRight", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_towerObjectName[ BRIDGE_TOWER_TO_RIGHT ] ) },
{ "DamagedToSound", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_damageToSoundString[ BODY_DAMAGED ] ) },
{ "RepairedToSound", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_repairedToSoundString[ BODY_DAMAGED ] ) },
{ "TransitionToOCL", parseTransitionToOCL, NULL, NULL },
{ "TransitionToFX", parseTransitionToFX, NULL, NULL },
{ NULL, NULL, NULL, 0 },
};
// ------------------------------------------------------------------------------------------------
/** In the form of
* Label = Transition:<Damage|Repair> ToState:<BODYTYPE> EffectNum:<INT> OCL:<OCL NAME> */
// ------------------------------------------------------------------------------------------------
/*static*/ void TerrainRoadType::parseTransitionToOCL( INI *ini,
void *instance,
void *store,
const void *userData )
{
const char *token;
TerrainRoadType *theInstance = (TerrainRoadType *)instance;
// which transition is this
Bool damageTransition;
token = ini->getNextSubToken( "Transition" );
if( stricmp( token, "Damage" ) == 0 )
damageTransition = TRUE;
else if( stricmp( token, "Repair" ) == 0 )
damageTransition = FALSE;
else
{
DEBUG_CRASH(( "Expected Damage/Repair transition keyword\n" ));
throw INI_INVALID_DATA;
} // end else
// get body damage state
token = ini->getNextSubToken( "ToState" );
BodyDamageType state = (BodyDamageType)ini->scanIndexList( token, TheBodyDamageTypeNames );
// get effect num
token = ini->getNextSubToken( "EffectNum" );
Int effectNum = ini->scanInt( token );
// make effectNum zero based
--effectNum;
// sanity check effect num
if( effectNum < 0 || effectNum >= MAX_BRIDGE_BODY_FX )
{
DEBUG_CRASH(( "Effect number max on bridge transitions is '%d'\n", MAX_BRIDGE_BODY_FX ));
throw INI_INVALID_DATA;
} // end if
// read the string
token = ini->getNextSubToken( "OCL" );
if( damageTransition )
theInstance->friend_setDamageToOCLString( state, effectNum, AsciiString( token ) );
else
theInstance->friend_setRepairedToOCLString( state, effectNum, AsciiString( token ) );
} // end parseTransitionToOCL
// ------------------------------------------------------------------------------------------------
/** In the form of
* Label = Transition:<Damage|Repair> ToState:<BODYTYPE> EffectNum:<INT> FX:<FXLIST NAME> */
// ------------------------------------------------------------------------------------------------
/*static*/ void TerrainRoadType::parseTransitionToFX( INI *ini,
void *instance,
void *store,
const void *userData )
{
const char *token;
TerrainRoadType *theInstance = (TerrainRoadType *)instance;
// which transition is this
Bool damageTransition;
token = ini->getNextSubToken( "Transition" );
if( stricmp( token, "Damage" ) == 0 )
damageTransition = TRUE;
else if( stricmp( token, "Repair" ) == 0 )
damageTransition = FALSE;
else
{
DEBUG_CRASH(( "Expected Damage/Repair transition keyword\n" ));
throw INI_INVALID_DATA;
} // end else
// get body damage state
token = ini->getNextSubToken( "ToState" );
BodyDamageType state = (BodyDamageType)ini->scanIndexList( token, TheBodyDamageTypeNames );
// get effect num
token = ini->getNextSubToken( "EffectNum" );
Int effectNum = ini->scanInt( token );
// make effectNum zero based
--effectNum;
// sanity check effect num
if( effectNum < 0 || effectNum >= MAX_BRIDGE_BODY_FX )
{
DEBUG_CRASH(( "Effect number max on bridge transitions is '%d'\n", MAX_BRIDGE_BODY_FX ));
throw INI_INVALID_DATA;
} // end if
// read the string
token = ini->getNextSubToken( "FX" );
if( damageTransition )
theInstance->friend_setDamageToFXString( state, effectNum, AsciiString( token ) );
else
theInstance->friend_setRepairedToFXString( state, effectNum, AsciiString( token ) );
} // end parseTransitionToFX
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
TerrainRoadType::TerrainRoadType( void )
{
m_isBridge = FALSE;
m_id = 0;
m_next = NULL;
m_roadWidth = 0.0f;
m_roadWidthInTexture = 0.0f;
m_bridgeScale = 1.0f;
m_radarColor.red = 0.0f;
m_radarColor.green = 0.0f;
m_radarColor.blue = 0.0f;
m_transitionEffectsHeight = 0.0f;
m_numFXPerType = 0;
} // end TerrainRoadType
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
TerrainRoadType::~TerrainRoadType( void )
{
} // end ~TerrainRoadType
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
TerrainRoadCollection::TerrainRoadCollection( void )
{
m_roadList = NULL;
m_bridgeList = NULL;
m_idCounter = 1; ///< MUST start this at 1.
} // end TerrainRoadCollection
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
TerrainRoadCollection::~TerrainRoadCollection( void )
{
TerrainRoadType *temp;
// delete all roads in the list
while( m_roadList )
{
// get next road
temp = m_roadList->friend_getNext();
// delete this road
m_roadList->deleteInstance();
// set the new head of the list
m_roadList = temp;
} // end while
// delete all bridges in the list
while( m_bridgeList )
{
// get next bridge
temp = m_bridgeList->friend_getNext();
// delete this bridge
m_bridgeList->deleteInstance();
// set the new head of the list
m_bridgeList = temp;
} // end while
} // end ~TerrainRoadCollection
//-------------------------------------------------------------------------------------------------
/** Find road with matching name */
//-------------------------------------------------------------------------------------------------
TerrainRoadType *TerrainRoadCollection::findRoad( AsciiString name )
{
TerrainRoadType *road;
for( road = m_roadList; road; road = nextRoad( road ) )
{
if( road->getName() == name )
return road;
} // end for road
// not found
return NULL;
} // end findRoad
//-------------------------------------------------------------------------------------------------
/** Find bridge with matching name */
//-------------------------------------------------------------------------------------------------
TerrainRoadType *TerrainRoadCollection::findBridge( AsciiString name )
{
TerrainRoadType *bridge;
for( bridge = m_bridgeList; bridge; bridge = nextBridge( bridge ) )
{
if( bridge->getName() == name )
return bridge;
} // end for bridge
// not found
return NULL;
} // end findBridge
//-------------------------------------------------------------------------------------------------
/** Search the roads AND bridge lists for the name */
//-------------------------------------------------------------------------------------------------
TerrainRoadType *TerrainRoadCollection::findRoadOrBridge( AsciiString name )
{
TerrainRoadType *road = findRoad( name );
if( road )
return road;
else
return findBridge( name );
} // end findRoadOrBridge
//-------------------------------------------------------------------------------------------------
/** Allocate a new road, set the name, and link to the road list */
//-------------------------------------------------------------------------------------------------
TerrainRoadType *TerrainRoadCollection::newRoad( AsciiString name )
{
TerrainRoadType *road = newInstance(TerrainRoadType);
// assign the name
road->friend_setName( name );
// assign unique id
road->friend_setID( m_idCounter++ );
// is not a bridge
road->friend_setBridge( FALSE );
// set defaults from the default road
TerrainRoadType *defaultRoad = findRoad( AsciiString( "DefaultRoad" ) );
if( defaultRoad )
{
road->friend_setTexture( defaultRoad->getTexture() );
road->friend_setRoadWidth( defaultRoad->getRoadWidth() );
road->friend_setRoadWidthInTexture( defaultRoad->getRoadWidthInTexture() );
} // end if
// link to list
road->friend_setNext( m_roadList );
m_roadList = road;
// return the new road
return road;
} // end newRoad
//-------------------------------------------------------------------------------------------------
/** Allocate a new bridge */
//-------------------------------------------------------------------------------------------------
TerrainRoadType *TerrainRoadCollection::newBridge( AsciiString name )
{
TerrainRoadType *bridge = newInstance(TerrainRoadType);
// assign the name
bridge->friend_setName( name );
// assign unique id
bridge->friend_setID( m_idCounter++ );
// is a bridge
bridge->friend_setBridge( TRUE );
// set defaults from the default bridge
TerrainRoadType *defaultBridge = findBridge( AsciiString( "DefaultBridge" ) );
if( defaultBridge )
{
bridge->friend_setTexture( defaultBridge->getTexture() );
bridge->friend_setBridgeScale( defaultBridge->getBridgeScale() );
bridge->friend_setBridgeModelName( defaultBridge->getBridgeModel() );
bridge->friend_setBridgeModelNameDamaged( defaultBridge->getBridgeModelNameDamaged() );
bridge->friend_setBridgeModelNameReallyDamaged( defaultBridge->getBridgeModelNameReallyDamaged() );
bridge->friend_setBridgeModelNameBroken( defaultBridge->getBridgeModelNameBroken() );
bridge->friend_setTextureDamaged( defaultBridge->getTextureDamaged() );
bridge->friend_setTextureReallyDamaged( defaultBridge->getTextureReallyDamaged() );
bridge->friend_setTextureBroken( defaultBridge->getTextureBroken() );
bridge->friend_setTransitionEffectsHeight( defaultBridge->getTransitionEffectsHeight() );
bridge->friend_setNumFXPerType( defaultBridge->getNumFXPerType() );
for( Int state = BODY_PRISTINE; state < BODYDAMAGETYPE_COUNT; state++ )
{
bridge->friend_setDamageToSoundString( (BodyDamageType)state, bridge->getDamageToSoundString( (BodyDamageType)state ) );
bridge->friend_setRepairedToSoundString( (BodyDamageType)state, bridge->getRepairedToSoundString( (BodyDamageType)state ) );
for( Int i = 0; i < MAX_BRIDGE_BODY_FX; i++ )
{
bridge->friend_setDamageToOCLString( (BodyDamageType)state, i, bridge->getDamageToOCLString( (BodyDamageType)state, i ) );
bridge->friend_setDamageToFXString( (BodyDamageType)state, i, bridge->getDamageToOCLString( (BodyDamageType)state, i ) );
bridge->friend_setRepairedToOCLString( (BodyDamageType)state, i, bridge->getDamageToOCLString( (BodyDamageType)state, i ) );
bridge->friend_setRepairedToFXString( (BodyDamageType)state, i, bridge->getDamageToOCLString( (BodyDamageType)state, i ) );
} // end for i
} // end for
} // end if
// link to list
bridge->friend_setNext( m_bridgeList );
m_bridgeList = bridge;
// return the new bridge
return bridge;
} // end newBridge
//-------------------------------------------------------------------------------------------------
/** Return next road in list */
//-------------------------------------------------------------------------------------------------
TerrainRoadType *TerrainRoadCollection::nextRoad( TerrainRoadType *road )
{
DEBUG_ASSERTCRASH( road->isBridge() == FALSE, ("nextRoad: road not a road\n") );
return road->friend_getNext();
} // end nextRoad
//-------------------------------------------------------------------------------------------------
/** Return next bridge in list */
//-------------------------------------------------------------------------------------------------
TerrainRoadType *TerrainRoadCollection::nextBridge( TerrainRoadType *bridge )
{
DEBUG_ASSERTCRASH( bridge->isBridge() == TRUE, ("nextBridge, bridge is not a bridge\n") );
return bridge->friend_getNext();
} // end nextBridge

View file

@ -0,0 +1,126 @@
/*
** Command & Conquer Generals(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. //
// //
////////////////////////////////////////////////////////////////////////////////
// FILE: TerrainVisual.cpp ////////////////////////////////////////////////////////////////////////
// Interface for visual representation of terrain on the client
// Author: Colin Day, April 2001
///////////////////////////////////////////////////////////////////////////////////////////////////
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
#include "Common/Xfer.h"
#include "GameClient/TerrainVisual.h"
// GLOBALS ////////////////////////////////////////////////////////////////////////////////////////
TerrainVisual *TheTerrainVisual = NULL;
///////////////////////////////////////////////////////////////////////////////////////////////////
// DEFINITIONS
///////////////////////////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
TerrainVisual::TerrainVisual()
{
} // end TerrainVisual
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
TerrainVisual::~TerrainVisual()
{
} // end ~TerrainVisual
//-------------------------------------------------------------------------------------------------
/** initialize the device independent functionality of the visual terrain */
//-------------------------------------------------------------------------------------------------
void TerrainVisual::init( void )
{
} // end init
//-------------------------------------------------------------------------------------------------
/** Reset */
//-------------------------------------------------------------------------------------------------
void TerrainVisual::reset( void )
{
m_filenameString.clear();
} // end reset
//-------------------------------------------------------------------------------------------------
/** Update */
//-------------------------------------------------------------------------------------------------
void TerrainVisual::update( void )
{
// All the interesting stuff happens in load. jba.
} // end update
//-------------------------------------------------------------------------------------------------
/** device independent implementation for common terrain visual systems */
//-------------------------------------------------------------------------------------------------
Bool TerrainVisual::load( AsciiString filename )
{
// save the filename
if (filename.isEmpty())
return FALSE;
m_filenameString = filename;
return TRUE;; // success
} // end load
// ------------------------------------------------------------------------------------------------
/** CRC */
// ------------------------------------------------------------------------------------------------
void TerrainVisual::crc( Xfer *xfer )
{
} // end CRC
// ------------------------------------------------------------------------------------------------
/** Xfer
* Version Info:
* 1: Initial version */
// ------------------------------------------------------------------------------------------------
void TerrainVisual::xfer( Xfer *xfer )
{
// version
XferVersion currentVersion = 1;
XferVersion version = currentVersion;
xfer->xferVersion( &version, currentVersion );
} // end xfer
// ------------------------------------------------------------------------------------------------
/** Load post process */
// ------------------------------------------------------------------------------------------------
void TerrainVisual::loadPostProcess( void )
{
} // end loadPostProcess