From 778ca33725a8bfac629b405f0bd26cfefaf47caf Mon Sep 17 00:00:00 2001 From: Bjørn Lindeijer Date: Sun, 3 Jun 2007 17:42:54 +0000 Subject: Have ParticleEmitter load a possible particle image early on and don't cause a crash when the image can't be found. --- ChangeLog | 6 ++++- src/imageparticle.cpp | 6 +++++ src/imageparticle.h | 14 ++++++++++++ src/particle.cpp | 2 +- src/particle.h | 8 +++++++ src/particleemitter.cpp | 58 ++++++++++++++++++++++++++++++------------------- src/particleemitter.h | 32 ++++++++++++++++++--------- 7 files changed, 92 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index f121a552..66252eeb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,9 +5,13 @@ * src/utils/fastsqrt.h: Fixed warning about strict-aliasing rules. * src/Makefile.am: Don't die on warnings by default. * src/resources/image.cpp: Fixed image loading in software mode to not - check for alpha layer with images aren't 32-bit. + check for alpha layer when images aren't 32-bit. * src/graphics.cpp, src/graphics.h, src/imageparticle.cpp: Removed drawImageTransparent from Graphics class, should be set on image. + * src/imageparticle.h, src/particleemitter.h, src/particle.h, + src/particleemitter.cpp, src/particle.cpp, src/imageparticle.cpp: Have + ParticleEmitter load a possible particle image early on and don't + cause a crash when the image can't be found. 2007-06-02 Bjørn Lindeijer diff --git a/src/imageparticle.cpp b/src/imageparticle.cpp index 410782bd..35cc21ad 100644 --- a/src/imageparticle.cpp +++ b/src/imageparticle.cpp @@ -31,6 +31,12 @@ ImageParticle::ImageParticle(Map *map, Image *image): Particle(map), mImage(image) { + mImage->incRef(); +} + +ImageParticle::~ImageParticle() +{ + mImage->decRef(); } void ImageParticle::draw(Graphics *graphics, int offsetX, int offsetY) const diff --git a/src/imageparticle.h b/src/imageparticle.h index afde7446..0ad515cc 100644 --- a/src/imageparticle.h +++ b/src/imageparticle.h @@ -29,11 +29,25 @@ class Image; class Map; +/** + * A particle that uses an image for its visualization. + */ class ImageParticle : public Particle { public: + /** + * Constructor. The image is reference counted by this particle. + * + * @param map the map this particle appears on + * @param image an Image instance, may not be NULL + */ ImageParticle(Map *map, Image *image); + /** + * Destructor. + */ + ~ImageParticle(); + /** * Draws the particle image */ diff --git a/src/particle.cpp b/src/particle.cpp index f88b9c21..509c20ee 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -48,7 +48,7 @@ int Particle::fastPhysics = 0; int Particle::emitterSkip = 1; const float Particle::PARTICLE_SKY = 800.0f; -Particle::Particle(Map *map) : +Particle::Particle(Map *map): mAlive(true), mPosX(0.0f), mPosY(0.0f), mPosZ(0.0f), mLifetimeLeft(-1), diff --git a/src/particle.h b/src/particle.h index 544a7f58..7a747a5f 100644 --- a/src/particle.h +++ b/src/particle.h @@ -54,8 +54,16 @@ class Particle : public Sprite static int maxCount; /**< Maximum number of particles */ static int emitterSkip; /**< Duration of pause between two emitter updates in ticks */ + /** + * Constructor. + * + * @param map the map this particle will add itself to, may be NULL + */ Particle(Map *map); + /** + * Destructor. + */ ~Particle(); /** diff --git a/src/particleemitter.cpp b/src/particleemitter.cpp index 62ac6bd8..2387c652 100644 --- a/src/particleemitter.cpp +++ b/src/particleemitter.cpp @@ -18,6 +18,7 @@ * along with The Mana World; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * $Id$ */ #include "particleemitter.h" @@ -37,29 +38,29 @@ #define SIN45 0.707106781f #define DEG_RAD_FACTOR 0.017453293f -ParticleEmitter::ParticleEmitter(xmlNodePtr emitterNode, Particle *target, Map *map) +ParticleEmitter::ParticleEmitter(xmlNodePtr emitterNode, Particle *target, Map *map): + mParticleImage(0) { mMap = map; mParticleTarget = target; //initializing default values - mParticlePosX.set (0.0f); - mParticlePosY.set (0.0f); - mParticlePosZ.set (0.0f); - mParticleAngleHorizontal.set (0.0f); - mParticleAngleVertical.set (0.0f); - mParticlePower.set (0.0f); - mParticleGravity.set (0.0f); - mParticleRandomnes.set (0); + mParticlePosX.set(0.0f); + mParticlePosY.set(0.0f); + mParticlePosZ.set(0.0f); + mParticleAngleHorizontal.set(0.0f); + mParticleAngleVertical.set(0.0f); + mParticlePower.set(0.0f); + mParticleGravity.set(0.0f); + mParticleRandomnes.set(0); mParticleBounce.set(0.0f); - mParticleAcceleration.set (0.0f); + mParticleAcceleration.set(0.0f); mParticleDieDistance.set(-1.0f); - mParticleMomentum.set (1.0f); - mParticleLifetime.set (-1); - mParticleFadeOut.set (0); - mParticleFadeIn.set (0); - mOutput.set (1); - mParticleImage = ""; + mParticleMomentum.set(1.0f); + mParticleLifetime.set(-1); + mParticleFadeOut.set(0); + mParticleFadeIn.set(0); + mOutput.set(1); for_each_xml_child_node(propertyNode, emitterNode) { @@ -82,7 +83,13 @@ ParticleEmitter::ParticleEmitter(xmlNodePtr emitterNode, Particle *target, Map * } else if (name == "image") { - mParticleImage = XML::getProperty(propertyNode, "value", ""); + std::string image = XML::getProperty(propertyNode, "value", ""); + // Don't leak when multiple images are defined + if (image != "" && !mParticleImage) + { + ResourceManager *resman = ResourceManager::getInstance(); + mParticleImage = resman->getImage(image); + } } else if (name == "horizontal-angle") { @@ -227,6 +234,15 @@ ParticleEmitter::ParticleEmitter(xmlNodePtr emitterNode, Particle *target, Map * } +ParticleEmitter::~ParticleEmitter() +{ + if (mParticleImage) + { + mParticleImage->decRef(); + } +} + + template MinMax ParticleEmitter::readMinMax(xmlNodePtr propertyNode, T def) { @@ -245,18 +261,16 @@ std::list ParticleEmitter::createParticles() { std::list newParticles; - ResourceManager *resman = ResourceManager::getInstance(); for (int i = mOutput.value(); i > 0; i--) { - //limit maximum particles + // Limit maximum particles if (Particle::particleCount > Particle::maxCount) break; Particle *newParticle; - if (mParticleImage != "") + if (mParticleImage) { - newParticle = new ImageParticle(mMap, - resman->getImage(mParticleImage)); + newParticle = new ImageParticle(mMap, mParticleImage); } else if (mParticleAnimation.getLength() > 0) { diff --git a/src/particleemitter.h b/src/particleemitter.h index dcc7069b..ca6d8622 100644 --- a/src/particleemitter.h +++ b/src/particleemitter.h @@ -18,6 +18,7 @@ * along with The Mana World; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * $Id$ */ #ifndef _PARTICLEEMITTER_H @@ -30,6 +31,7 @@ #include "resources/animation.h" +class Image; class Map; class Particle; @@ -40,8 +42,15 @@ class Particle; class ParticleEmitter { public: + /** + * Constructor. + */ + ParticleEmitter(xmlNodePtr emitterNode, Particle *target, Map *map); - ParticleEmitter(xmlNodePtr emitterNode, Particle *target, Map *map); + /** + * Destructor. + */ + ~ParticleEmitter(); /** * Spawns new particles @@ -74,14 +83,14 @@ class ParticleEmitter */ MinMax mParticlePower; - /** - * vector changing of particles: + /* + * Vector changing of particles: */ MinMax mParticleGravity; MinMax mParticleRandomnes; MinMax mParticleBounce; - /** + /* * Properties of targeting particles: */ Particle *mParticleTarget; @@ -89,20 +98,23 @@ class ParticleEmitter MinMax mParticleDieDistance; MinMax mParticleMomentum; - /** + /* * Behavior over time of the particles: */ MinMax mParticleLifetime; MinMax mParticleFadeOut; MinMax mParticleFadeIn; - Map *mMap; /**< Map the particles are supposed to spawn on */ + Map *mMap; /**< Map the particles are spawned on */ + + MinMax mOutput; /**< Number of particles spawned per update */ - MinMax mOutput; /**< Number of particles spawned per update */ + Image *mParticleImage; /**< Particle image, if used */ - std::string mParticleImage; /**< Filename of particle image */ - Animation mParticleAnimation; /**< Filename of particle animation file */ + /** Filename of particle animation file */ + Animation mParticleAnimation; - std::list mParticleChildEmitters; /** List of emitters the spawned particles are equipped with */ + /** List of emitters the spawned particles are equipped with */ + std::list mParticleChildEmitters; }; #endif -- cgit v1.2.3-70-g09d2