summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/graphics.cpp13
-rw-r--r--src/graphics.h8
-rw-r--r--src/imageparticle.cpp26
-rw-r--r--src/imageparticle.h1
-rw-r--r--src/particle.cpp738
-rw-r--r--src/particle.h559
-rw-r--r--src/resources/image.cpp25
7 files changed, 676 insertions, 694 deletions
diff --git a/src/graphics.cpp b/src/graphics.cpp
index 4ea75a93..1e31f903 100644
--- a/src/graphics.cpp
+++ b/src/graphics.cpp
@@ -136,8 +136,6 @@ bool Graphics::drawImage(Image *image, int srcX, int srcY, int dstX, int dstY,
srcX += image->mBounds.x;
srcY += image->mBounds.y;
-
-
SDL_Rect dstRect;
SDL_Rect srcRect;
dstRect.x = dstX; dstRect.y = dstY;
@@ -148,17 +146,6 @@ bool Graphics::drawImage(Image *image, int srcX, int srcY, int dstX, int dstY,
return !(SDL_BlitSurface(image->mImage, &srcRect, mScreen, &dstRect) < 0);
}
-bool Graphics::drawImageTransparent(Image *image, int x, int y, float opacity)
-{
- if (!image) return false;
-
- float oldalpha = image->getAlpha();
- image->setAlpha(opacity * oldalpha);
- bool retval = drawImage(image, x, y);
- image->setAlpha(oldalpha);
- return retval;
-}
-
void Graphics::drawImagePattern(Image *image, int x, int y, int w, int h)
{
int iw = image->getWidth();
diff --git a/src/graphics.h b/src/graphics.h
index abef794f..b3d36653 100644
--- a/src/graphics.h
+++ b/src/graphics.h
@@ -97,14 +97,6 @@ class Graphics : public gcn::SDLGraphics {
int dstX, int dstY,
int width, int height);
- /**
- * Blits an image onto the screen with an alpha factor
- *
- * @return <code>true</code> if the image was blitted properly
- * <code>false</code> otherwise.
- */
- bool drawImageTransparent(Image *image, int x, int y, float opacity);
-
virtual void
drawImagePattern(Image *image,
int x, int y,
diff --git a/src/imageparticle.cpp b/src/imageparticle.cpp
index 86e7e50f..410782bd 100644
--- a/src/imageparticle.cpp
+++ b/src/imageparticle.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 "imageparticle.h"
@@ -37,31 +38,26 @@ void ImageParticle::draw(Graphics *graphics, int offsetX, int offsetY) const
if (!mAlive)
return;
- int screenX = (int)mPosX + offsetX - mImage->getWidth()/2;
- int screenY = (int)mPosY - int(mPosZ) + offsetY - mImage->getHeight()/2;
+ int screenX = (int) mPosX + offsetX - mImage->getWidth() / 2;
+ int screenY = (int) mPosY - (int) mPosZ + offsetY - mImage->getHeight()/2;
- // check if on screen
- if (screenX + mImage->getWidth() < 0 ||
+ // Check if on screen
+ if (screenX + mImage->getWidth() < 0 ||
screenX > graphics->getWidth() ||
screenY + mImage->getHeight() < 0 ||
screenY > graphics->getHeight())
+ {
return;
+ }
float alphafactor = 1.0f;
if (mLifetimeLeft > -1 && mLifetimeLeft < mFadeOut)
- alphafactor *= ((float)mLifetimeLeft / (float)mFadeOut);
+ alphafactor *= (float) mLifetimeLeft / (float) mFadeOut;
if (mLifetimePast < mFadeIn)
- alphafactor *= ((float)mLifetimePast / (float)mFadeIn);
+ alphafactor *= (float) mLifetimePast / (float) mFadeIn;
- if (alphafactor < 1.0f) {
- graphics->drawImageTransparent(mImage,
- screenX,
- screenY,
- alphafactor
- );
- } else {
- graphics->drawImage(mImage, screenX, screenY);
- }
+ mImage->setAlpha(alphafactor);
+ graphics->drawImage(mImage, screenX, screenY);
}
diff --git a/src/imageparticle.h b/src/imageparticle.h
index 4396fb7c..afde7446 100644
--- a/src/imageparticle.h
+++ b/src/imageparticle.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 _IMAGEPARTICLE_H
diff --git a/src/particle.cpp b/src/particle.cpp
index 88e8c2b3..f88b9c21 100644
--- a/src/particle.cpp
+++ b/src/particle.cpp
@@ -1,368 +1,370 @@
-/*
- * The Mana World
- * Copyright 2006 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * The Mana World 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 2 of the License, or
- * any later version.
- *
- * The Mana World 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 The Mana World; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "particle.h"
-
-#include <cmath>
-
-#include "animationparticle.h"
-#include "configuration.h"
-#include "imageparticle.h"
-#include "log.h"
-#include "map.h"
-#include "particleemitter.h"
-#include "textparticle.h"
-
-#include "resources/resourcemanager.h"
-
-#include "utils/dtor.h"
-#include "utils/fastsqrt.h"
-#include "utils/xml.h"
-
-class Graphics;
-class Image;
-
-int Particle::particleCount = 0;
-int Particle::maxCount = 0;
-int Particle::fastPhysics = 0;
-int Particle::emitterSkip = 1;
-const float Particle::PARTICLE_SKY = 800.0f;
-
-Particle::Particle(Map *map) :
- mAlive(true),
- mPosX(0.0f), mPosY(0.0f), mPosZ(0.0f),
- mLifetimeLeft(-1),
- mLifetimePast(0),
- mFadeOut(0),
- mFadeIn(0),
- mAutoDelete(true),
- mMap(map),
- mVectorX(0.0f), mVectorY(0.0f), mVectorZ(0.0f),
- mGravity(0.0f),
- mRandomnes(0),
- mBounce(0.0f),
- mTarget(NULL),
- mAcceleration(0.0f),
- mInvDieDistance(-1.0f),
- mMomentum(1.0f)
-{
- Particle::particleCount++;
- if (mMap) setSpriteIterator(mMap->addSprite(this));
-}
-
-
-void
-Particle::setupEngine()
-{
- Particle::maxCount = (int)config.getValue("particleMaxCount", 3000);
- Particle::fastPhysics = (int)config.getValue("particleFastPhysics", 0);
- Particle::emitterSkip = (int)config.getValue("particleEmitterSkip", 0) + 1;
- disableAutoDelete();
- logger->log("Particle engine set up");
-}
-
-bool
-Particle::update()
-{
- if (!mMap) return false;
-
- if (mLifetimeLeft == 0)
- {
- mAlive = false;
- }
-
- if (mAlive)
- {
- //update child emitters
- if (mLifetimePast%Particle::emitterSkip == 0)
- {
- for ( EmitterIterator e = mChildEmitters.begin();
- e != mChildEmitters.end();
- e++
- )
- {
- Particles newParticles = (*e)->createParticles();
- for ( ParticleIterator p = newParticles.begin();
- p != newParticles.end();
- p++
- )
- {
- (*p)->moveBy(mPosX, mPosY, mPosZ);
- mChildParticles.push_back (*p);
- }
- }
- }
-
- if (mMomentum != 1.0f)
- {
- mVectorX *= mMomentum;
- mVectorY *= mMomentum;
- mVectorZ *= mMomentum;
- }
-
- if (mTarget && mAcceleration != 0.0f)
- {
- float distX = mPosX - mTarget->getPosX();
- float distY = mPosY - mTarget->getPosY();
- float distZ = mPosZ - mTarget->getPosZ();
- float invHypotenuse;
-
- switch(Particle::fastPhysics)
- {
- case 1:
- invHypotenuse = fastInvSqrt(
- distX * distX + distY * distY + distZ * distZ);
- break;
- case 2:
- invHypotenuse = 2.0f /
- fabs(distX) + fabs(distY) + fabs(distZ);
- break;
- default:
- invHypotenuse = 1.0f / sqrt(
- distX * distX + distY * distY + distZ * distZ);
- break;
- }
-
- if (invHypotenuse)
- {
- if (mInvDieDistance > 0.0f && invHypotenuse > mInvDieDistance)
- {
- mAlive = false;
- }
- float accFactor = invHypotenuse * mAcceleration;
- mVectorX -= distX * accFactor;
- mVectorY -= distY * accFactor;
- mVectorZ -= distZ * accFactor;
- }
- }
-
- if (mRandomnes > 0)
- {
- mVectorX += (rand()%mRandomnes - rand()%mRandomnes) / 1000.0f;
- mVectorY += (rand()%mRandomnes - rand()%mRandomnes) / 1000.0f;
- mVectorZ += (rand()%mRandomnes - rand()%mRandomnes) / 1000.0f;
- }
-
- mVectorZ -= mGravity;
-
- // update position
- mPosX += mVectorX;
- mPosY += mVectorY;
- mPosZ += mVectorZ;
-
- //update other stuff
- if (mLifetimeLeft > 0)
- {
- mLifetimeLeft--;
- }
- mLifetimePast++;
-
- if (mPosZ > PARTICLE_SKY || mPosZ < 0.0f)
- {
- if (mBounce > 0.0f)
- {
- mPosZ *= -mBounce;
- mVectorX *= mBounce;
- mVectorY *= mBounce;
- mVectorZ *= -mBounce;
- }
- else {
- mAlive = false;
- }
- }
- }
-
- //update child particles
- for ( ParticleIterator p = mChildParticles.begin();
- p != mChildParticles.end();
-
- )
- {
- if ((*p)->update())
- {
- p++;
- }else {
- delete (*p);
- p = mChildParticles.erase(p);
- }
- }
-
- if (!mAlive && mChildParticles.empty() && mAutoDelete)
- {
- return false;
- };
-
- return true;
-}
-
-
-void Particle::draw(Graphics *graphics, int offsetX, int offsetY) const
-{
-}
-
-
-Particle*
-Particle::addEffect (std::string particleEffectFile, int pixelX, int pixelY)
-{
- Particle *newParticle = NULL;
-
- // XML parser initialisation stuff
- int size;
- ResourceManager *resman = ResourceManager::getInstance();
- char *data = (char*) resman->loadFile(particleEffectFile.c_str(), size);
-
- if (!data) {
- logger->log("Warning: Particle engine could not find %s !",
- particleEffectFile.c_str());
- return NULL;
- }
-
- xmlDocPtr doc = xmlParseMemory(data, size);
- free(data);
-
- if (!doc) {
- logger->log("Warning: Particle engine found syntax error in %s!",
- particleEffectFile.c_str());
- return NULL;
- }
-
- xmlNodePtr rootNode = xmlDocGetRootElement(doc);
- if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "effect")) {
- logger->log("Warning: %s is not a valid particle effect definition file!",
- particleEffectFile.c_str());
- return NULL;
- }
-
- // parse particles
- for_each_xml_child_node(effectChildNode, rootNode)
- {
- // We're only interested in particles
- if (!xmlStrEqual(effectChildNode->name, BAD_CAST "particle"))
- continue;
-
- // Determine the exact particle type
- xmlNodePtr node;
-
- // Animation
- if ((node = XML::findFirstChildByName(
- effectChildNode, "animation"))) {
- newParticle = new AnimationParticle(mMap, node);
- }
- // Image
- else if ((node = XML::findFirstChildByName(
- effectChildNode, "image"))) {
- Image *img= resman->getImage((const char*)
- node->xmlChildrenNode->content);
-
- newParticle = new ImageParticle(mMap, img);
- }
- // Other
- else {
- newParticle = new Particle(mMap);
- }
-
- // Read and set the basic properties of the particle
- int offsetX = XML::getProperty(effectChildNode, "position-x", 0);
- int offsetY = XML::getProperty(effectChildNode, "position-y", 0);
- int offsetZ = XML::getProperty(effectChildNode, "position-z", 0);
-
- int particleX = (int)mPosX + pixelX + offsetX;
- int particleY = (int)mPosY + pixelY + offsetY;
- int particleZ = (int)mPosZ + offsetZ;
-
- int lifetime = XML::getProperty(effectChildNode, "lifetime", -1);
-
- newParticle->setPosition(particleX, particleY, particleZ);
- newParticle->setLifetime(lifetime);
-
- // Look for additional emitters for this particle
- for_each_xml_child_node(emitterNode, effectChildNode)
- {
- if (!xmlStrEqual(emitterNode->name, BAD_CAST "emitter"))
- continue;
-
- ParticleEmitter *newEmitter;
- newEmitter = new ParticleEmitter(emitterNode, newParticle, mMap);
- newParticle->addEmitter(newEmitter);
- }
-
- mChildParticles.push_back(newParticle);
- }
-
- return newParticle;
-}
-
-
-Particle*
-Particle::addTextSplashEffect(std::string text,
- int colorR, int colorG, int colorB,
- gcn::Font *font, int x, int y)
-{
- Particle *newParticle = new TextParticle(mMap, text, colorR, colorG, colorB,
- font);
- newParticle->setPosition(x, y, 0);
- newParticle->setVector ( ((rand()%100) - 50) / 200.0f, //X Vector
- ((rand()%100) - 50) / 200.0f, //Y Vector
- ((rand()%100) / 200.0f) + 4.0f //Z Vector
- );
- newParticle->setGravity(0.1f);
- newParticle->setBounce(0.5f);
- newParticle->setLifetime(200);
- newParticle->setFadeOut(100);
-
- mChildParticles.push_back(newParticle);
-
- return newParticle;
-}
-
-
-void
-Particle::setMap(Map *map)
-{
- mMap = map;
- if (mMap) setSpriteIterator(mMap->addSprite(this));
-
- // TODO: Create map emitters based on emitter data in map data
-}
-
-
-Particle::~Particle()
-{
- //remove from map sprite list
- if (mMap) mMap->removeSprite(mSpriteIterator);
- //delete child emitters and child particles
- clear();
- Particle::particleCount--;
-}
-
-
-void
-Particle::clear()
-{
- std::for_each(mChildEmitters.begin(), mChildEmitters.end(),
- make_dtor(mChildEmitters));
- mChildEmitters.clear();
-
- std::for_each(mChildParticles.begin(), mChildParticles.end(),
- make_dtor(mChildParticles));
- mChildParticles.clear();
-}
+/*
+ * The Mana World
+ * Copyright 2006 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World 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 2 of the License, or
+ * any later version.
+ *
+ * The Mana World 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 The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#include "particle.h"
+
+#include <cmath>
+
+#include "animationparticle.h"
+#include "configuration.h"
+#include "imageparticle.h"
+#include "log.h"
+#include "map.h"
+#include "particleemitter.h"
+#include "textparticle.h"
+
+#include "resources/resourcemanager.h"
+
+#include "utils/dtor.h"
+#include "utils/fastsqrt.h"
+#include "utils/xml.h"
+
+class Graphics;
+class Image;
+
+int Particle::particleCount = 0;
+int Particle::maxCount = 0;
+int Particle::fastPhysics = 0;
+int Particle::emitterSkip = 1;
+const float Particle::PARTICLE_SKY = 800.0f;
+
+Particle::Particle(Map *map) :
+ mAlive(true),
+ mPosX(0.0f), mPosY(0.0f), mPosZ(0.0f),
+ mLifetimeLeft(-1),
+ mLifetimePast(0),
+ mFadeOut(0),
+ mFadeIn(0),
+ mAutoDelete(true),
+ mMap(map),
+ mVectorX(0.0f), mVectorY(0.0f), mVectorZ(0.0f),
+ mGravity(0.0f),
+ mRandomnes(0),
+ mBounce(0.0f),
+ mTarget(NULL),
+ mAcceleration(0.0f),
+ mInvDieDistance(-1.0f),
+ mMomentum(1.0f)
+{
+ Particle::particleCount++;
+ if (mMap) setSpriteIterator(mMap->addSprite(this));
+}
+
+
+void
+Particle::setupEngine()
+{
+ Particle::maxCount = (int)config.getValue("particleMaxCount", 3000);
+ Particle::fastPhysics = (int)config.getValue("particleFastPhysics", 0);
+ Particle::emitterSkip = (int)config.getValue("particleEmitterSkip", 0) + 1;
+ disableAutoDelete();
+ logger->log("Particle engine set up");
+}
+
+bool
+Particle::update()
+{
+ if (!mMap) return false;
+
+ if (mLifetimeLeft == 0)
+ {
+ mAlive = false;
+ }
+
+ if (mAlive)
+ {
+ // Update child emitters
+ if (mLifetimePast%Particle::emitterSkip == 0)
+ {
+ for ( EmitterIterator e = mChildEmitters.begin();
+ e != mChildEmitters.end();
+ e++
+ )
+ {
+ Particles newParticles = (*e)->createParticles();
+ for ( ParticleIterator p = newParticles.begin();
+ p != newParticles.end();
+ p++
+ )
+ {
+ (*p)->moveBy(mPosX, mPosY, mPosZ);
+ mChildParticles.push_back (*p);
+ }
+ }
+ }
+
+ if (mMomentum != 1.0f)
+ {
+ mVectorX *= mMomentum;
+ mVectorY *= mMomentum;
+ mVectorZ *= mMomentum;
+ }
+
+ if (mTarget && mAcceleration != 0.0f)
+ {
+ float distX = mPosX - mTarget->getPosX();
+ float distY = mPosY - mTarget->getPosY();
+ float distZ = mPosZ - mTarget->getPosZ();
+ float invHypotenuse;
+
+ switch(Particle::fastPhysics)
+ {
+ case 1:
+ invHypotenuse = fastInvSqrt(
+ distX * distX + distY * distY + distZ * distZ);
+ break;
+ case 2:
+ invHypotenuse = 2.0f /
+ fabs(distX) + fabs(distY) + fabs(distZ);
+ break;
+ default:
+ invHypotenuse = 1.0f / sqrt(
+ distX * distX + distY * distY + distZ * distZ);
+ break;
+ }
+
+ if (invHypotenuse)
+ {
+ if (mInvDieDistance > 0.0f && invHypotenuse > mInvDieDistance)
+ {
+ mAlive = false;
+ }
+ float accFactor = invHypotenuse * mAcceleration;
+ mVectorX -= distX * accFactor;
+ mVectorY -= distY * accFactor;
+ mVectorZ -= distZ * accFactor;
+ }
+ }
+
+ if (mRandomnes > 0)
+ {
+ mVectorX += (rand()%mRandomnes - rand()%mRandomnes) / 1000.0f;
+ mVectorY += (rand()%mRandomnes - rand()%mRandomnes) / 1000.0f;
+ mVectorZ += (rand()%mRandomnes - rand()%mRandomnes) / 1000.0f;
+ }
+
+ mVectorZ -= mGravity;
+
+ // Update position
+ mPosX += mVectorX;
+ mPosY += mVectorY;
+ mPosZ += mVectorZ;
+
+ // Update other stuff
+ if (mLifetimeLeft > 0)
+ {
+ mLifetimeLeft--;
+ }
+ mLifetimePast++;
+
+ if (mPosZ > PARTICLE_SKY || mPosZ < 0.0f)
+ {
+ if (mBounce > 0.0f)
+ {
+ mPosZ *= -mBounce;
+ mVectorX *= mBounce;
+ mVectorY *= mBounce;
+ mVectorZ *= -mBounce;
+ }
+ else {
+ mAlive = false;
+ }
+ }
+ }
+
+ // Update child particles
+ for ( ParticleIterator p = mChildParticles.begin();
+ p != mChildParticles.end();
+
+ )
+ {
+ if ((*p)->update())
+ {
+ p++;
+ } else {
+ delete (*p);
+ p = mChildParticles.erase(p);
+ }
+ }
+
+ if (!mAlive && mChildParticles.empty() && mAutoDelete)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+void Particle::draw(Graphics *graphics, int offsetX, int offsetY) const
+{
+}
+
+
+Particle*
+Particle::addEffect(std::string particleEffectFile, int pixelX, int pixelY)
+{
+ Particle *newParticle = NULL;
+
+ // XML parser initialisation stuff
+ int size;
+ ResourceManager *resman = ResourceManager::getInstance();
+ char *data = (char*) resman->loadFile(particleEffectFile.c_str(), size);
+
+ if (!data) {
+ logger->log("Warning: Particle engine could not find %s !",
+ particleEffectFile.c_str());
+ return NULL;
+ }
+
+ xmlDocPtr doc = xmlParseMemory(data, size);
+ free(data);
+
+ if (!doc) {
+ logger->log("Warning: Particle engine found syntax error in %s!",
+ particleEffectFile.c_str());
+ return NULL;
+ }
+
+ xmlNodePtr rootNode = xmlDocGetRootElement(doc);
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "effect"))
+ {
+ logger->log("Warning: %s is not a valid particle effect definition file!",
+ particleEffectFile.c_str());
+ return NULL;
+ }
+
+ // Parse particles
+ for_each_xml_child_node(effectChildNode, rootNode)
+ {
+ // We're only interested in particles
+ if (!xmlStrEqual(effectChildNode->name, BAD_CAST "particle"))
+ continue;
+
+ // Determine the exact particle type
+ xmlNodePtr node;
+
+ // Animation
+ if ((node = XML::findFirstChildByName(
+ effectChildNode, "animation"))) {
+ newParticle = new AnimationParticle(mMap, node);
+ }
+ // Image
+ else if ((node = XML::findFirstChildByName(
+ effectChildNode, "image"))) {
+ Image *img= resman->getImage((const char*)
+ node->xmlChildrenNode->content);
+
+ newParticle = new ImageParticle(mMap, img);
+ }
+ // Other
+ else {
+ newParticle = new Particle(mMap);
+ }
+
+ // Read and set the basic properties of the particle
+ int offsetX = XML::getProperty(effectChildNode, "position-x", 0);
+ int offsetY = XML::getProperty(effectChildNode, "position-y", 0);
+ int offsetZ = XML::getProperty(effectChildNode, "position-z", 0);
+
+ int particleX = (int)mPosX + pixelX + offsetX;
+ int particleY = (int)mPosY + pixelY + offsetY;
+ int particleZ = (int)mPosZ + offsetZ;
+
+ int lifetime = XML::getProperty(effectChildNode, "lifetime", -1);
+
+ newParticle->setPosition(particleX, particleY, particleZ);
+ newParticle->setLifetime(lifetime);
+
+ // Look for additional emitters for this particle
+ for_each_xml_child_node(emitterNode, effectChildNode)
+ {
+ if (!xmlStrEqual(emitterNode->name, BAD_CAST "emitter"))
+ continue;
+
+ ParticleEmitter *newEmitter;
+ newEmitter = new ParticleEmitter(emitterNode, newParticle, mMap);
+ newParticle->addEmitter(newEmitter);
+ }
+
+ mChildParticles.push_back(newParticle);
+ }
+
+ return newParticle;
+}
+
+
+Particle*
+Particle::addTextSplashEffect(std::string text,
+ int colorR, int colorG, int colorB,
+ gcn::Font *font, int x, int y)
+{
+ Particle *newParticle = new TextParticle(mMap, text, colorR, colorG, colorB,
+ font);
+ newParticle->setPosition(x, y, 0);
+ newParticle->setVector ( ((rand()%100) - 50) / 200.0f, // X vector
+ ((rand()%100) - 50) / 200.0f, // Y vector
+ ((rand()%100) / 200.0f) + 4.0f // Z vector
+ );
+ newParticle->setGravity(0.1f);
+ newParticle->setBounce(0.5f);
+ newParticle->setLifetime(200);
+ newParticle->setFadeOut(100);
+
+ mChildParticles.push_back(newParticle);
+
+ return newParticle;
+}
+
+
+void
+Particle::setMap(Map *map)
+{
+ mMap = map;
+ if (mMap) setSpriteIterator(mMap->addSprite(this));
+
+ // TODO: Create map emitters based on emitter data in map data
+}
+
+
+Particle::~Particle()
+{
+ // Remove from map sprite list
+ if (mMap) mMap->removeSprite(mSpriteIterator);
+ // Delete child emitters and child particles
+ clear();
+ Particle::particleCount--;
+}
+
+
+void
+Particle::clear()
+{
+ std::for_each(mChildEmitters.begin(), mChildEmitters.end(),
+ make_dtor(mChildEmitters));
+ mChildEmitters.clear();
+
+ std::for_each(mChildParticles.begin(), mChildParticles.end(),
+ make_dtor(mChildParticles));
+ mChildParticles.clear();
+}
diff --git a/src/particle.h b/src/particle.h
index 4073abdd..544a7f58 100644
--- a/src/particle.h
+++ b/src/particle.h
@@ -1,279 +1,280 @@
-/*
- * The Mana World
- * Copyright 2006 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * The Mana World 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 2 of the License, or
- * any later version.
- *
- * The Mana World 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 The Mana World; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef _PARTICLE_H
-#define _PARTICLE_H
-
-#include <list>
-#include <string>
-
-#include <guichan/color.hpp>
-
-#include "guichanfwd.h"
-#include "sprite.h"
-
-
-class Map;
-class Particle;
-class ParticleEmitter;
-
-typedef std::list<Particle *> Particles;
-typedef Particles::iterator ParticleIterator;
-typedef std::list<ParticleEmitter *> Emitters;
-typedef Emitters::iterator EmitterIterator;
-
-/**
- * a particle spawned by a ParticleEmitter
- */
-class Particle : public Sprite
-{
- public:
- static const float PARTICLE_SKY; /**< maximum Z position of particles */
- static int fastPhysics; /**< mode of squareroot calculation */
- static int particleCount; /**< current number of particles*/
- static int maxCount; /**< maximum number of particles*/
- static int emitterSkip; /**< duration of pause between two emitter updates in ticks */
-
- Particle(Map *map);
-
- ~Particle();
-
- /**
- * Deletes all child particles and emitters
- */
- void
- clear();
-
- /**
- * Gives a particle the properties of an engine root particle and loads
- * the particle-related config settings
- */
- void
- setupEngine();
-
- /**
- * Updates particle position, returns false when the particle should
- * be deleted
- */
- virtual bool
- update();
-
- /**
- * Draws the particle image
- */
- virtual void
- draw(Graphics *graphics, int offsetX, int offsetY) const;
-
- /**
- * Necessary for sorting with the other sprites
- */
- virtual int
- getPixelY() const
- {
- return (int)(mPosY + mPosZ) - 64;
- };
-
- /*
- Basic Particle properites:
- */
-
- /**
- * Sets the map the particle is on
- */
- void setMap(Map *map);
-
- /**
- * Creates a child particle that hosts some emitters described in the
- * particleEffectFile
- */
- Particle*
- addEffect (std::string particleEffectFile, int pixelX, int pixelY);
-
- /**
- * Creates a standalone text particle
- */
- Particle*
- addTextSplashEffect(std::string text, int colorR, int colorG, int colorB,
- gcn::Font *font, int x, int y);
-
- /**
- * Adds an emitter to the particle
- */
- void
- addEmitter (ParticleEmitter* emitter)
- { mChildEmitters.push_back(emitter);};
-
- /**
- * Sets the position in 3 dimensional space in pixels relative to map
- */
- void
- setPosition(float x, float y, float z)
- { mPosX = x; mPosY = y; mPosZ = z; };
-
- /**
- * Sets the position in 2 dimensional space in pixels relative to map
- */
- void
- setPosition(float x, float y)
- { mPosX = x; mPosY = y; };
-
- float getPosX() const
- { return mPosX; };
-
- float getPosY() const
- { return mPosY; };
-
- float getPosZ() const
- { return mPosZ; };
-
- /**
- * Changes the particle position relative
- */
- void
- moveBy(float x, float y, float z)
- { mPosX += x; mPosY += y; mPosZ += z; };
-
- /**
- * Sets the time in game ticks until the particle is destroyed.
- */
- void
- setLifetime(int lifetime)
- { mLifetimeLeft = lifetime; mLifetimePast = 0; };
-
- /**
- * Sets the age of the pixel in game ticks where the particle has
- * faded in completely
- */
- void
- setFadeOut (int fadeOut)
- { mFadeOut = fadeOut; };
-
- /**
- * Sets the remaining particle lifetime where the particle starts to
- * fade out
- */
- void
- setFadeIn (int fadeIn)
- { mFadeIn = fadeIn; };
-
- /**
- * Sets the sprite iterator of the particle on the current map to make
- * it easier to remove the particle from the map when it is destroyed
- */
- void
- setSpriteIterator(std::list<Sprite*>::iterator spriteIterator)
- { mSpriteIterator = spriteIterator; };
-
- /**
- * Gets the sprite iterator of the particle on the current map
- */
- std::list<Sprite*>::iterator
- getSpriteIterator() const
- { return mSpriteIterator; };
-
- /**
- * Sets the current velocity in 3 dimensional space
- */
- void
- setVector(float x, float y, float z)
- { mVectorX = x; mVectorY = y; mVectorZ = z; };
-
- /**
- * Sets the downward acceleration
- */
- void
- setGravity(float g)
- { mGravity = g; };
-
- /**
- * Sets the ammount of random vector changes
- */
- void
- setRandomnes(int r)
- { mRandomnes = r; };
-
- /**
- * Sets the ammount of velocity particles retain after
- * hitting the ground.
- */
- void
- setBounce(float bouncieness)
- { mBounce = bouncieness; };
-
- /**
- * Makes the particle move toward another particle with a
- * given acceleration and momentum
- */
- void setDestination(Particle *target, float accel, float moment)
- { mTarget = target; mAcceleration = accel; mMomentum = moment; };
-
- /**
- * Sets the distance in pixel the particle can come near the target
- * particle before it is destroyed. Does only make sense after a
- * target particle has been set using setDestination.
- */
- void setDieDistance(float dist)
- { mInvDieDistance = 1.0f / dist; };
-
- /**
- * Manually marks the particle for deletion
- */
- void kill()
- { mAlive = false; mAutoDelete = true; };
-
- /**
- * After calling this function the particle will only request
- * deletion when kill() is called
- */
- void disableAutoDelete()
- { mAutoDelete = false; };
-
- protected:
- bool mAlive; /**< Is the particle supposed to be drawn and updated?*/
- float mPosX, mPosY, mPosZ; /**< Position in 3 dimensonal space - pixel based relative to map */
- int mLifetimeLeft; /**< Lifetime left in game ticks*/
- int mLifetimePast; /**< Age of the particle in game ticks*/
- int mFadeOut; /**< Lifetime in game ticks left where fading out begins*/
- int mFadeIn; /**< Age in game ticks where fading in is finished*/
-
- private:
- // generic properties
- bool mAutoDelete; /**< May the particle request its deletion by the parent particle?*/
- Map *mMap; /**< Map the particle is on*/
- std::list<Sprite*>::iterator mSpriteIterator; /**< iterator of the particle on the current map */
- Emitters mChildEmitters; /**< List of child emitters*/
- Particles mChildParticles; /**< List of particles controlled by this particle*/
- //dynamic particle
- float mVectorX, mVectorY, mVectorZ; /**< Speed in 3 dimensional space in pixels per game-tick */
- float mGravity; /**< Downward acceleration in pixels per game-tickČ*/
- int mRandomnes; /**< Ammount of random vector change*/
- float mBounce; /**< How much the particle bounces off when hitting the ground*/
- //follow-point particles
- Particle *mTarget; /**< The particle that attracts this particle*/
- float mAcceleration; /**< Acceleration towards the target particle in pixels per game-tickČ*/
- float mInvDieDistance; /**< Distance in pixels from the target particle that causes the destruction of the particle*/
- float mMomentum; /**< How much speed the particle retains after each game tick*/
-};
-
-extern Particle *particleEngine;
-
-#endif
+/*
+ * The Mana World
+ * Copyright 2006 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World 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 2 of the License, or
+ * any later version.
+ *
+ * The Mana World 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 The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#ifndef _PARTICLE_H
+#define _PARTICLE_H
+
+#include <list>
+#include <string>
+
+#include <guichan/color.hpp>
+
+#include "guichanfwd.h"
+#include "sprite.h"
+
+
+class Map;
+class Particle;
+class ParticleEmitter;
+
+typedef std::list<Particle *> Particles;
+typedef Particles::iterator ParticleIterator;
+typedef std::list<ParticleEmitter *> Emitters;
+typedef Emitters::iterator EmitterIterator;
+
+/**
+ * A particle spawned by a ParticleEmitter.
+ */
+class Particle : public Sprite
+{
+ public:
+ static const float PARTICLE_SKY; /**< Maximum Z position of particles */
+ static int fastPhysics; /**< Mode of squareroot calculation */
+ static int particleCount; /**< Current number of particles */
+ static int maxCount; /**< Maximum number of particles */
+ static int emitterSkip; /**< Duration of pause between two emitter updates in ticks */
+
+ Particle(Map *map);
+
+ ~Particle();
+
+ /**
+ * Deletes all child particles and emitters
+ */
+ void
+ clear();
+
+ /**
+ * Gives a particle the properties of an engine root particle and loads
+ * the particle-related config settings
+ */
+ void
+ setupEngine();
+
+ /**
+ * Updates particle position, returns false when the particle should
+ * be deleted
+ */
+ virtual bool
+ update();
+
+ /**
+ * Draws the particle image
+ */
+ virtual void
+ draw(Graphics *graphics, int offsetX, int offsetY) const;
+
+ /**
+ * Necessary for sorting with the other sprites
+ */
+ virtual int
+ getPixelY() const
+ {
+ return (int)(mPosY + mPosZ) - 64;
+ };
+
+ /*
+ Basic Particle properties:
+ */
+
+ /**
+ * Sets the map the particle is on.
+ */
+ void setMap(Map *map);
+
+ /**
+ * Creates a child particle that hosts some emitters described in the
+ * particleEffectFile.
+ */
+ Particle*
+ addEffect(std::string particleEffectFile, int pixelX, int pixelY);
+
+ /**
+ * Creates a standalone text particle.
+ */
+ Particle*
+ addTextSplashEffect(std::string text, int colorR, int colorG, int colorB,
+ gcn::Font *font, int x, int y);
+
+ /**
+ * Adds an emitter to the particle.
+ */
+ void
+ addEmitter (ParticleEmitter* emitter)
+ { mChildEmitters.push_back(emitter); }
+
+ /**
+ * Sets the position in 3 dimensional space in pixels relative to map
+ */
+ void
+ setPosition(float x, float y, float z)
+ { mPosX = x; mPosY = y; mPosZ = z; }
+
+ /**
+ * Sets the position in 2 dimensional space in pixels relative to map
+ */
+ void
+ setPosition(float x, float y)
+ { mPosX = x; mPosY = y; }
+
+ float getPosX() const
+ { return mPosX; }
+
+ float getPosY() const
+ { return mPosY; }
+
+ float getPosZ() const
+ { return mPosZ; }
+
+ /**
+ * Changes the particle position relative
+ */
+ void
+ moveBy(float x, float y, float z)
+ { mPosX += x; mPosY += y; mPosZ += z; }
+
+ /**
+ * Sets the time in game ticks until the particle is destroyed.
+ */
+ void
+ setLifetime(int lifetime)
+ { mLifetimeLeft = lifetime; mLifetimePast = 0; }
+
+ /**
+ * Sets the age of the pixel in game ticks where the particle has
+ * faded in completely
+ */
+ void
+ setFadeOut (int fadeOut)
+ { mFadeOut = fadeOut; }
+
+ /**
+ * Sets the remaining particle lifetime where the particle starts to
+ * fade out
+ */
+ void
+ setFadeIn (int fadeIn)
+ { mFadeIn = fadeIn; }
+
+ /**
+ * Sets the sprite iterator of the particle on the current map to make
+ * it easier to remove the particle from the map when it is destroyed
+ */
+ void
+ setSpriteIterator(std::list<Sprite*>::iterator spriteIterator)
+ { mSpriteIterator = spriteIterator; }
+
+ /**
+ * Gets the sprite iterator of the particle on the current map
+ */
+ std::list<Sprite*>::iterator
+ getSpriteIterator() const
+ { return mSpriteIterator; }
+
+ /**
+ * Sets the current velocity in 3 dimensional space
+ */
+ void
+ setVector(float x, float y, float z)
+ { mVectorX = x; mVectorY = y; mVectorZ = z; }
+
+ /**
+ * Sets the downward acceleration
+ */
+ void
+ setGravity(float g)
+ { mGravity = g; }
+
+ /**
+ * Sets the ammount of random vector changes
+ */
+ void
+ setRandomnes(int r)
+ { mRandomnes = r; }
+
+ /**
+ * Sets the ammount of velocity particles retain after
+ * hitting the ground.
+ */
+ void
+ setBounce(float bouncieness)
+ { mBounce = bouncieness; }
+
+ /**
+ * Makes the particle move toward another particle with a
+ * given acceleration and momentum
+ */
+ void setDestination(Particle *target, float accel, float moment)
+ { mTarget = target; mAcceleration = accel; mMomentum = moment; }
+
+ /**
+ * Sets the distance in pixel the particle can come near the target
+ * particle before it is destroyed. Does only make sense after a
+ * target particle has been set using setDestination.
+ */
+ void setDieDistance(float dist)
+ { mInvDieDistance = 1.0f / dist; }
+
+ /**
+ * Manually marks the particle for deletion
+ */
+ void kill()
+ { mAlive = false; mAutoDelete = true; }
+
+ /**
+ * After calling this function the particle will only request
+ * deletion when kill() is called
+ */
+ void disableAutoDelete()
+ { mAutoDelete = false; }
+
+ protected:
+ bool mAlive; /**< Is the particle supposed to be drawn and updated?*/
+ float mPosX, mPosY, mPosZ; /**< Position in 3 dimensonal space - pixel based relative to map */
+ int mLifetimeLeft; /**< Lifetime left in game ticks*/
+ int mLifetimePast; /**< Age of the particle in game ticks*/
+ int mFadeOut; /**< Lifetime in game ticks left where fading out begins*/
+ int mFadeIn; /**< Age in game ticks where fading in is finished*/
+
+ private:
+ // generic properties
+ bool mAutoDelete; /**< May the particle request its deletion by the parent particle?*/
+ Map *mMap; /**< Map the particle is on*/
+ std::list<Sprite*>::iterator mSpriteIterator; /**< iterator of the particle on the current map */
+ Emitters mChildEmitters; /**< List of child emitters*/
+ Particles mChildParticles; /**< List of particles controlled by this particle*/
+ //dynamic particle
+ float mVectorX, mVectorY, mVectorZ; /**< Speed in 3 dimensional space in pixels per game-tick */
+ float mGravity; /**< Downward acceleration in pixels per game-tickČ*/
+ int mRandomnes; /**< Ammount of random vector change*/
+ float mBounce; /**< How much the particle bounces off when hitting the ground*/
+ //follow-point particles
+ Particle *mTarget; /**< The particle that attracts this particle*/
+ float mAcceleration; /**< Acceleration towards the target particle in pixels per game-tickČ*/
+ float mInvDieDistance; /**< Distance in pixels from the target particle that causes the destruction of the particle*/
+ float mMomentum; /**< How much speed the particle retains after each game tick*/
+};
+
+extern Particle *particleEngine;
+
+#endif
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index 393c443c..31e38d6d 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -187,19 +187,22 @@ Image* Image::load(void *buffer, unsigned int bufferSize,
bool hasAlpha = false;
- // Figure out whether the image uses its alpha layer
- for (int i = 0; i < tmpImage->w * tmpImage->h; ++i)
+ if (tmpImage->format->BitsPerPixel == 32)
{
- Uint8 r, g, b, a;
- SDL_GetRGBA(
- ((char*) tmpImage->pixels)[i * tmpImage->format->BitsPerPixel],
- tmpImage->format,
- &r, &g, &b, &a);
-
- if (a != 255)
+ // Figure out whether the image uses its alpha layer
+ for (int i = 0; i < tmpImage->w * tmpImage->h; ++i)
{
- hasAlpha = true;
- break;
+ Uint8 r, g, b, a;
+ SDL_GetRGBA(
+ ((Uint32*) tmpImage->pixels)[i],
+ tmpImage->format,
+ &r, &g, &b, &a);
+
+ if (a != 255)
+ {
+ hasAlpha = true;
+ break;
+ }
}
}