summaryrefslogtreecommitdiff
path: root/src/resources
diff options
context:
space:
mode:
Diffstat (limited to 'src/resources')
-rw-r--r--src/resources/dye.cpp14
-rw-r--r--src/resources/dye.h6
-rw-r--r--src/resources/image.cpp79
-rw-r--r--src/resources/image.h10
-rw-r--r--src/resources/itemdb.cpp7
5 files changed, 102 insertions, 14 deletions
diff --git a/src/resources/dye.cpp b/src/resources/dye.cpp
index 22bd2411..1e4fd2fd 100644
--- a/src/resources/dye.cpp
+++ b/src/resources/dye.cpp
@@ -25,7 +25,7 @@
#include "../log.h"
-Palette::Palette(const std::string &description)
+DyePalette::DyePalette(const std::string &description)
{
int size = description.length();
if (size == 0) return;
@@ -62,7 +62,7 @@ Palette::Palette(const std::string &description)
logger->log("Error, invalid embedded palette: %s", description.c_str());
}
-void Palette::getColor(int intensity, int color[3]) const
+void DyePalette::getColor(int intensity, int color[3]) const
{
if (intensity == 0)
{
@@ -111,7 +111,7 @@ void Palette::getColor(int intensity, int color[3]) const
Dye::Dye(const std::string &description)
{
for (int i = 0; i < 7; ++i)
- mPalettes[i] = 0;
+ mDyePalettes[i] = 0;
if (description.empty()) return;
@@ -141,7 +141,7 @@ Dye::Dye(const std::string &description)
logger->log("Error, invalid dye: %s", description.c_str());
return;
}
- mPalettes[i] = new Palette(description.substr(pos + 2, next_pos - pos - 2));
+ mDyePalettes[i] = new DyePalette(description.substr(pos + 2, next_pos - pos - 2));
++next_pos;
}
while (next_pos < length);
@@ -150,7 +150,7 @@ Dye::Dye(const std::string &description)
Dye::~Dye()
{
for (int i = 0; i < 7; ++i)
- delete mPalettes[i];
+ delete mDyePalettes[i];
}
void Dye::update(int color[3]) const
@@ -170,8 +170,8 @@ void Dye::update(int color[3]) const
int i = (color[0] != 0) | ((color[1] != 0) << 1) | ((color[2] != 0) << 2);
- if (mPalettes[i - 1])
- mPalettes[i - 1]->getColor(cmax, color);
+ if (mDyePalettes[i - 1])
+ mDyePalettes[i - 1]->getColor(cmax, color);
}
void Dye::instantiate(std::string &target, const std::string &palettes)
diff --git a/src/resources/dye.h b/src/resources/dye.h
index 3cef334a..d0d010bc 100644
--- a/src/resources/dye.h
+++ b/src/resources/dye.h
@@ -28,7 +28,7 @@
/**
* Class for performing a linear interpolation between colors.
*/
-class Palette
+class DyePalette
{
public:
@@ -37,7 +37,7 @@ class Palette
* The string is either a file name or a sequence of hexadecimal RGB
* values separated by ',' and starting with '#'.
*/
- Palette(const std::string &pallete);
+ DyePalette(const std::string &pallete);
/**
* Gets a pixel color depending on its intensity.
@@ -89,7 +89,7 @@ class Dye
*
* Red, Green, Yellow, Blue, Magenta, White (or rather gray).
*/
- Palette *mPalettes[7];
+ DyePalette *mDyePalettes[7];
};
#endif
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index 7a7e6ac8..b696389f 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -25,6 +25,7 @@
#include "image.h"
#include "../log.h"
+#include "../position.h"
#ifdef USE_OPENGL
bool Image::mUseOpenGL = false;
@@ -46,8 +47,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),
@@ -315,6 +315,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 fe3081ac..eeaa574e 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -40,6 +40,7 @@
#include "resource.h"
class Dye;
+class Position;
class SDL_Rect;
class SDL_Surface;
@@ -131,6 +132,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.
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index 1ff34d98..dbd12eee 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -144,9 +144,12 @@ void ItemDB::load()
if (param == error_value) \
logger->log("ItemDB: Missing " #param " attribute for item %i!",id)
- CHECK_PARAM(name, "");
+ if (id >= 0)
+ {
+ CHECK_PARAM(name, "");
+ CHECK_PARAM(description, "");
+ }
CHECK_PARAM(image, "");
- CHECK_PARAM(description, "");
// CHECK_PARAM(effect, "");
// CHECK_PARAM(type, 0);
// CHECK_PARAM(weight, 0);