From 6d8e7edcbf3c82f5158ec1d04372589c69fd769a Mon Sep 17 00:00:00 2001 From: "wrenczes@gmail.com" Date: Mon, 8 Nov 2010 07:27:19 +0000 Subject: [PATCH] Improvements against http://code.google.com/p/wagic/issues/detail?id=50, Mana animation slows PSP down. Two things: 1) there was an extremely inefficient implementation in the particle system of a queue where, when particles expired, each expired element would be copied over(replaced) by one at the rear of the container. Depending on the performance of the update, this could range anywhere from 100 to 500 (the max particle count) memcpy operations per update loop. I replaced the flat array with a std::list, and simply pop the unneeded elements when they expire now. This seems to shave ~30% off the time spent in the Update() call. 2) Hardcoded the number of emitters for the mana particles to 60 (the default in the psi file seems to be around 114). This reduces the amount of iterations per tapped mana by just over half, which also helps the performance, and it's not really noticeable - the glow effect is a *tiny* bit more muted, but chances are, if you didn't read this comment, you probably wouldn't have noticed. I've gone from having my psp start lagging noticeably at 8 tapped mana to about 12 - at this point, I think the bigger remaining lag is the fact that when there's a cache miss for a card image, we're doing synchronous i/o on the main thread - the framerate drop this causes is far more noticable than the mana particle lag. --- JGE/include/hge/hgeparticle.h | 25 +-- JGE/lib/psp/libhgetools.a | Bin 35260 -> 35852 bytes JGE/src/hge/hgeparticle.cpp | 354 +++++++++++++++++----------------- projects/mtg/src/GuiMana.cpp | 8 +- 4 files changed, 193 insertions(+), 194 deletions(-) diff --git a/JGE/include/hge/hgeparticle.h b/JGE/include/hge/hgeparticle.h index 68c1e6673..eaa63d9d8 100644 --- a/JGE/include/hge/hgeparticle.h +++ b/JGE/include/hge/hgeparticle.h @@ -17,6 +17,8 @@ #include "hgecolor.h" #include "hgerect.h" +#include + class JQuad; #define MAX_PARTICLES 500 @@ -109,27 +111,28 @@ public: float GetAge() const { return fAge; } void GetPosition(float *x, float *y) const { *x=vecLocation.x; *y=vecLocation.y; } void GetTransposition(float *x, float *y) const { *x=fTx; *y=fTy; } - hgeRect* GetBoundingBox(hgeRect *rect) const { memcpy(rect, &rectBoundingBox, sizeof(hgeRect)); return rect; } + hgeRect* GetBoundingBox(hgeRect *rect) const { memcpy(rect, &rectBoundingBox, sizeof(hgeRect)); return rect; } private: hgeParticleSystem(); //static HGE *hge; - float fAge; - float fEmissionResidue; + float fAge; + float fEmissionResidue; - hgeVector vecPrevLocation; - hgeVector vecLocation; - float fTx, fTy; + hgeVector vecPrevLocation; + hgeVector vecLocation; + float fTx, fTy; - int nParticlesAlive; - hgeRect rectBoundingBox; - bool bUpdateBoundingBox; + int nParticlesAlive; + hgeRect rectBoundingBox; + bool bUpdateBoundingBox; - hgeParticle particles[MAX_PARTICLES]; + typedef std::list ParticleBuffer; + ParticleBuffer mParticleBuffer; - float mTimer; + float mTimer; }; class hgeParticleManager diff --git a/JGE/lib/psp/libhgetools.a b/JGE/lib/psp/libhgetools.a index 4ef9d4d9c496216b0135f7bfad5f9a5b8e6c8a21..3f8f97910cf99a4bfa36231f67ee6bfa2f5bb6d9 100644 GIT binary patch delta 7934 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 delta 7262 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 GNB#@++#S3C diff --git a/JGE/src/hge/hgeparticle.cpp b/JGE/src/hge/hgeparticle.cpp index 5acc34224..2e628e298 100644 --- a/JGE/src/hge/hgeparticle.cpp +++ b/JGE/src/hge/hgeparticle.cpp @@ -29,20 +29,20 @@ unsigned int g_seed=0; void Random_Seed(int seed) { - if(!seed) g_seed=JGE::GetInstance()->GetTime(); - else g_seed=seed; + if(!seed) g_seed=JGE::GetInstance()->GetTime(); + else g_seed=seed; } int Random_Int(int min, int max) { - g_seed=214013*g_seed+2531011; - return min+(g_seed ^ g_seed>>15)%(max-min+1); + g_seed=214013*g_seed+2531011; + return min+(g_seed ^ g_seed>>15)%(max-min+1); } float Random_Float(float min, float max) { - g_seed=214013*g_seed+2531011; - return min+(g_seed>>16)*(1.0f/65535.0f)*(max-min); + g_seed=214013*g_seed+2531011; + return min+(g_seed>>16)*(1.0f/65535.0f)*(max-min); } @@ -50,19 +50,19 @@ float Random_Float(float min, float max) hgeParticleSystem::hgeParticleSystem(const char *filename, JQuad *sprite) { - //void *psi; - //hgeParticleSystemInfo psi; + //void *psi; + //hgeParticleSystemInfo psi; - JFileSystem* fileSys = JFileSystem::GetInstance(); - //hge=hgeCreate(HGE_VERSION); + JFileSystem* fileSys = JFileSystem::GetInstance(); + //hge=hgeCreate(HGE_VERSION); - //psi=hge->Resource_Load(filename); - if (!fileSys->OpenFile(filename)) return; + //psi=hge->Resource_Load(filename); + if (!fileSys->OpenFile(filename)) return; - //if(!psi) return; + //if(!psi) return; - //memcpy(&info, psi, sizeof(hgeParticleSystemInfo)); - //hge->Resource_Free(psi); + //memcpy(&info, psi, sizeof(hgeParticleSystemInfo)); + //hge->Resource_Free(psi); // Skip reading the pointer as it may be larger than 4 bytes in the structure void *dummyPointer; @@ -73,240 +73,234 @@ hgeParticleSystem::hgeParticleSystem(const char *filename, JQuad *sprite) fileSys->ReadFile(&(info.nEmission), sizeof(hgeParticleSystemInfo)); fileSys->CloseFile(); - info.sprite=sprite; -// info.fGravityMin *= 100; -// info.fGravityMax *= 100; -// info.fSpeedMin *= 100; -// info.fSpeedMax *= 100; + info.sprite=sprite; + // info.fGravityMin *= 100; + // info.fGravityMax *= 100; + // info.fSpeedMin *= 100; + // info.fSpeedMax *= 100; - vecLocation.x=vecPrevLocation.x=0.0f; - vecLocation.y=vecPrevLocation.y=0.0f; - fTx=fTy=0; + vecLocation.x=vecPrevLocation.x=0.0f; + vecLocation.y=vecPrevLocation.y=0.0f; + fTx=fTy=0; - fEmissionResidue=0.0f; - nParticlesAlive=0; - fAge=-2.0; - mTimer = 0.0f; + fEmissionResidue=0.0f; + nParticlesAlive=0; + fAge=-2.0; + mTimer = 0.0f; - rectBoundingBox.Clear(); - bUpdateBoundingBox=false; + rectBoundingBox.Clear(); + bUpdateBoundingBox=false; } hgeParticleSystem::hgeParticleSystem(hgeParticleSystemInfo *psi) { - //hge=hgeCreate(HGE_VERSION); + //hge=hgeCreate(HGE_VERSION); - memcpy(&info, psi, sizeof(hgeParticleSystemInfo)); + memcpy(&info, psi, sizeof(hgeParticleSystemInfo)); - vecLocation.x=vecPrevLocation.x=0.0f; - vecLocation.y=vecPrevLocation.y=0.0f; - fTx=fTy=0; + vecLocation.x=vecPrevLocation.x=0.0f; + vecLocation.y=vecPrevLocation.y=0.0f; + fTx=fTy=0; - fEmissionResidue=0.0f; - nParticlesAlive=0; - fAge=-2.0; - mTimer = 0.0f; + fEmissionResidue=0.0f; + nParticlesAlive=0; + fAge=-2.0; + mTimer = 0.0f; - rectBoundingBox.Clear(); - bUpdateBoundingBox=false; + rectBoundingBox.Clear(); + bUpdateBoundingBox=false; } hgeParticleSystem::hgeParticleSystem(const hgeParticleSystem &ps) { - memcpy(this, &ps, sizeof(hgeParticleSystem)); - //hge=hgeCreate(HGE_VERSION); + memcpy(this, &ps, sizeof(hgeParticleSystem)); + //hge=hgeCreate(HGE_VERSION); } void hgeParticleSystem::Update(float fDeltaTime) { - int i; - float ang; - hgeParticle *par; - hgeVector vecAccel, vecAccel2; + int i; + float ang; + hgeVector vecAccel, vecAccel2; - if(fAge >= 0) - { - fAge += fDeltaTime; - if(fAge >= info.fLifetime) fAge = -2.0f; - } + if(fAge >= 0) + { + fAge += fDeltaTime; + if(fAge >= info.fLifetime) fAge = -2.0f; + } - mTimer += fDeltaTime; - if (mTimer < 0.01f) - return; + mTimer += fDeltaTime; + if (mTimer < 0.01f) + return; - fDeltaTime = mTimer; - mTimer = 0.0f; + fDeltaTime = mTimer; + mTimer = 0.0f; - // update all alive particles + // update all alive particles - if(bUpdateBoundingBox) rectBoundingBox.Clear(); - par=particles; + if(bUpdateBoundingBox) rectBoundingBox.Clear(); - for(i=0; ifAge += fDeltaTime; - if(par->fAge >= par->fTerminalAge) - { - nParticlesAlive--; - if (par != &particles[nParticlesAlive]) - memcpy(par, &particles[nParticlesAlive], sizeof(hgeParticle)); - i--; - continue; - } + ParticleBuffer::iterator particle = mParticleBuffer.begin(); + while(particle != mParticleBuffer.end()) + { + particle->fAge += fDeltaTime; + if(particle->fAge >= particle->fTerminalAge) + { + nParticlesAlive--; + ++particle; + mParticleBuffer.pop_front(); + continue; + } - vecAccel = par->vecLocation-vecLocation; - vecAccel.Normalize(); - vecAccel2 = vecAccel; - vecAccel *= par->fRadialAccel; + vecAccel = particle->vecLocation-vecLocation; + vecAccel.Normalize(); + vecAccel2 = vecAccel; + vecAccel *= particle->fRadialAccel; - // vecAccel2.Rotate(M_PI_2); - // the following is faster - ang = vecAccel2.x; - vecAccel2.x = -vecAccel2.y; - vecAccel2.y = ang; + // vecAccel2.Rotate(M_PI_2); + // the following is faster + ang = vecAccel2.x; + vecAccel2.x = -vecAccel2.y; + vecAccel2.y = ang; - vecAccel2 *= par->fTangentialAccel; - par->vecVelocity += (vecAccel+vecAccel2)*fDeltaTime; - par->vecVelocity.y += par->fGravity*fDeltaTime; + vecAccel2 *= particle->fTangentialAccel; + particle->vecVelocity += (vecAccel+vecAccel2)*fDeltaTime; + particle->vecVelocity.y += particle->fGravity*fDeltaTime; - //par->vecVelocity.y = 0.1f; - par->vecLocation += par->vecVelocity; + //par->vecVelocity.y = 0.1f; + particle->vecLocation += particle->vecVelocity; - par->fSpin += par->fSpinDelta*fDeltaTime; - par->fSize += par->fSizeDelta*fDeltaTime; - par->colColor += par->colColorDelta*fDeltaTime; + particle->fSpin += particle->fSpinDelta*fDeltaTime; + particle->fSize += particle->fSizeDelta*fDeltaTime; + particle->colColor += particle->colColorDelta*fDeltaTime; - if(bUpdateBoundingBox) rectBoundingBox.Encapsulate(par->vecLocation.x, par->vecLocation.y); + if(bUpdateBoundingBox) rectBoundingBox.Encapsulate(particle->vecLocation.x, particle->vecLocation.y); - par++; - } + ++particle; + } - // generate new particles + // generate new particles - if(fAge != -2.0f) - { - float fParticlesNeeded = info.nEmission*fDeltaTime + fEmissionResidue; - int nParticlesCreated = (unsigned int)fParticlesNeeded; - fEmissionResidue=fParticlesNeeded-nParticlesCreated; + if(fAge != -2.0f) + { + float fParticlesNeeded = info.nEmission*fDeltaTime + fEmissionResidue; + int nParticlesCreated = (unsigned int)fParticlesNeeded; + fEmissionResidue=fParticlesNeeded-nParticlesCreated; - par=&particles[nParticlesAlive]; + for(i=0; i=MAX_PARTICLES) break; - for(i=0; i=MAX_PARTICLES) break; + hgeParticle newParticle; + newParticle.fAge = 0.0f; + newParticle.fTerminalAge = Random_Float(info.fParticleLifeMin, info.fParticleLifeMax); - par->fAge = 0.0f; - par->fTerminalAge = Random_Float(info.fParticleLifeMin, info.fParticleLifeMax); + newParticle.vecLocation = vecPrevLocation+(vecLocation-vecPrevLocation)*Random_Float(0.0f, 1.0f); + newParticle.vecLocation.x += Random_Float(-2.0f, 2.0f); + newParticle.vecLocation.y += Random_Float(-2.0f, 2.0f); - par->vecLocation = vecPrevLocation+(vecLocation-vecPrevLocation)*Random_Float(0.0f, 1.0f); - par->vecLocation.x += Random_Float(-2.0f, 2.0f); - par->vecLocation.y += Random_Float(-2.0f, 2.0f); + ang=info.fDirection-M_PI_2+Random_Float(0,info.fSpread)-info.fSpread/2.0f; + if(info.bRelative) ang += (vecPrevLocation-vecLocation).Angle()+M_PI_2; + newParticle.vecVelocity.x = cosf(ang); + newParticle.vecVelocity.y = sinf(ang); + newParticle.vecVelocity *= Random_Float(info.fSpeedMin, info.fSpeedMax); - ang=info.fDirection-M_PI_2+Random_Float(0,info.fSpread)-info.fSpread/2.0f; - if(info.bRelative) ang += (vecPrevLocation-vecLocation).Angle()+M_PI_2; - par->vecVelocity.x = cosf(ang); - par->vecVelocity.y = sinf(ang); - par->vecVelocity *= Random_Float(info.fSpeedMin, info.fSpeedMax); + newParticle.fGravity = Random_Float(info.fGravityMin, info.fGravityMax); + newParticle.fRadialAccel = Random_Float(info.fRadialAccelMin, info.fRadialAccelMax); + newParticle.fTangentialAccel = Random_Float(info.fTangentialAccelMin, info.fTangentialAccelMax); - par->fGravity = Random_Float(info.fGravityMin, info.fGravityMax); - par->fRadialAccel = Random_Float(info.fRadialAccelMin, info.fRadialAccelMax); - par->fTangentialAccel = Random_Float(info.fTangentialAccelMin, info.fTangentialAccelMax); + newParticle.fSize = Random_Float(info.fSizeStart, info.fSizeStart+(info.fSizeEnd-info.fSizeStart)*info.fSizeVar); + newParticle.fSizeDelta = (info.fSizeEnd-newParticle.fSize) / newParticle.fTerminalAge; - par->fSize = Random_Float(info.fSizeStart, info.fSizeStart+(info.fSizeEnd-info.fSizeStart)*info.fSizeVar); - par->fSizeDelta = (info.fSizeEnd-par->fSize) / par->fTerminalAge; + newParticle.fSpin = Random_Float(info.fSpinStart, info.fSpinStart+(info.fSpinEnd-info.fSpinStart)*info.fSpinVar); + newParticle.fSpinDelta = (info.fSpinEnd-newParticle.fSpin) / newParticle.fTerminalAge; - par->fSpin = Random_Float(info.fSpinStart, info.fSpinStart+(info.fSpinEnd-info.fSpinStart)*info.fSpinVar); - par->fSpinDelta = (info.fSpinEnd-par->fSpin) / par->fTerminalAge; + newParticle.colColor.r = Random_Float(info.colColorStart.r, info.colColorStart.r+(info.colColorEnd.r-info.colColorStart.r)*info.fColorVar); + newParticle.colColor.g = Random_Float(info.colColorStart.g, info.colColorStart.g+(info.colColorEnd.g-info.colColorStart.g)*info.fColorVar); + newParticle.colColor.b = Random_Float(info.colColorStart.b, info.colColorStart.b+(info.colColorEnd.b-info.colColorStart.b)*info.fColorVar); + newParticle.colColor.a = Random_Float(info.colColorStart.a, info.colColorStart.a+(info.colColorEnd.a-info.colColorStart.a)*info.fAlphaVar); - par->colColor.r = Random_Float(info.colColorStart.r, info.colColorStart.r+(info.colColorEnd.r-info.colColorStart.r)*info.fColorVar); - par->colColor.g = Random_Float(info.colColorStart.g, info.colColorStart.g+(info.colColorEnd.g-info.colColorStart.g)*info.fColorVar); - par->colColor.b = Random_Float(info.colColorStart.b, info.colColorStart.b+(info.colColorEnd.b-info.colColorStart.b)*info.fColorVar); - par->colColor.a = Random_Float(info.colColorStart.a, info.colColorStart.a+(info.colColorEnd.a-info.colColorStart.a)*info.fAlphaVar); + newParticle.colColorDelta.r = (info.colColorEnd.r-newParticle.colColor.r) / newParticle.fTerminalAge; + newParticle.colColorDelta.g = (info.colColorEnd.g-newParticle.colColor.g) / newParticle.fTerminalAge; + newParticle.colColorDelta.b = (info.colColorEnd.b-newParticle.colColor.b) / newParticle.fTerminalAge; + newParticle.colColorDelta.a = (info.colColorEnd.a-newParticle.colColor.a) / newParticle.fTerminalAge; - par->colColorDelta.r = (info.colColorEnd.r-par->colColor.r) / par->fTerminalAge; - par->colColorDelta.g = (info.colColorEnd.g-par->colColor.g) / par->fTerminalAge; - par->colColorDelta.b = (info.colColorEnd.b-par->colColor.b) / par->fTerminalAge; - par->colColorDelta.a = (info.colColorEnd.a-par->colColor.a) / par->fTerminalAge; + if(bUpdateBoundingBox) rectBoundingBox.Encapsulate(newParticle.vecLocation.x, newParticle.vecLocation.y); - if(bUpdateBoundingBox) rectBoundingBox.Encapsulate(par->vecLocation.x, par->vecLocation.y); + mParticleBuffer.push_back(newParticle); + ++nParticlesAlive; + } + } - nParticlesAlive++; - par++; - } - } - - vecPrevLocation=vecLocation; + vecPrevLocation=vecLocation; } void hgeParticleSystem::MoveTo(float x, float y, bool bMoveParticles) { - int i; - float dx,dy; - - if(bMoveParticles) - { - dx=x-vecLocation.x; - dy=y-vecLocation.y; + float dx,dy; - for(i=0;ivecLocation.x += dx; + particle->vecLocation.y += dy; + } - vecLocation.x=x; - vecLocation.y=y; + vecPrevLocation.x=vecPrevLocation.x + dx; + vecPrevLocation.y=vecPrevLocation.y + dy; + } + else + { + if(fAge==-2.0) { vecPrevLocation.x=x; vecPrevLocation.y=y; } + else { vecPrevLocation.x=vecLocation.x; vecPrevLocation.y=vecLocation.y; } + } + + vecLocation.x=x; + vecLocation.y=y; } void hgeParticleSystem::FireAt(float x, float y) { - Stop(); - MoveTo(x,y); - Fire(); + Stop(); + MoveTo(x,y); + Fire(); } void hgeParticleSystem::Fire() { - mTimer = 0.0f; + mTimer = 0.0f; - if(info.fLifetime==-1.0f) fAge=-1.0f; - else fAge=0.0f; + if(info.fLifetime==-1.0f) fAge=-1.0f; + else fAge=0.0f; } void hgeParticleSystem::Stop(bool bKillParticles) { - fAge=-2.0f; - if(bKillParticles) - { - nParticlesAlive=0; - rectBoundingBox.Clear(); - } + fAge=-2.0f; + if(bKillParticles) + { + nParticlesAlive=0; + mParticleBuffer.clear(); + rectBoundingBox.Clear(); + } } void hgeParticleSystem::Render() { - int i; -// DWORD col; - hgeParticle *par=particles; - - //col=info.sprite->GetColor(); - - for(i=0; iSetColor(par->colColor.GetHWColor()); - JRenderer::GetInstance()->RenderQuad(info.sprite, par->vecLocation.x+fTx, par->vecLocation.y+fTy, par->fSpin*par->fAge, par->fSize, par->fSize); - par++; - } - - //info.sprite->SetColor(col); + ParticleBuffer::iterator particle = mParticleBuffer.begin(); + for (;particle != mParticleBuffer.end(); ++particle) + { + info.sprite->SetColor(particle->colColor.GetHWColor()); + JRenderer::GetInstance()->RenderQuad( + info.sprite, + particle->vecLocation.x+fTx, particle->vecLocation.y+fTy, + particle->fSpin * particle->fAge, + particle->fSize, particle->fSize); + } } diff --git a/projects/mtg/src/GuiMana.cpp b/projects/mtg/src/GuiMana.cpp index 16ac744d1..9027283f4 100644 --- a/projects/mtg/src/GuiMana.cpp +++ b/projects/mtg/src/GuiMana.cpp @@ -98,7 +98,9 @@ ManaIcon::ManaIcon(int color, float x, float y, float destx, float desty) : Pos( else particleSys = NEW hgeParticleSystem(psi); //Cache will clean psi up later. - + // if we want to throttle the amount of particles for mana, + // here's where to do it - this is hardcoded to something like 114 in the psi file + particleSys->info.nEmission = 60; icon = manaIcons[color]; particleSys->FireAt(x, y); @@ -252,15 +254,15 @@ void GuiMana::RenderStatic(){ void GuiMana::Render() { - for (vector::iterator it = manas.begin(); it != manas.end(); ++it) (*it)->Render(); if (OptionManaDisplay::DYNAMIC != options[Options::MANADISPLAY].number) RenderStatic(); - } + bool remove_dead(ManaIcon* m) { return ManaIcon::DEAD != m->mode; } + void GuiMana::Update(float dt) { {