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,26 @@
/*
** 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. //
// //
////////////////////////////////////////////////////////////////////////////////
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine

View file

@ -0,0 +1,133 @@
/*
** 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: AnimatedParticleSysBoneClientUpdate.cpp //////////////////////////////////////////////////////////////////
// Author: Mark Lorenzen, October 2002
// Desc: client update module to translate particle systems with animation
///////////////////////////////////////////////////////////////////////////////////////////////////
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
#include "GameClient/Drawable.h"
#include "GameClient/Module/AnimatedParticleSysBoneClientUpdate.h"
#include "Common/Player.h"
#include "Common/PlayerList.h"
#include "Common/ThingFactory.h"
#include "Common/ThingTemplate.h"
#include "Common/RandomValue.h"
#include "Common/DrawModule.h"
#include "Common/PerfTimer.h"
#include "Common/Xfer.h"
#include "GameLogic/Object.h"
#include "GameLogic/ScriptEngine.h"
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
AnimatedParticleSysBoneClientUpdate::AnimatedParticleSysBoneClientUpdate( Thing *thing, const ModuleData* moduleData ) :
ClientUpdateModule( thing, moduleData )
{
m_life = 0;
}
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
AnimatedParticleSysBoneClientUpdate::~AnimatedParticleSysBoneClientUpdate( void )
{
}
//-------------------------------------------------------------------------------------------------
/** The client update callback. */
//-------------------------------------------------------------------------------------------------
void AnimatedParticleSysBoneClientUpdate::clientUpdate( void )
{
//THIS IS HAPPENING CLIENT-SIDE
// I CAN DO WHAT I NEED HERE AND NOT HAVE TO BE LOGIC SYNC-SAFE
++m_life;
Drawable *draw = getDrawable();
if (draw)
{
for (DrawModule** dm = draw->getDrawModules(); *dm; ++dm)
{
ObjectDrawInterface* di = (*dm)->getObjectDrawInterface();
if (di)
{
if (di->updateBonesForClientParticleSystems())
break;
}
}
}
}
// ------------------------------------------------------------------------------------------------
/** CRC */
// ------------------------------------------------------------------------------------------------
void AnimatedParticleSysBoneClientUpdate::crc( Xfer *xfer )
{
// extend base class
ClientUpdateModule::crc( xfer );
} // end crc
// ------------------------------------------------------------------------------------------------
/** Xfer method
* Version Info:
* 1: Initial version */
// ------------------------------------------------------------------------------------------------
void AnimatedParticleSysBoneClientUpdate::xfer( Xfer *xfer )
{
// version
XferVersion currentVersion = 1;
XferVersion version = currentVersion;
xfer->xferVersion( &version, currentVersion );
// extend base class
ClientUpdateModule::xfer( xfer );
} // end xfer
// ------------------------------------------------------------------------------------------------
/** Load post process */
// ------------------------------------------------------------------------------------------------
void AnimatedParticleSysBoneClientUpdate::loadPostProcess( void )
{
// extend base class
ClientUpdateModule::loadPostProcess();
} // end loadPostProcess

View file

@ -0,0 +1,230 @@
/*
** 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: BeaconClientUpdate.cpp //////////////////////////////////////////////////////////////////
// Author: Matthew D. Campbell, August 2002
// Desc: Beacon client update module
///////////////////////////////////////////////////////////////////////////////////////////////////
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine
#include "GameClient/Drawable.h"
#include "GameClient/ParticleSys.h"
#include "GameClient/Module/BeaconClientUpdate.h"
#include "Common/Player.h"
#include "Common/PlayerList.h"
#include "Common/Radar.h"
#include "Common/Xfer.h"
#include "GameLogic/GameLogic.h"
//-------------------------------------------------------------------------------------------------
BeaconClientUpdateModuleData::BeaconClientUpdateModuleData() :
m_framesBetweenRadarPulses(30),
m_radarPulseDuration(15)
{
}
//-------------------------------------------------------------------------------------------------
BeaconClientUpdateModuleData::~BeaconClientUpdateModuleData()
{
}
//-------------------------------------------------------------------------------------------------
void BeaconClientUpdateModuleData::buildFieldParse(MultiIniFieldParse& p)
{
ClientUpdateModuleData::buildFieldParse(p);
static const FieldParse dataFieldParse[] =
{
{ "RadarPulseFrequency", INI::parseDurationUnsignedInt, NULL, offsetof(BeaconClientUpdateModuleData, m_framesBetweenRadarPulses) },
{ "RadarPulseDuration", INI::parseDurationUnsignedInt, NULL, offsetof(BeaconClientUpdateModuleData, m_radarPulseDuration) },
{ 0, 0, 0, 0 }
};
p.add(dataFieldParse);
}
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
BeaconClientUpdate::BeaconClientUpdate( Thing *thing, const ModuleData* moduleData ) :
ClientUpdateModule( thing, moduleData ),
m_particleSystemID(INVALID_PARTICLE_SYSTEM_ID),
m_lastRadarPulse(TheGameLogic->getFrame())
{
}
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
BeaconClientUpdate::~BeaconClientUpdate( void )
{
}
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
static ParticleSystem* createParticleSystem( Drawable *draw )
{
ParticleSystem *system = NULL;
if (draw)
{
Object *obj = draw->getObject();
if (obj)
{
AsciiString templateName;
templateName.format("BeaconSmoke%6.6X", (0xffffff & obj->getIndicatorColor()));
const ParticleSystemTemplate *particleTemplate = TheParticleSystemManager->findTemplate( templateName );
DEBUG_ASSERTCRASH(particleTemplate, ("Could not find particle system %s\n", templateName.str()));
if (particleTemplate)
{
system = TheParticleSystemManager->createParticleSystem( particleTemplate );
if (system)
system->attachToDrawable( draw );
}
else// This is a failsafe... if someone has monkeyed with the particle system names, or the MP house colors
{// THis this will whip up a new particle system to match the house color provided
templateName.format("BeaconSmokeFFFFFF");
const ParticleSystemTemplate *failsafeTemplate = TheParticleSystemManager->findTemplate( templateName );
DEBUG_ASSERTCRASH(failsafeTemplate, ("Doh, this is bad \n I Could not even find the white particle system to make a failsafe system out of."));
if (failsafeTemplate)
{
system = TheParticleSystemManager->createParticleSystem( failsafeTemplate );
if (system)
{
system->attachToDrawable( draw );
system->tintAllColors( obj->getIndicatorColor() );
}
}
}
}
}
return system;
}
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
void BeaconClientUpdate::hideBeacon( void )
{
Drawable *draw = getDrawable();
if (draw)
{
draw->setDrawableHidden( true );
draw->setShadowsEnabled( false );
}
ParticleSystem *system;
if (draw && m_particleSystemID == INVALID_PARTICLE_SYSTEM_ID)
{
system = createParticleSystem( draw );
if (system)
m_particleSystemID = system->getSystemID();
}
// clean up particle system
if (m_particleSystemID != INVALID_PARTICLE_SYSTEM_ID)
{
ParticleSystem *system = TheParticleSystemManager->findParticleSystem( m_particleSystemID );
if( system )
system->stop();
} // end if
// DEBUG_LOG(("in hideBeacon(): draw=%d, m_particleSystemID=%d\n", draw, m_particleSystemID));
}
//-------------------------------------------------------------------------------------------------
/** The client update callback. */
//-------------------------------------------------------------------------------------------------
void BeaconClientUpdate::clientUpdate( void )
{
Drawable *draw = getDrawable();
if (!draw)
return;
if (m_particleSystemID == INVALID_PARTICLE_SYSTEM_ID)
{
ParticleSystem *system = createParticleSystem( draw );
if( system )
m_particleSystemID = system->getSystemID();
}
if (!draw->isDrawableEffectivelyHidden())
{
BeaconClientUpdateModuleData *moduleData = (BeaconClientUpdateModuleData *)getModuleData();
if (TheGameLogic->getFrame() > m_lastRadarPulse + moduleData->m_framesBetweenRadarPulses)
{
TheRadar->createEvent( draw->getPosition(), RADAR_EVENT_BEACON_PULSE, moduleData->m_radarPulseDuration * SECONDS_PER_LOGICFRAME_REAL );
m_lastRadarPulse = TheGameLogic->getFrame();
}
}
}
// ------------------------------------------------------------------------------------------------
/** CRC */
// ------------------------------------------------------------------------------------------------
void BeaconClientUpdate::crc( Xfer *xfer )
{
// extend base class
ClientUpdateModule::crc( xfer );
} // end crc
// ------------------------------------------------------------------------------------------------
/** Xfer method
* Version Info:
* 1: Initial version */
// ------------------------------------------------------------------------------------------------
void BeaconClientUpdate::xfer( Xfer *xfer )
{
// version
XferVersion currentVersion = 1;
XferVersion version = currentVersion;
xfer->xferVersion( &version, currentVersion );
// extend base class
ClientUpdateModule::xfer( xfer );
// particle system ID
xfer->xferUser( &m_particleSystemID, sizeof( ParticleSystemID ) );
// last radar pulse
xfer->xferUnsignedInt( &m_lastRadarPulse );
} // end xfer
// ------------------------------------------------------------------------------------------------
/** Load post process */
// ------------------------------------------------------------------------------------------------
void BeaconClientUpdate::loadPostProcess( void )
{
// extend base class
ClientUpdateModule::loadPostProcess();
} // end loadPostProcess

View file

@ -0,0 +1,205 @@
/*
** 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: SwayClientUpdate.cpp //////////////////////////////////////////////////////////////////
// Author: Matthew D. Campbell, May 2002
// Desc: Tree sway client update module
///////////////////////////////////////////////////////////////////////////////////////////////////
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
#include "GameClient/Drawable.h"
#include "GameClient/Module/SwayClientUpdate.h"
#include "Common/Player.h"
#include "Common/PlayerList.h"
#include "Common/ThingFactory.h"
#include "Common/ThingTemplate.h"
#include "Common/RandomValue.h"
#include "Common/PerfTimer.h"
#include "Common/Xfer.h"
#include "GameLogic/Object.h"
#include "GameLogic/ScriptEngine.h"
#include "GameLogic/GameLogic.h"
#ifdef _INTERNAL
// for occasional debugging...
//#pragma optimize("", off)
//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
#endif
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
SwayClientUpdate::SwayClientUpdate( Thing *thing, const ModuleData* moduleData ) :
ClientUpdateModule( thing, moduleData ),
m_curDelta(0),
m_curValue(0),
m_curAngle(0),
m_curAngleLimit(0),
m_leanAngle(0),
m_swaying(true),
m_unused(false),
m_curVersion(-1) // so that we never match the first time
{
// don't do updateSway here; wait till the first time we go thru our update loop.
//updateSway();
}
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
SwayClientUpdate::~SwayClientUpdate( void )
{
}
//-------------------------------------------------------------------------------------------------
// Update the sway parameters.
//-------------------------------------------------------------------------------------------------
void SwayClientUpdate::updateSway()
{
const BreezeInfo& info = TheScriptEngine->getBreezeInfo();
if (info.m_randomness == 0.0f)
{
m_curValue = 0;
}
Real delta = info.m_randomness * 0.5f;
m_curAngleLimit = info.m_intensity * GameClientRandomValueReal(1.0f-delta, 1.0f+delta);
m_curDelta = 2*PI/info.m_breezePeriod * GameClientRandomValueReal(1.0f-delta, 1.0f+delta);
m_leanAngle = info.m_lean * GameClientRandomValueReal(1.0f-delta, 1.0f+delta);
m_curVersion = info.m_breezeVersion;
}
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
/** The client update callback. */
//-------------------------------------------------------------------------------------------------
void SwayClientUpdate::clientUpdate( void )
{
if( !m_swaying )
return;
Drawable *draw = getDrawable();
// if breeze changes, always process the full update, even if not visible,
// so that things offscreen won't 'pop' when first viewed
const BreezeInfo& info = TheScriptEngine->getBreezeInfo();
if (info.m_breezeVersion != m_curVersion)
{
updateSway();
}
else
{
// Otherwise, only update visible drawables
if (!draw || !draw->isVisible())
return;
}
m_curValue += m_curDelta;
if (m_curValue > 2*PI)
m_curValue -= 2*PI;
Real cosine = Cos(m_curValue);
Real targetAngle = cosine * m_curAngleLimit + m_leanAngle;
Real deltaAngle = targetAngle - m_curAngle;
Matrix3D xfrm = *draw->getInstanceMatrix();
xfrm.In_Place_Pre_Rotate_X(-deltaAngle * info.m_directionVec.x);
xfrm.In_Place_Pre_Rotate_Y(deltaAngle * info.m_directionVec.y);
draw->setInstanceMatrix(&xfrm);
m_curAngle = targetAngle;
// burned things don't sway.
Object* obj = draw->getObject();
if (obj && (obj->getStatusBits() & OBJECT_STATUS_BURNED) != 0)
stopSway();
}
// ------------------------------------------------------------------------------------------------
/** CRC */
// ------------------------------------------------------------------------------------------------
void SwayClientUpdate::crc( Xfer *xfer )
{
// extend base class
ClientUpdateModule::crc( xfer );
} // end crc
// ------------------------------------------------------------------------------------------------
/** Xfer method
* Version Info:
* 1: Initial version */
// ------------------------------------------------------------------------------------------------
void SwayClientUpdate::xfer( Xfer *xfer )
{
// version
XferVersion currentVersion = 1;
XferVersion version = currentVersion;
xfer->xferVersion( &version, currentVersion );
// extend base class
ClientUpdateModule::xfer( xfer );
// cur value
xfer->xferReal( &m_curValue );
// cur angle
xfer->xferReal( &m_curAngle );
// cur delta
xfer->xferReal( &m_curDelta );
// cur angle limit
xfer->xferReal( &m_curAngleLimit );
// lean angle
xfer->xferReal( &m_leanAngle );
// cur version
xfer->xferShort( &m_curVersion );
// swaying
xfer->xferBool( &m_swaying );
} // end xfer
// ------------------------------------------------------------------------------------------------
/** Load post process */
// ------------------------------------------------------------------------------------------------
void SwayClientUpdate::loadPostProcess( void )
{
// extend base class
ClientUpdateModule::loadPostProcess();
updateSway();
} // end loadPostProcess