All pastes #1843553 Raw Edit

Something

public text v1 · immutable
#1843553 ·published 2010-03-17 14:02 UTC
rendered paste body
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 <map>
+
 #include "resources/resource.h"
 
 #include <SDL.h>
@@ -42,6 +44,7 @@
 class Dye;
 class Position;
 
+typedef std::map<float, SDL_Surface* > 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;