From 6276c1ff96e449e73e84977110334cd8957c31b6 Mon Sep 17 00:00:00 2001 From: Bjørn Lindeijer Date: Sun, 3 Jun 2007 16:52:06 +0000 Subject: Fixed image loading in software mode to not check for alpha layer with images aren't 32-bit and removed drawImageTransparent from Graphics class, should be set on image. --- ChangeLog | 4 +- src/graphics.cpp | 13 - src/graphics.h | 8 - src/imageparticle.cpp | 26 +- src/imageparticle.h | 1 + src/particle.cpp | 738 ++++++++++++++++++++++++------------------------ src/particle.h | 559 ++++++++++++++++++------------------ src/resources/image.cpp | 25 +- 8 files changed, 679 insertions(+), 695 deletions(-) diff --git a/ChangeLog b/ChangeLog index c71110de..f121a552 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,7 +5,9 @@ * 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 - assume all images are 32-bit. + check for alpha layer with images aren't 32-bit. + * src/graphics.cpp, src/graphics.h, src/imageparticle.cpp: Removed + drawImageTransparent from Graphics class, should be set on image. 2007-06-02 Bjørn Lindeijer 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 true if the image was blitted properly - * false 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 - -#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 + +#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 -#include - -#include - -#include "guichanfwd.h" -#include "sprite.h" - - -class Map; -class Particle; -class ParticleEmitter; - -typedef std::list Particles; -typedef Particles::iterator ParticleIterator; -typedef std::list 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::iterator spriteIterator) - { mSpriteIterator = spriteIterator; }; - - /** - * Gets the sprite iterator of the particle on the current map - */ - std::list::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::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 +#include + +#include + +#include "guichanfwd.h" +#include "sprite.h" + + +class Map; +class Particle; +class ParticleEmitter; + +typedef std::list Particles; +typedef Particles::iterator ParticleIterator; +typedef std::list 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::iterator spriteIterator) + { mSpriteIterator = spriteIterator; } + + /** + * Gets the sprite iterator of the particle on the current map + */ + std::list::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::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; + } } } -- cgit v1.2.3-70-g09d2