diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 0e7dc89..49095dc 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -33,6 +33,21 @@ int Image::mTextureType = 0; int Image::mTextureSize = 0; #endif +// This function exists in this file only +SDL_Surface *duplicateSurface (SDL_Surface* surf) +{ + SDL_Surface* cpy; + cpy = (SDL_Surface *)malloc(sizeof(SDL_Surface)); + memcpy((SDL_Surface *)cpy, (SDL_Surface *)surf, sizeof(SDL_Surface)); + cpy->format = (SDL_PixelFormat *)malloc(sizeof(SDL_PixelFormat)); + memcpy((SDL_PixelFormat *)cpy->format, (SDL_PixelFormat *)surf->format, + sizeof(SDL_PixelFormat)); + size_t size = surf->pitch * surf->h; + cpy->pixels = malloc(size); + memcpy((Uint8 *)cpy->pixels, (Uint8 *)surf->pixels, size * sizeof(Uint8)); + return cpy; +} + Image::Image(SDL_Surface *image, bool hasAlphaChannel, Uint8 *alphaChannel): mAlpha(1.0f), mHasAlphaChannel(hasAlphaChannel), @@ -165,6 +180,19 @@ void Image::unload() { mLoaded = false; + // Clear the cache + SurfaceCache::iterator it = mSDLSurfaceCache.begin(); + while (it != mSDLSurfaceCache.end()) + { + // We delete mSDLSurface later + if (it->second != mSDLSurface && it->second) + { + SDL_FreeSurface(it->second); + it->second = NULL; + } + it++; + } + if (mSDLSurface) { // Free the image surface. @@ -214,10 +242,24 @@ void Image::setAlpha(float alpha) if (alpha < 0.0f || alpha > 1.0f) return; + float oldAlpha = mAlpha; mAlpha = alpha; if (mSDLSurface) { + // See if we need to cache oldAlpha (currently in mSDLSurface) + SurfaceCache::iterator cache = mSDLSurfaceCache.find(oldAlpha); + if (cache == mSDLSurfaceCache.end()) + { + mSDLSurfaceCache[oldAlpha] = duplicateSurface(mSDLSurface); + } + // See if the new alpha is already in the cache + cache = mSDLSurfaceCache.find(mAlpha); + if (cache != mSDLSurfaceCache.end()) + { + mSDLSurface = cache->second; + return; + } if (!hasAlphaChannel()) { // Set the alpha value this image is drawn at diff --git a/src/resources/image.h b/src/resources/image.h index 3e8ad55..83808cf 100644 --- a/src/resources/image.h +++ b/src/resources/image.h @@ -24,6 +24,8 @@ #include "main.h" +#include + #include "resources/resource.h" #include @@ -42,6 +44,7 @@ class Dye; class Position; +typedef std::map SurfaceCache; /** * Defines a class for loading and storing images. */ @@ -210,6 +213,9 @@ class Image : public Resource SDL_Surface *mSDLSurface; + /** Used to cache different alphas */ + SurfaceCache mSDLSurfaceCache; + /** Alpha Channel pointer used for 32bit based SDL surfaces */ Uint8 *mAlphaChannel;