summaryrefslogtreecommitdiff
path: root/src/resources
diff options
context:
space:
mode:
Diffstat (limited to 'src/resources')
-rw-r--r--src/resources/image.cpp431
-rw-r--r--src/resources/image.h112
-rw-r--r--src/resources/iteminfo.h2
-rw-r--r--src/resources/wallpaper.cpp91
4 files changed, 400 insertions, 236 deletions
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index 9af3059a..d2a1c82e 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -34,31 +34,56 @@ int Image::mTextureType = 0;
int Image::mTextureSize = 0;
#endif
-Image::Image(SDL_Surface *image):
+Image::Image(SDL_Surface *image, bool hasAlphaChannel, Uint8 *alphaChannel):
+ mAlpha(1.0f),
+ mHasAlphaChannel(hasAlphaChannel),
+ mSDLSurface(image),
+ mAlphaChannel(alphaChannel)
+{
#ifdef USE_OPENGL
- mGLImage(0),
+ mGLImage = 0;
#endif
- mImage(image),
- mAlpha(1.0f)
-{
+
mBounds.x = 0;
mBounds.y = 0;
- mBounds.w = mImage->w;
- mBounds.h = mImage->h;
+
+ mLoaded = false;
+
+ if (mSDLSurface)
+ {
+ mBounds.w = mSDLSurface->w;
+ mBounds.h = mSDLSurface->h;
+
+ mLoaded = true;
+ }
+ else
+ logger->log(
+ "Image::Image(SDL_Surface*): Couldn't load invalid Surface!");
}
#ifdef USE_OPENGL
Image::Image(GLuint glimage, int width, int height, int texWidth, int texHeight):
+ mAlpha(1.0f),
+ mHasAlphaChannel(true),
+ mSDLSurface(0),
+ mAlphaChannel(0),
mGLImage(glimage),
mTexWidth(texWidth),
- mTexHeight(texHeight),
- mImage(0),
- mAlpha(1.0)
+ mTexHeight(texHeight)
{
mBounds.x = 0;
mBounds.y = 0;
mBounds.w = width;
mBounds.h = height;
+
+ if (mGLImage)
+ mLoaded = true;
+ else
+ {
+ logger->log(
+ "Image::Image(GLuint*, ...): Couldn't load invalid Surface!");
+ mLoaded = false;
+ }
}
#endif
@@ -132,153 +157,23 @@ Image *Image::load(SDL_Surface *tmpImage)
{
#ifdef USE_OPENGL
if (mUseOpenGL)
- {
- // Flush current error flag.
- glGetError();
-
- int width = tmpImage->w;
- int height = tmpImage->h;
- int realWidth = powerOfTwo(width);
- int realHeight = powerOfTwo(height);
-
- if (realWidth < width || realHeight < height)
- {
- logger->log("Warning: image too large, cropping to %dx%d texture!",
- tmpImage->w, tmpImage->h);
- }
-
- // Make sure the alpha channel is not used, but copied to destination
- SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE);
-
- // Determine 32-bit masks based on byte order
- Uint32 rmask, gmask, bmask, amask;
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- rmask = 0xff000000;
- gmask = 0x00ff0000;
- bmask = 0x0000ff00;
- amask = 0x000000ff;
-#else
- rmask = 0x000000ff;
- gmask = 0x0000ff00;
- bmask = 0x00ff0000;
- amask = 0xff000000;
-#endif
-
- SDL_Surface *oldImage = tmpImage;
- tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight,
- 32, rmask, gmask, bmask, amask);
-
- if (!tmpImage)
- {
- logger->log("Error, image convert failed: out of memory");
- return NULL;
- }
-
- SDL_BlitSurface(oldImage, NULL, tmpImage, NULL);
-
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(mTextureType, texture);
-
- if (SDL_MUSTLOCK(tmpImage))
- SDL_LockSurface(tmpImage);
-
- glTexImage2D(
- mTextureType, 0, 4,
- tmpImage->w, tmpImage->h,
- 0, GL_RGBA, GL_UNSIGNED_BYTE,
- tmpImage->pixels);
-
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glTexParameteri(mTextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(mTextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- if (SDL_MUSTLOCK(tmpImage)) {
- SDL_UnlockSurface(tmpImage);
- }
-
- SDL_FreeSurface(tmpImage);
-
- GLenum error = glGetError();
- if (error)
- {
- std::string errmsg = "Unknown error";
- switch (error)
- {
- case GL_INVALID_ENUM:
- errmsg = "GL_INVALID_ENUM";
- break;
- case GL_INVALID_VALUE:
- errmsg = "GL_INVALID_VALUE";
- break;
- case GL_INVALID_OPERATION:
- errmsg = "GL_INVALID_OPERATION";
- break;
- case GL_STACK_OVERFLOW:
- errmsg = "GL_STACK_OVERFLOW";
- break;
- case GL_STACK_UNDERFLOW:
- errmsg = "GL_STACK_UNDERFLOW";
- break;
- case GL_OUT_OF_MEMORY:
- errmsg = "GL_OUT_OF_MEMORY";
- break;
- }
- logger->log("Error: Image GL import failed: %s", errmsg.c_str());
- return NULL;
- }
-
- return new Image(texture, width, height, realWidth, realHeight);
- }
+ return _GLload(tmpImage);
#endif
-
- bool hasAlpha = false;
-
- if (tmpImage->format->BitsPerPixel == 32)
- {
- // Figure out whether the image uses its alpha layer
- for (int i = 0; i < tmpImage->w * tmpImage->h; ++i)
- {
- Uint8 r, g, b, a;
- SDL_GetRGBA(
- ((Uint32*) tmpImage->pixels)[i],
- tmpImage->format,
- &r, &g, &b, &a);
-
- if (a != 255)
- {
- hasAlpha = true;
- break;
- }
- }
- }
-
- SDL_Surface *image;
-
- // Convert the surface to the current display format
- if (hasAlpha)
- image = SDL_DisplayFormatAlpha(tmpImage);
- else
- image = SDL_DisplayFormat(tmpImage);
-
- if (!image)
- {
- logger->log("Error: Image convert failed.");
- return NULL;
- }
-
- return new Image(image);
+ return _SDLload(tmpImage);
}
void Image::unload()
{
mLoaded = false;
- if (mImage)
+ if (mSDLSurface)
{
// Free the image surface.
- SDL_FreeSurface(mImage);
- mImage = NULL;
+ SDL_FreeSurface(mSDLSurface);
+ mSDLSurface = NULL;
+
+ delete[] mAlphaChannel;
+ mAlphaChannel = NULL;
}
#ifdef USE_OPENGL
@@ -299,34 +194,79 @@ bool Image::isAnOpenGLOne() const
#endif
}
-void Image::setAlpha(float a)
+bool Image::hasAlphaChannel()
{
- if (mAlpha == a)
+ if (mLoaded)
+ return mHasAlphaChannel;
+
+#ifdef USE_OPENGL
+ if (mUseOpenGL)
+ return true;
+#endif
+
+ return false;
+}
+
+void Image::setAlpha(float alpha)
+{
+ if (mAlpha == alpha)
return;
- mAlpha = a;
+ if (alpha < 0.0f || alpha > 1.0f)
+ return;
- if (mImage)
+ mAlpha = alpha;
+
+ if (mSDLSurface)
{
- // Set the alpha value this image is drawn at
- SDL_SetAlpha(mImage, SDL_SRCALPHA, (int) (255 * mAlpha));
+ if (!hasAlphaChannel())
+ {
+ // Set the alpha value this image is drawn at
+ SDL_SetAlpha(mSDLSurface, SDL_SRCALPHA, (int) (255 * mAlpha));
+ }
+ else
+ {
+ if (SDL_MUSTLOCK(mSDLSurface))
+ SDL_LockSurface(mSDLSurface);
+
+ for (int i = 0; i < mSDLSurface->w * mSDLSurface->h; ++i)
+ {
+ Uint8 r, g, b, a;
+ SDL_GetRGBA(
+ ((Uint32*) mSDLSurface->pixels)[i],
+ mSDLSurface->format,
+ &r, &g, &b, &a);
+
+ a = (Uint8) (mAlphaChannel[i] * mAlpha);
+
+ // Here is the pixel we want to set
+ ((Uint32 *)(mSDLSurface->pixels))[i] =
+ SDL_MapRGBA(mSDLSurface->format, r, g, b, a);
+ }
+
+ if (SDL_MUSTLOCK(mSDLSurface))
+ SDL_UnlockSurface(mSDLSurface);
+ }
}
}
-Image* Image::merge(Image *image, int x, int y)
+Image* Image::SDLmerge(Image *image, int x, int y)
{
- SDL_Surface* surface = new SDL_Surface(*(image->mImage));
+ if (!mSDLSurface)
+ return NULL;
+
+ SDL_Surface* surface = new SDL_Surface(*(image->mSDLSurface));
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 *current_fmt = mSDLSurface->format;
SDL_PixelFormat *surface_fmt = surface->format;
int current_offset, surface_offset;
int offset_x, offset_y;
SDL_LockSurface(surface);
- SDL_LockSurface(mImage);
+ SDL_LockSurface(mSDLSurface);
// for each pixel lines of a source image
for (offset_x = (x > 0 ? 0 : -x); offset_x < image->getWidth() &&
x + offset_x < getWidth(); offset_x++)
@@ -340,7 +280,7 @@ Image* Image::merge(Image *image, int x, int y)
// Retrieving a pixel to merge
surface_pix = ((Uint32*) surface->pixels)[surface_offset];
- cur_pix = ((Uint32*) mImage->pixels)[current_offset];
+ cur_pix = ((Uint32*) mSDLSurface->pixels)[current_offset];
// Retreiving each channel of the pixel using pixel format
r = (Uint8)(((surface_pix & surface_fmt->Rmask) >>
@@ -381,18 +321,13 @@ Image* Image::merge(Image *image, int x, int y)
}
}
SDL_UnlockSurface(surface);
- SDL_UnlockSurface(mImage);
+ SDL_UnlockSurface(mSDLSurface);
Image *newImage = new Image(surface);
return newImage;
}
-float Image::getAlpha() const
-{
- return mAlpha;
-}
-
Image* Image::SDLgetScaledImage(int width, int height)
{
// No scaling on incorrect new values.
@@ -406,9 +341,9 @@ Image* Image::SDLgetScaledImage(int width, int height)
Image* scaledImage = NULL;
SDL_Surface* scaledSurface = NULL;
- if (mImage)
+ if (mSDLSurface)
{
- scaledSurface = _SDLzoomSurface(mImage,
+ scaledSurface = _SDLzoomSurface(mSDLSurface,
(double) width / getWidth(),
(double) height / getHeight(),
1);
@@ -421,7 +356,160 @@ Image* Image::SDLgetScaledImage(int width, int height)
return scaledImage;
}
+Image *Image::_SDLload(SDL_Surface *tmpImage)
+{
+ if (!tmpImage)
+ return NULL;
+
+ bool hasAlpha = false;
+
+ // The alpha channel to be filled with alpha values
+ Uint8 *alphaChannel = new Uint8[tmpImage->w * tmpImage->h];
+
+ if (tmpImage->format->BitsPerPixel == 32)
+ {
+ // Figure out whether the image uses its alpha layer
+ for (int i = 0; i < tmpImage->w * tmpImage->h; ++i)
+ {
+ Uint8 r, g, b, a;
+ SDL_GetRGBA(
+ ((Uint32*) tmpImage->pixels)[i],
+ tmpImage->format,
+ &r, &g, &b, &a);
+
+ if (a != 255)
+ hasAlpha = true;
+
+ alphaChannel[i] = a;
+ }
+ }
+
+ SDL_Surface *image;
+
+ // Convert the surface to the current display format
+ if (hasAlpha)
+ image = SDL_DisplayFormatAlpha(tmpImage);
+ else
+ {
+ image = SDL_DisplayFormat(tmpImage);
+
+ // We also delete the alpha channel since
+ // it's not used.
+ delete[] alphaChannel;
+ alphaChannel = NULL;
+ }
+
+ if (!image)
+ {
+ logger->log("Error: Image convert failed.");
+ delete[] alphaChannel;
+ return NULL;
+ }
+
+ return new Image(image, hasAlpha, alphaChannel);
+}
+
#ifdef USE_OPENGL
+Image *Image::_GLload(SDL_Surface *tmpImage)
+{
+ // Flush current error flag.
+ glGetError();
+
+ int width = tmpImage->w;
+ int height = tmpImage->h;
+ int realWidth = powerOfTwo(width);
+ int realHeight = powerOfTwo(height);
+
+ if (realWidth < width || realHeight < height)
+ {
+ logger->log("Warning: image too large, cropping to %dx%d texture!",
+ tmpImage->w, tmpImage->h);
+ }
+
+ // Make sure the alpha channel is not used, but copied to destination
+ SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE);
+
+ // Determine 32-bit masks based on byte order
+ Uint32 rmask, gmask, bmask, amask;
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ rmask = 0xff000000;
+ gmask = 0x00ff0000;
+ bmask = 0x0000ff00;
+ amask = 0x000000ff;
+#else
+ rmask = 0x000000ff;
+ gmask = 0x0000ff00;
+ bmask = 0x00ff0000;
+ amask = 0xff000000;
+#endif
+
+ SDL_Surface *oldImage = tmpImage;
+ tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight,
+ 32, rmask, gmask, bmask, amask);
+
+ if (!tmpImage)
+ {
+ logger->log("Error, image convert failed: out of memory");
+ return NULL;
+ }
+
+ SDL_BlitSurface(oldImage, NULL, tmpImage, NULL);
+
+ GLuint texture;
+ glGenTextures(1, &texture);
+ glBindTexture(mTextureType, texture);
+
+ if (SDL_MUSTLOCK(tmpImage))
+ SDL_LockSurface(tmpImage);
+
+ glTexImage2D(
+ mTextureType, 0, 4,
+ tmpImage->w, tmpImage->h,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ tmpImage->pixels);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glTexParameteri(mTextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(mTextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ if (SDL_MUSTLOCK(tmpImage)) {
+ SDL_UnlockSurface(tmpImage);
+ }
+
+ SDL_FreeSurface(tmpImage);
+
+ GLenum error = glGetError();
+ if (error)
+ {
+ std::string errmsg = "Unknown error";
+ switch (error)
+ {
+ case GL_INVALID_ENUM:
+ errmsg = "GL_INVALID_ENUM";
+ break;
+ case GL_INVALID_VALUE:
+ errmsg = "GL_INVALID_VALUE";
+ break;
+ case GL_INVALID_OPERATION:
+ errmsg = "GL_INVALID_OPERATION";
+ break;
+ case GL_STACK_OVERFLOW:
+ errmsg = "GL_STACK_OVERFLOW";
+ break;
+ case GL_STACK_UNDERFLOW:
+ errmsg = "GL_STACK_UNDERFLOW";
+ break;
+ case GL_OUT_OF_MEMORY:
+ errmsg = "GL_OUT_OF_MEMORY";
+ break;
+ }
+ logger->log("Error: Image GL import failed: %s", errmsg.c_str());
+ return NULL;
+ }
+
+ return new Image(texture, width, height, realWidth, realHeight);
+}
+
void Image::setLoadAsOpenGL(bool useOpenGL)
{
Image::mUseOpenGL = useOpenGL;
@@ -455,7 +543,7 @@ Image *Image::getSubImage(int x, int y, int width, int height)
mTexWidth, mTexHeight);
#endif
- return new SubImage(this, mImage, x, y, width, height);
+ return new SubImage(this, mSDLSurface, x, y, width, height);
}
//============================================================================
@@ -469,6 +557,9 @@ SubImage::SubImage(Image *parent, SDL_Surface *image,
{
mParent->incRef();
+ mHasAlphaChannel = mParent->hasAlphaChannel();
+ mAlphaChannel = mParent->SDLgetAlphaChannel();
+
// Set up the rectangle.
mBounds.x = x;
mBounds.y = y;
@@ -496,7 +587,9 @@ SubImage::SubImage(Image *parent, GLuint image,
SubImage::~SubImage()
{
// Avoid destruction of the image
- mImage = 0;
+ mSDLSurface = 0;
+ // Avoid possible destruction of its alpha channel
+ mAlphaChannel = 0;
#ifdef USE_OPENGL
mGLImage = 0;
#endif
diff --git a/src/resources/image.h b/src/resources/image.h
index f497f608..9c0f9da7 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -88,19 +88,15 @@ class Image : public Resource
static Image *load(SDL_Surface *);
/**
- * Gets an scaled instance of an image.
- *
- * @param width The desired width of the scaled image.
- * @param height The desired height of the scaled image.
- *
- * @return A new Image* object.
+ * Frees the resources created by SDL.
*/
- Image* SDLgetScaledImage(int width, int height);
+ virtual void unload();
/**
- * Frees the resources created by SDL.
+ * Tells is the image is loaded
*/
- virtual void unload();
+ bool isLoaded()
+ { return mLoaded; }
/**
* Returns the width of the image.
@@ -115,12 +111,29 @@ class Image : public Resource
{ return mBounds.h; }
/**
- * Tells if the image was loade using OpenGL or SDL
+ * Tells if the image was loaded using OpenGL or SDL
* @return true if OpenGL, false if SDL.
*/
bool isAnOpenGLOne() const;
/**
+ * Tells if the image has got an alpha channel
+ * @return true if it's true, false otherwise.
+ */
+ bool hasAlphaChannel();
+
+ /**
+ * Sets the alpha value of this image.
+ */
+ virtual void setAlpha(float alpha);
+
+ /**
+ * Returns the alpha value of this image.
+ */
+ float getAlpha() const
+ { return mAlpha; }
+
+ /**
* Creates a new image with the desired clipping rectangle.
*
* @return <code>NULL</code> if creation failed and a valid
@@ -128,17 +141,38 @@ class Image : public Resource
*/
virtual Image *getSubImage(int x, int y, int width, int height);
+
+ // SDL only public functions
+
/**
- * Sets the alpha value of this image.
+ * Gets an scaled instance of an image.
+ *
+ * @param width The desired width of the scaled image.
+ * @param height The desired height of the scaled image.
+ *
+ * @return A new Image* object.
*/
- virtual void setAlpha(float alpha);
+ Image* SDLgetScaledImage(int width, int height);
/**
- * Returns the alpha value of this image.
+ * 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.
*/
- float getAlpha() const;
+ Image *SDLmerge(Image *image, int x, int y);
+
+ /**
+ * Get the alpha Channel of a SDL surface.
+ */
+ Uint8 *SDLgetAlphaChannel() const
+ { return mAlphaChannel; }
#ifdef USE_OPENGL
+
+ // OpenGL only public functions
+
/**
* Sets the target image format. Use <code>false</code> for SDL and
* <code>true</code> for OpenGL.
@@ -150,20 +184,40 @@ class Image : public Resource
static int getTextureType() { return mTextureType; }
#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, int x, int y);
-
protected:
+
+ // -----------------------
+ // Generic protected members
+ // -----------------------
+
+ SDL_Rect mBounds;
+ bool mLoaded;
+ float mAlpha;
+ bool mHasAlphaChannel;
+
+ // -----------------------
+ // SDL protected members
+ // -----------------------
+
+ /** SDL Constructor */
+ Image(SDL_Surface *image, bool hasAlphaChannel = false,
+ Uint8 *alphaChannel = NULL);
+
+ /** SDL_Surface to SDL_Surface Image loader */
+ static Image *_SDLload(SDL_Surface *tmpImage);
+
+ SDL_Surface *mSDLSurface;
+
+ /** Alpha Channel pointer used for 32bit based SDL surfaces */
+ Uint8 *mAlphaChannel;
+
+ // -----------------------
+ // OpenGL protected members
+ // -----------------------
+#ifdef USE_OPENGL
/**
- * Constructor.
+ * OpenGL Constructor.
*/
-#ifdef USE_OPENGL
Image(GLuint glimage, int width, int height,
int texWidth, int texHeight);
@@ -171,13 +225,9 @@ class Image : public Resource
* Returns the first power of two equal or bigger than the input.
*/
static int powerOfTwo(int input);
-#endif
- Image(SDL_Surface *image);
- SDL_Rect mBounds;
- bool mLoaded;
+ static Image *_GLload(SDL_Surface *tmpImage);
-#ifdef USE_OPENGL
GLuint mGLImage;
int mTexWidth, mTexHeight;
@@ -185,8 +235,6 @@ class Image : public Resource
static int mTextureType;
static int mTextureSize;
#endif
- SDL_Surface *mImage;
- float mAlpha;
};
/**
diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h
index 0c87b585..6c033490 100644
--- a/src/resources/iteminfo.h
+++ b/src/resources/iteminfo.h
@@ -24,7 +24,7 @@
#include "resources/spritedef.h"
-#include "being.h"
+#include "player.h"
#include <map>
#include <string>
diff --git a/src/resources/wallpaper.cpp b/src/resources/wallpaper.cpp
index bc9728d0..f0e834b1 100644
--- a/src/resources/wallpaper.cpp
+++ b/src/resources/wallpaper.cpp
@@ -32,18 +32,19 @@
#include <physfs.h>
#define WALLPAPER_FOLDER "graphics/images/"
-#define WALLPAPER_BASE "login_wallpaper"
+#define WALLPAPER_BASE "login_wallpaper.png"
-struct WallpaperSize
+struct WallpaperData
{
+ std::string filename;
int width;
int height;
};
-static std::vector<WallpaperSize> wallpaperSizes;
+static std::vector<WallpaperData> wallpaperData;
static bool haveBackup; // Is the backup (no size given) version available?
-bool wallpaperCompare(WallpaperSize a, WallpaperSize b)
+bool wallpaperCompare(WallpaperData a, WallpaperData b)
{
int aa = a.width * a.height;
int ab = b.width * b.height;
@@ -53,60 +54,82 @@ bool wallpaperCompare(WallpaperSize a, WallpaperSize b)
void Wallpaper::loadWallpapers()
{
- wallpaperSizes.clear();
-
- size_t baseLen = strlen(WALLPAPER_BASE);
- haveBackup = false;
+ wallpaperData.clear();
char **imgs = PHYSFS_enumerateFiles(WALLPAPER_FOLDER);
for (char **i = imgs; *i != NULL; i++)
{
- if (strncmp(*i, WALLPAPER_BASE, baseLen) == 0)
+ int width;
+ int height;
+
+ // If the backup file is found, we tell it.
+ if (strncmp (*i, WALLPAPER_BASE, strlen(*i)) == 0)
+ haveBackup = true;
+
+ // If the image format is terminated by: "_<width>x<height>.png"
+ // It is taken as a potential wallpaper.
+
+ // First, get the base filename of the image:
+ std::string filename = *i;
+ int separator = filename.rfind("_");
+ filename = filename.substr(0, separator);
+
+ // Then, append the width and height search mask.
+ filename.append("_%dx%d.png");
+
+ if (sscanf(*i, filename.c_str(), &width, &height) == 2)
{
- int width;
- int height;
-
- if (strlen(*i) == baseLen + 4)
- {
- if (haveBackup)
- logger->log("Duplicate default wallpaper!");
- else
- haveBackup = true;
- }
- else if (sscanf(*i, WALLPAPER_BASE "_%dx%d.png",
- &width, &height) == 2)
- {
- WallpaperSize wp;
- wp.width = width;
- wp.height = height;
- wallpaperSizes.push_back(wp);
- }
+ WallpaperData wp;
+ wp.filename = WALLPAPER_FOLDER;
+ wp.filename.append(*i);
+ wp.width = width;
+ wp.height = height;
+ wallpaperData.push_back(wp);
}
}
PHYSFS_freeList(imgs);
- std::sort(wallpaperSizes.begin(), wallpaperSizes.end(), wallpaperCompare);
+ std::sort(wallpaperData.begin(), wallpaperData.end(), wallpaperCompare);
}
std::string Wallpaper::getWallpaper(int width, int height)
{
- std::vector<WallpaperSize>::iterator iter;
- WallpaperSize wp;
+ std::vector<WallpaperData>::iterator iter;
+ WallpaperData wp;
- for (iter = wallpaperSizes.begin(); iter != wallpaperSizes.end(); iter++)
+ // Wallpaper filename container
+ std::vector<std::string> wallPaperVector;
+
+ for (iter = wallpaperData.begin(); iter != wallpaperData.end(); iter++)
{
wp = *iter;
if (wp.width <= width && wp.height <= height)
+ wallPaperVector.push_back(wp.filename);
+ }
+
+
+ if (!wallPaperVector.empty())
+ {
+ // If we've got more than one occurence of a valid wallpaper...
+ if (wallPaperVector.size() > 0)
{
- return std::string(strprintf(WALLPAPER_FOLDER WALLPAPER_BASE
- "_%dx%d.png", wp.width, wp.height));
+ // Return randomly a wallpaper between vector[0] and
+ // vector[vector.size() - 1]
+ srand((unsigned)time(0));
+ return wallPaperVector
+ [int(wallPaperVector.size() * rand() / (RAND_MAX + 1.0))];
}
+ else // If there at least one, we return it
+ return wallPaperVector[0];
}
+ // Return the backup file if everything else failed...
if (haveBackup)
- return std::string(WALLPAPER_FOLDER WALLPAPER_BASE ".png");
+ return std::string(WALLPAPER_FOLDER WALLPAPER_BASE);
+ // Return an empty string if everything else failed
return std::string();
+
}