Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions Core/GameEngine/Include/GameClient/ParticleSys.h
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,8 @@ class ParticleSystemManager : public SubsystemInterface,
virtual void reset() override; ///< reset the manager and all particle systems
virtual void update() override; ///< update all particle systems

virtual Bool isDummy() const { return false; }

virtual Int getOnScreenParticleCount() = 0; ///< returns the number of particles on screen
virtual void setOnScreenParticleCount(int count);

Expand All @@ -761,8 +763,7 @@ class ParticleSystemManager : public SubsystemInterface,
ParticleSystemTemplate *newTemplate( const AsciiString &name );

/// given a template, instantiate a particle system
ParticleSystem *createParticleSystem( const ParticleSystemTemplate *sysTemplate,
Bool createSlaves = TRUE );
ParticleSystem *createParticleSystem( const ParticleSystemTemplate *sysTemplate, Bool createSlaves = TRUE );

/** given a template, instantiate a particle system.
if attachTo is not null, attach the particle system to the given object.
Expand Down Expand Up @@ -835,11 +836,24 @@ class ParticleSystemManager : public SubsystemInterface,
ParticleSystemIDMap m_systemMap; ///< a hash map of all particle systems
};


// TheSuperHackers @feature bobtista 31/01/2026
// ParticleSystemManager that does nothing. Used for Headless Mode.
// Generally does not load particle system templates. Certainly does not create particle systems.
class ParticleSystemManagerDummy : public ParticleSystemManager
{
public:
#if RETAIL_COMPATIBLE_CRC
// Must not overload init to keep loading the particle system templates,
// which are unfortunately needed to preserve the correct logic crc.
Comment thread
Caball009 marked this conversation as resolved.
#else
virtual void init() override {}
virtual void reset() override {}
#endif
virtual void update() override {}

virtual Bool isDummy() const override { return true; }

virtual Int getOnScreenParticleCount() override { return 0; }
virtual void doParticles(RenderInfoClass &rinfo) override {}
virtual void queueParticleRender() override {}
Expand Down
2 changes: 0 additions & 2 deletions Core/GameEngine/Source/Common/ReplaySimulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,6 @@ int ReplaySimulation::simulateReplaysInThisProcess(const std::vector<AsciiString
UnsignedInt totalTimeSec = TheRecorder->getPlaybackFrameCount() / LOGICFRAMES_PER_SECOND;
while (TheRecorder->isPlaybackInProgress())
{
TheGameClient->updateHeadless();

const int progressFrameInterval = 10*60*LOGICFRAMES_PER_SECOND;
if (TheGameLogic->getFrame() != 0 && TheGameLogic->getFrame() % progressFrameInterval == 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ static ParticleSystem* createParticleSystem( Drawable *draw )
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", templateName.str()));

DEBUG_ASSERTCRASH(TheParticleSystemManager->isDummy() || particleTemplate, ("Could not find particle system %s", templateName.str()));
if (particleTemplate)
{
system = TheParticleSystemManager->createParticleSystem( particleTemplate );
Expand All @@ -107,7 +105,7 @@ static ParticleSystem* createParticleSystem( Drawable *draw )
{// 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."));
DEBUG_ASSERTCRASH(TheParticleSystemManager->isDummy() || failsafeTemplate, ("Doh, this is bad \n I Could not even find the white particle system to make a failsafe system out of."));
system = TheParticleSystemManager->createParticleSystem( failsafeTemplate );
if (system)
{
Expand Down
2 changes: 1 addition & 1 deletion Core/GameEngine/Source/GameClient/FXList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ class ParticleSystemFXNugget : public FXNugget
}

const ParticleSystemTemplate *tmp = TheParticleSystemManager->findTemplate(m_name);
DEBUG_ASSERTCRASH(tmp, ("ParticleSystem %s not found",m_name.str()));
DEBUG_ASSERTCRASH(TheParticleSystemManager->isDummy() || tmp, ("ParticleSystem %s not found",m_name.str()));
if (tmp)
{
for (Int i = 0; i < m_count; i++ )
Expand Down
2 changes: 0 additions & 2 deletions Generals/Code/GameEngine/Include/GameClient/GameClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ class GameClient : public SubsystemInterface,

void step(); ///< Do one fixed time step

void updateHeadless();

void addDrawableToLookupTable( Drawable *draw ); ///< add drawable ID to hash lookup table
void removeDrawableFromLookupTable( Drawable *draw ); ///< remove drawable ID from hash lookup table

Expand Down
9 changes: 0 additions & 9 deletions Generals/Code/GameEngine/Source/GameClient/GameClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -750,15 +750,6 @@ void GameClient::step()
TheDisplay->step();
}

void GameClient::updateHeadless()
{
// TheSuperHackers @info helmutbuhler 03/05/2025 bobtista 02/02/2026
// Update particles to prevent accumulation in headless mode. Particles are generated
// during GameLogic and only cleaned up during rendering. update() lets particles finish
// their lifecycle naturally instead of abruptly removing them with reset().
TheParticleSystemManager->update();
}

Bool GameClient::isMovieAbortRequested()
{
if (TheGameEngine)
Expand Down
2 changes: 0 additions & 2 deletions GeneralsMD/Code/GameEngine/Include/GameClient/GameClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@ class GameClient : public SubsystemInterface,

void step(); ///< Do one fixed time step

void updateHeadless();

void addDrawableToLookupTable( Drawable *draw ); ///< add drawable ID to hash lookup table
void removeDrawableFromLookupTable( Drawable *draw ); ///< remove drawable ID from hash lookup table

Expand Down
9 changes: 0 additions & 9 deletions GeneralsMD/Code/GameEngine/Source/GameClient/GameClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -787,15 +787,6 @@ void GameClient::step()
TheDisplay->step();
}

void GameClient::updateHeadless()
{
// TheSuperHackers @info helmutbuhler 03/05/2025 bobtista 02/02/2026
// Update particles to prevent accumulation in headless mode. Particles are generated
// during GameLogic and only cleaned up during rendering. update() lets particles finish
// their lifecycle naturally instead of abruptly removing them with reset().
TheParticleSystemManager->update();
}

Bool GameClient::isMovieAbortRequested()
{
if (TheGameEngine)
Expand Down
Loading