diff --git a/source/glest_game/ai/path_finder.cpp b/source/glest_game/ai/path_finder.cpp index 61cccf15..aec61c56 100644 --- a/source/glest_game/ai/path_finder.cpp +++ b/source/glest_game/ai/path_finder.cpp @@ -173,7 +173,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos){ bool nodeLimitReached= false; Node *node= NULL; - if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + //if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); while(!nodeLimitReached){ @@ -219,7 +219,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos){ } }//while - if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, openNodes.empty() = %d, pathFound = %d, nodeLimitReached = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),openNodes.empty(),pathFound,nodeLimitReached); + if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, openNodes.empty() = %d, pathFound = %d, nodeLimitReached = %d, unit = %s\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),openNodes.empty(),pathFound,nodeLimitReached,unit->getFullName().c_str()); Node *lastNode= node; @@ -232,7 +232,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos){ } } - if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + //if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); //check results of path finding TravelState ts; @@ -261,7 +261,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos){ } } - if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + //if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); //clean nodes openNodes.clear(); diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 55dc554d..bd5da643 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -65,6 +65,8 @@ Game::Game(Program *program, const GameSettings *gameSettings): renderFps=0; lastUpdateFps=0; lastRenderFps=-1; + avgUpdateFps=-1; + avgRenderFps=-1; paused= false; gameOver= false; renderNetworkStatus= false; @@ -556,7 +558,7 @@ void Game::update(){ if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //renderer.updateParticleManager(rsGame,lastRenderFps); renderer.updateParticleManager(rsGame); if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); @@ -665,6 +667,19 @@ void Game::renderWorker() { // ==================== tick ==================== void Game::tick(){ + if(avgUpdateFps == -1) { + avgUpdateFps = updateFps; + } + else { + avgUpdateFps = (avgUpdateFps + updateFps) / 2; + } + if(avgRenderFps == -1) { + avgRenderFps = renderFps; + } + else { + avgRenderFps = (avgRenderFps + renderFps) / 2; + } + lastUpdateFps= updateFps; lastRenderFps= renderFps; updateFps= 0; @@ -1317,15 +1332,15 @@ void Game::render2d(){ string str; if( renderer.getShowDebugUI() == true || (perfLogging == true && difftime(time(NULL),lastRenderLog2d) >= 1)) { - str+= "MouseXY: " + intToStr(mouseX) + "," + intToStr(mouseY)+"\n"; - str+= "PosObjWord: " + intToStr(gui.getPosObjWorld().x) + "," + intToStr(gui.getPosObjWorld().y)+"\n"; - str+= "Render FPS: "+intToStr(lastRenderFps)+"\n"; - str+= "Update FPS: "+intToStr(lastUpdateFps)+"\n"; - str+= "GameCamera pos: "+floatToStr(gameCamera.getPos().x)+","+floatToStr(gameCamera.getPos().y)+","+floatToStr(gameCamera.getPos().z)+"\n"; - str+= "Time: "+floatToStr(world.getTimeFlow()->getTime(),8)+"\n"; - str+= "Triangle count: "+intToStr(renderer.getTriangleCount())+"\n"; - str+= "Vertex count: "+intToStr(renderer.getPointCount())+"\n"; - str+= "Frame count:"+intToStr(world.getFrameCount())+"\n"; + str+= "MouseXY: " + intToStr(mouseX) + "," + intToStr(mouseY)+"\n"; + str+= "PosObjWord: " + intToStr(gui.getPosObjWorld().x) + "," + intToStr(gui.getPosObjWorld().y)+"\n"; + str+= "Render FPS: " + intToStr(lastRenderFps) + "[" + intToStr(avgRenderFps) + "]\n"; + str+= "Update FPS: " + intToStr(lastUpdateFps) + "[" + intToStr(avgUpdateFps) + "]\n"; + str+= "GameCamera pos: " + floatToStr(gameCamera.getPos().x)+","+floatToStr(gameCamera.getPos().y)+","+floatToStr(gameCamera.getPos().z)+"\n"; + str+= "Time: " + floatToStr(world.getTimeFlow()->getTime(),8)+"\n"; + str+= "Triangle count: " + intToStr(renderer.getTriangleCount())+"\n"; + str+= "Vertex count: " + intToStr(renderer.getPointCount())+"\n"; + str+= "Frame count:" + intToStr(world.getFrameCount())+"\n"; //visible quad Quad2i visibleQuad= renderer.getVisibleQuad(); diff --git a/source/glest_game/game/game.h b/source/glest_game/game/game.h index 628ad096..5fb5a4ea 100644 --- a/source/glest_game/game/game.h +++ b/source/glest_game/game/game.h @@ -67,8 +67,8 @@ private: string loadingText; int mouse2d; int mouseX, mouseY; //coords win32Api - int updateFps, lastUpdateFps; - int renderFps, lastRenderFps; + int updateFps, lastUpdateFps, avgUpdateFps; + int renderFps, lastRenderFps, avgRenderFps; bool paused; bool gameOver; bool renderNetworkStatus; diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index 15334203..9ff58312 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -474,8 +474,10 @@ void Renderer::manageParticleSystem(ParticleSystem *particleSystem, ResourceScop particleManager[rs]->manage(particleSystem); } -void Renderer::updateParticleManager(ResourceScope rs){ - particleManager[rs]->update(); +void Renderer::updateParticleManager(ResourceScope rs, int renderFps) { + if(renderFps < 0 || renderFps >= MIN_FPS_NORMAL_RENDERING) { + particleManager[rs]->update(); + } } void Renderer::renderParticleManager(ResourceScope rs){ diff --git a/source/glest_game/graphics/renderer.h b/source/glest_game/graphics/renderer.h index 06986add..60287392 100644 --- a/source/glest_game/graphics/renderer.h +++ b/source/glest_game/graphics/renderer.h @@ -286,7 +286,7 @@ public: Font2D *newFont(ResourceScope rs); TextRenderer2D *getTextRenderer() const {return textRenderer;} void manageParticleSystem(ParticleSystem *particleSystem, ResourceScope rs); - void updateParticleManager(ResourceScope rs); + void updateParticleManager(ResourceScope rs,int renderFps=-1); void renderParticleManager(ResourceScope rs); void swapBuffers(); diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 8a79f25e..af3e53b5 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -904,8 +904,9 @@ bool Unit::update(){ assert(progress<=1.f); //highlight - if(highlight>0.f){ - highlight-= 1.f/(highlightTime*GameConstants::updateFps); + if(highlight>0.f) { + const Game *game = Renderer::getInstance().getGame(); + highlight-= 1.f / (highlightTime * game->getWorld()->getUpdateFps(this->getFactionIndex())); } if(currSkill == NULL) { @@ -936,8 +937,9 @@ bool Unit::update(){ //update progresses lastAnimProgress= animProgress; - progress+= (speed*diagonalFactor*heightFactor)/(speedDivider*GameConstants::updateFps); - animProgress+= (currSkill->getAnimSpeed()*heightFactor)/(speedDivider*GameConstants::updateFps); + const Game *game = Renderer::getInstance().getGame(); + progress += (speed * diagonalFactor * heightFactor) / (speedDivider * game->getWorld()->getUpdateFps(this->getFactionIndex())); + animProgress += (currSkill->getAnimSpeed() * heightFactor) / (speedDivider * game->getWorld()->getUpdateFps(this->getFactionIndex())); //update target updateTarget(); @@ -1495,7 +1497,8 @@ void Unit::startDamageParticles(){ if(type->getProperty(UnitType::pBurnable) && fire==NULL){ FireParticleSystem *fps; fps= new FireParticleSystem(200); - fps->setSpeed(2.5f/GameConstants::updateFps); + const Game *game = Renderer::getInstance().getGame(); + fps->setSpeed(2.5f / game->getWorld()->getUpdateFps(this->getFactionIndex())); fps->setPos(getCurrVector()); fps->setRadius(type->getSize()/3.f); fps->setTexture(CoreData::getInstance().getFireTexture()); @@ -1513,7 +1516,8 @@ void Unit::startDamageParticles(){ ups->setDirection(Vec3f(0,1,-0.2f)); ups->setRadius(type->getSize()/3.f); ups->setTexture(CoreData::getInstance().getFireTexture()); - ups->setSpeed(2.0f/GameConstants::updateFps); + const Game *game = Renderer::getInstance().getGame(); + ups->setSpeed(2.0f / game->getWorld()->getUpdateFps(this->getFactionIndex())); ups->setGravity(0.0004f); ups->setEmissionRate(1); ups->setMaxParticleEnergy(150); diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index 7b799358..7388855b 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -48,7 +48,7 @@ World::World(){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); Config &config= Config::getInstance(); - staggeredFactionUpdates = false; + staggeredFactionUpdates = true; ExploredCellsLookupItemCache.clear(); ExploredCellsLookupItemCacheTimer.clear(); ExploredCellsLookupItemCacheTimerCount = 0; @@ -239,24 +239,51 @@ void World::loadScenario(const string &path, Checksum *checksum){ // ==================== misc ==================== void World::updateAllFactionUnits() { + int factionIdxToTick = -1; + //if(staggeredFactionUpdates == true) { + // factionIdxToTick = tickFactionIndex(); + // if(factionIdxToTick < 0) { + // return; + // } + //} + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] factionIdxToTick = %d\n",__FILE__,__FUNCTION__,__LINE__,factionIdxToTick); + //units - for(int i=0; igetUnitCount(); ++j){ - unitUpdater.updateUnit(getFaction(i)->getUnit(j)); + for(int i=0; igetUnitCount(); ++j) { + unitUpdater.updateUnit(getFaction(i)->getUnit(j)); + } } } } void World::underTakeDeadFactionUnits() { + int factionIdxToTick = -1; + if(staggeredFactionUpdates == true) { + factionIdxToTick = tickFactionIndex(); + if(factionIdxToTick < 0) { + return; + } + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] factionIdxToTick = %d\n",__FILE__,__FUNCTION__,__LINE__,factionIdxToTick); + //undertake the dead for(int i=0; igetUnitCount(); - for(int j= unitCount - 1; j >= 0; j--){ - Unit *unit= getFaction(i)->getUnit(j); - if(unit->getToBeUndertaken()) { - unit->undertake(); - delete unit; - //j--; + if(factionIdxToTick == -1 || factionIdxToTick == i) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] factionIdxToTick = %d, i = %d\n",__FILE__,__FUNCTION__,__LINE__,factionIdxToTick,i); + + int unitCount = getFaction(i)->getUnitCount(); + for(int j= unitCount - 1; j >= 0; j--){ + Unit *unit= getFaction(i)->getUnit(j); + if(unit->getToBeUndertaken()) { + unit->undertake(); + delete unit; + //j--; + } } } } @@ -266,7 +293,7 @@ void World::updateAllFactionConsumableCosts() { //food costs for(int i=0; igetResourceTypeCount(); ++i){ const ResourceType *rt= techTree->getResourceType(i); - if(rt->getClass()==rcConsumable && frameCount % (rt->getInterval()*GameConstants::updateFps)==0){ + if(rt->getClass() == rcConsumable && frameCount % (rt->getInterval() * GameConstants::updateFps)==0){ for(int i=0; iapplyCostsOnInterval(); } @@ -288,13 +315,24 @@ void World::update(){ waterEffects.update(); if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - //units - updateAllFactionUnits(); - if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + //bool needToUpdateUnits = true; + //if(staggeredFactionUpdates == true) { + // needToUpdateUnits = (frameCount % (GameConstants::updateFps / GameConstants::maxPlayers) == 0); + //} - //undertake the dead - underTakeDeadFactionUnits(); - if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + //if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + + //if(needToUpdateUnits == true) { + // SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] needToUpdateUnits = %d, frameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,needToUpdateUnits,frameCount); + + //units + updateAllFactionUnits(); + if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + + //undertake the dead + underTakeDeadFactionUnits(); + if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + //} //food costs updateAllFactionConsumableCosts(); @@ -320,6 +358,14 @@ void World::update(){ if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); } +int World::getUpdateFps(int factionIndex) const { + int result = GameConstants::updateFps; + //if(factionIndex != -1 && staggeredFactionUpdates == true) { + // result = (GameConstants::updateFps / GameConstants::maxPlayers); + //} + return result; +} + bool World::canTickFaction(int factionIdx) { int factionUpdateInterval = (GameConstants::updateFps / GameConstants::maxPlayers); int expectedFactionIdx = (frameCount / factionUpdateInterval) -1; @@ -350,7 +396,7 @@ int World::tickFactionIndex() { void World::tick() { int factionIdxToTick = -1; if(staggeredFactionUpdates == true) { - int factionIdxToTick = tickFactionIndex(); + factionIdxToTick = tickFactionIndex(); if(factionIdxToTick < 0) { return; } diff --git a/source/glest_game/world/world.h b/source/glest_game/world/world.h index d84332ef..f6becdea 100644 --- a/source/glest_game/world/world.h +++ b/source/glest_game/world/world.h @@ -190,6 +190,8 @@ public: void setFogOfWar(bool value); std::string DumpWorldToLog(bool consoleBasicInfoOnly = false) const; + int getUpdateFps(int factionIndex) const; + private: void initCells(bool fogOfWar); diff --git a/source/shared_lib/include/graphics/particle.h b/source/shared_lib/include/graphics/particle.h index 752ce533..1d16b9b7 100644 --- a/source/shared_lib/include/graphics/particle.h +++ b/source/shared_lib/include/graphics/particle.h @@ -40,7 +40,7 @@ class Model; // class Particle // ===================================================== -class Particle{ +class Particle { public: //attributes Vec3f pos; @@ -52,6 +52,10 @@ public: int energy; public: + Particle() { + size = 0; + energy = 0; + } //get Vec3f getPos() const {return pos;} Vec3f getLastPos() const {return lastPos;} @@ -94,7 +98,7 @@ protected: protected: - Particle *particles; + std::vector particles; RandomGen random; BlendMode blendMode; @@ -102,7 +106,7 @@ protected: bool active; bool visible; int aliveParticleCount; - int particleCount; + //int particleCount; Texture *texture; diff --git a/source/shared_lib/sources/graphics/particle.cpp b/source/shared_lib/sources/graphics/particle.cpp index 5ce564bb..329eebb9 100644 --- a/source/shared_lib/sources/graphics/particle.cpp +++ b/source/shared_lib/sources/graphics/particle.cpp @@ -12,15 +12,19 @@ #include "math_wrapper.h" #include "particle.h" +#include #include #include #include "util.h" #include "particle_renderer.h" #include "math_util.h" +#include "platform_common.h" #include "leak_dumper.h" +using namespace std; using namespace Shared::Util; +using namespace Shared::PlatformCommon; namespace Shared{ namespace Graphics{ @@ -28,11 +32,14 @@ namespace Shared{ namespace Graphics{ // class ParticleSystem // ===================================================== -ParticleSystem::ParticleSystem(int particleCount){ - +ParticleSystem::ParticleSystem(int particleCount) { //init particle vector blendMode = bmOne; - particles= new Particle[particleCount]; + //particles= new Particle[particleCount]; + particles.clear(); + particles.reserve(300); + particles.resize(1); + state= sPlay; aliveParticleCount=0; active= true; @@ -43,7 +50,8 @@ ParticleSystem::ParticleSystem(int particleCount){ particleObserver= NULL; //params - this->particleCount= particleCount; + //this->particleCount= particleCount; + //this->particleCount= particles.size(); maxParticleEnergy= 250; varParticleEnergy= 50; pos= Vec3f(0.0f); @@ -56,35 +64,38 @@ ParticleSystem::ParticleSystem(int particleCount){ } ParticleSystem::~ParticleSystem(){ - delete [] particles; + //delete [] particles; + particles.clear(); } // =============== VIRTUAL ====================== //updates all living particles and creates new ones -void ParticleSystem::update(){ +void ParticleSystem::update() { + if(aliveParticleCount > particles.size()) { + throw runtime_error("aliveParticleCount >= particles.size()"); + } - if(state!=sPause){ - for(int i=0; i0){ - particles[i]= particles[aliveParticleCount]; + //maintain alive particles at front of the array + if(aliveParticleCount > 0) { + particles[i] = particles[aliveParticleCount-1]; } - } } - if(state!=sFade){ - for(int i=0; i::iterator it; +void ParticleManager::update() { + Chrono chrono; + chrono.start(); - for (it=particleSystems.begin(); it!=particleSystems.end(); it++){ + int particleSystemCount = particleSystems.size(); + int particleCount = 0; + list::iterator it; + for (it=particleSystems.begin(); it!=particleSystems.end(); it++) { + particleCount += (*it)->getAliveParticleCount(); (*it)->update(); - if((*it)->isEmpty()){ + if((*it)->isEmpty()) { delete *it; *it= NULL; } } particleSystems.remove(NULL); + + if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld, particleSystemCount = %d, particleCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),particleSystemCount,particleCount); } void ParticleManager::manage(ParticleSystem *ps){