summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/map.cpp12
-rw-r--r--src/openglgraphics.cpp1
-rw-r--r--src/particle.cpp44
-rw-r--r--src/resources/image.cpp79
-rw-r--r--src/resources/image.h10
5 files changed, 117 insertions, 29 deletions
diff --git a/src/map.cpp b/src/map.cpp
index bda618e2..877a8ba9 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -120,10 +120,8 @@ Image* MapLayer::getTile(int x, int y) const
return mTiles[x + y * mWidth];
}
-void MapLayer::draw(Graphics *graphics,
- int startX, int startY,
- int endX, int endY,
- int scrollX, int scrollY,
+void MapLayer::draw(Graphics *graphics, int startX, int startY,
+ int endX, int endY, int scrollX, int scrollY,
const Sprites &sprites) const
{
startX -= mX;
@@ -164,8 +162,10 @@ void MapLayer::draw(Graphics *graphics,
}
// Draw any remaining sprites
- if (mIsFringeLayer) {
- while (si != sprites.end()) {
+ if (mIsFringeLayer)
+ {
+ while (si != sprites.end())
+ {
(*si)->draw(graphics, -scrollX, -scrollY);
si++;
}
diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp
index 78b502ea..df8d264f 100644
--- a/src/openglgraphics.cpp
+++ b/src/openglgraphics.cpp
@@ -233,7 +233,6 @@ void OpenGLGraphics::drawImagePattern(Image *image, int x, int y, int w, int h)
glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a);
}
-
void OpenGLGraphics::updateScreen()
{
glFlush();
diff --git a/src/particle.cpp b/src/particle.cpp
index e56435ed..0e412ada 100644
--- a/src/particle.cpp
+++ b/src/particle.cpp
@@ -177,7 +177,8 @@ bool Particle::update()
mVelocity *= mBounce;
mVelocity.z = -mVelocity.z;
}
- else {
+ else
+ {
mAlive = false;
}
}
@@ -185,16 +186,12 @@ bool Particle::update()
// Update child emitters
if ((mLifetimePast-1)%Particle::emitterSkip == 0)
{
- for ( EmitterIterator e = mChildEmitters.begin();
- e != mChildEmitters.end();
- e++
- )
+ for (EmitterIterator e = mChildEmitters.begin();
+ e != mChildEmitters.end(); e++)
{
Particles newParticles = (*e)->createParticles(mLifetimePast);
- for ( ParticleIterator p = newParticles.begin();
- p != newParticles.end();
- p++
- )
+ for (ParticleIterator p = newParticles.begin();
+ p != newParticles.end(); p++)
{
(*p)->moveBy(mPos);
mChildParticles.push_back (*p);
@@ -219,7 +216,9 @@ bool Particle::update()
if ((*p)->update())
{
p++;
- } else {
+ }
+ else
+ {
delete (*p);
p = mChildParticles.erase(p);
}
@@ -237,8 +236,7 @@ void Particle::moveBy(const Vector &change)
{
mPos += change;
for (ParticleIterator p = mChildParticles.begin();
- p != mChildParticles.end();
- p++)
+ p != mChildParticles.end(); p++)
{
if ((*p)->doesFollow())
{
@@ -279,20 +277,21 @@ Particle* Particle::addEffect(const std::string &particleEffectFile,
xmlNodePtr node;
// Animation
- if ((node = XML::findFirstChildByName(
- effectChildNode, "animation"))) {
+ if ((node = XML::findFirstChildByName(effectChildNode, "animation")))
+ {
newParticle = new AnimationParticle(mMap, node);
}
// Image
- else if ((node = XML::findFirstChildByName(
- effectChildNode, "image"))) {
+ else if ((node = XML::findFirstChildByName(effectChildNode, "image")))
+ {
Image *img= resman->getImage((const char*)
node->xmlChildrenNode->content);
newParticle = new ImageParticle(mMap, img);
}
// Other
- else {
+ else
+ {
newParticle = new Particle(mMap);
}
@@ -315,7 +314,8 @@ Particle* Particle::addEffect(const std::string &particleEffectFile,
continue;
ParticleEmitter *newEmitter;
- newEmitter = new ParticleEmitter(emitterNode, newParticle, mMap, rotation);
+ newEmitter = new ParticleEmitter(emitterNode, newParticle, mMap,
+ rotation);
newParticle->addEmitter(newEmitter);
}
@@ -326,7 +326,8 @@ Particle* Particle::addEffect(const std::string &particleEffectFile,
}
Particle *Particle::addTextSplashEffect(const std::string &text, int x, int y,
- const gcn::Color *color, gcn::Font *font, bool outline)
+ const gcn::Color *color,
+ gcn::Font *font, bool outline)
{
Particle *newParticle = new TextParticle(mMap, text, color, font, outline);
newParticle->moveTo(x, y);
@@ -344,7 +345,10 @@ Particle *Particle::addTextSplashEffect(const std::string &text, int x, int y,
}
Particle *Particle::addTextRiseFadeOutEffect(const std::string &text,
- int x, int y, const gcn::Color *color, gcn::Font *font, bool outline){
+ int x, int y,
+ const gcn::Color *color,
+ gcn::Font *font, bool outline)
+{
Particle *newParticle = new TextParticle(mMap, text, color, font, outline);
newParticle->moveTo(x, y);
newParticle->setVelocity(0.0f, 0.0f, 0.5f);
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index 7a15b762..cff40197 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -26,6 +26,7 @@
#include "image.h"
#include "../log.h"
+#include "../position.h"
#ifdef USE_OPENGL
bool Image::mUseOpenGL = false;
@@ -47,8 +48,7 @@ Image::Image(SDL_Surface *image):
}
#ifdef USE_OPENGL
-Image::Image(GLuint glimage, int width, int height,
- int texWidth, int texHeight):
+Image::Image(GLuint glimage, int width, int height, int texWidth, int texHeight):
mGLImage(glimage),
mTexWidth(texWidth),
mTexHeight(texHeight),
@@ -316,6 +316,81 @@ void Image::setAlpha(float a)
}
}
+Image* Image::merge(Image* image, const Position& pos)
+{
+ SDL_Surface* surface = new SDL_Surface(*(image->mImage));
+
+ Uint32 surface_pix, cur_pix;
+ Uint8 r, g, b, a, p_r, p_g, p_b, p_a;
+ double f_a, f_ca, f_pa;
+ SDL_PixelFormat *current_fmt = mImage->format;
+ SDL_PixelFormat *surface_fmt = surface->format;
+ int current_offset, surface_offset;
+ Position offset(0, 0);
+
+ SDL_LockSurface(surface);
+ SDL_LockSurface(mImage);
+ // for each pixel lines of a source image
+ for (offset.x = (pos.x > 0 ? 0 : -pos.x); offset.x < image->getWidth() &&
+ pos.x + offset.x < getWidth(); offset.x++)
+ {
+ for (offset.y = (pos.y > 0 ? 0 : -pos.y); offset.y < image->getHeight()
+ && pos.y + offset.y < getHeight(); offset.y++)
+ {
+ // Computing offset on both images
+ current_offset = (pos.y + offset.y) * getWidth() + pos.x + offset.x;
+ surface_offset = offset.y * surface->w + offset.x;
+
+ // Retrieving a pixel to merge
+ surface_pix = ((Uint32*) surface->pixels)[surface_offset];
+ cur_pix = ((Uint32*) mImage->pixels)[current_offset];
+
+ // Retreiving each channel of the pixel using pixel format
+ r = (Uint8)(((surface_pix & surface_fmt->Rmask) >>
+ surface_fmt->Rshift) << surface_fmt->Rloss);
+ g = (Uint8)(((surface_pix & surface_fmt->Gmask) >>
+ surface_fmt->Gshift) << surface_fmt->Gloss);
+ b = (Uint8)(((surface_pix & surface_fmt->Bmask) >>
+ surface_fmt->Bshift) << surface_fmt->Bloss);
+ a = (Uint8)(((surface_pix & surface_fmt->Amask) >>
+ surface_fmt->Ashift) << surface_fmt->Aloss);
+
+ // Retreiving previous alpha value
+ p_a = (Uint8)(((cur_pix & current_fmt->Amask) >>
+ current_fmt->Ashift) << current_fmt->Aloss);
+
+ // new pixel with no alpha or nothing on previous pixel
+ if (a == SDL_ALPHA_OPAQUE || (p_a == 0 && a > 0))
+ ((Uint32 *)(surface->pixels))[current_offset] =
+ SDL_MapRGBA(current_fmt, r, g, b, a);
+ else if (a > 0)
+ { // alpha is lower => merge color with previous value
+ f_a = (double) a / 255.0;
+ f_ca = 1.0 - f_a;
+ f_pa = (double) p_a / 255.0;
+ p_r = (Uint8)(((cur_pix & current_fmt->Rmask) >>
+ current_fmt->Rshift) << current_fmt->Rloss);
+ p_g = (Uint8)(((cur_pix & current_fmt->Gmask) >>
+ current_fmt->Gshift) << current_fmt->Gloss);
+ p_b = (Uint8)(((cur_pix & current_fmt->Bmask) >>
+ current_fmt->Bshift) << current_fmt->Bloss);
+ r = (Uint8)((double) p_r * f_ca * f_pa + (double)r * f_a);
+ g = (Uint8)((double) p_g * f_ca * f_pa + (double)g * f_a);
+ b = (Uint8)((double) p_b * f_ca * f_pa + (double)b * f_a);
+ a = (a > p_a ? a : p_a);
+ ((Uint32 *)(surface->pixels))[current_offset] =
+ SDL_MapRGBA(current_fmt, r, g, b, a);
+ }
+ }
+ }
+ SDL_UnlockSurface(surface);
+ SDL_UnlockSurface(mImage);
+
+ Image* newImage = new Image(surface);
+
+ return newImage;
+}
+
float Image::getAlpha()
{
return mAlpha;
diff --git a/src/resources/image.h b/src/resources/image.h
index 596917ce..f6b77f26 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -41,6 +41,7 @@
#include "resource.h"
class Dye;
+class Position;
class SDL_Rect;
class SDL_Surface;
@@ -132,6 +133,15 @@ class Image : public Resource
static void setLoadAsOpenGL(bool useOpenGL);
#endif
+ /**
+ * Merges two image SDL_Surfaces together. This is for SDL use only, as
+ * reducing the number of surfaces that SDL has to render can cut down
+ * on the number of blit operations necessary, which in turn can help
+ * improve overall framerates. Don't use unless you are using it to
+ * reduce the number of overall layers that need to be drawn through SDL.
+ */
+ Image* merge(Image* image, const Position& pos);
+
protected:
/**
* Constructor.