diff options
Diffstat (limited to 'src/resources')
-rw-r--r-- | src/resources/dye.cpp | 14 | ||||
-rw-r--r-- | src/resources/dye.h | 6 | ||||
-rw-r--r-- | src/resources/image.cpp | 79 | ||||
-rw-r--r-- | src/resources/image.h | 10 | ||||
-rw-r--r-- | src/resources/itemdb.cpp | 7 |
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); |