From 07e401fb2335d2372a93f37317f144449f7e872b Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Mon, 16 Jul 2012 18:18:22 +0300 Subject: Add new dye type A. Same as type S for colors + alpha channel. Example: equipment/feet/boots.png|A:#3c3c3cff,40332d40,4d4d4dff,5e4a3d40 here colors in format RRGGBBAA. --- src/gui/theme.cpp | 2 +- src/resources/dye.cpp | 89 ++++++++++++++++++++++++++++--------- src/resources/dye.h | 51 ++++++++++++++------- src/resources/openglimagehelper.cpp | 72 ++++++++++++++++++++---------- src/resources/sdlimagehelper.cpp | 71 +++++++++++++++++++---------- 5 files changed, 197 insertions(+), 88 deletions(-) diff --git a/src/gui/theme.cpp b/src/gui/theme.cpp index e01799ea7..108d736cd 100644 --- a/src/gui/theme.cpp +++ b/src/gui/theme.cpp @@ -851,7 +851,7 @@ void Theme::loadColors(std::string file) continue; mProgressColors[type] = new DyePalette(XML::getProperty(node, - "color", "")); + "color", ""), 6); } } } diff --git a/src/resources/dye.cpp b/src/resources/dye.cpp index 954817103..316dff9f3 100644 --- a/src/resources/dye.cpp +++ b/src/resources/dye.cpp @@ -29,7 +29,7 @@ #include "debug.h" -DyePalette::DyePalette(const std::string &description) +DyePalette::DyePalette(const std::string &description, int8_t blockSize) { const int size = static_cast(description.length()); if (size == 0) @@ -43,21 +43,22 @@ DyePalette::DyePalette(const std::string &description) int pos = 1; for ( ; ; ) { - if (pos + 6 > size) + if (pos + blockSize > size) break; Color color = { - {0, 0, 0} + {0, 0, 0, 0} }; - for (int i = 0, colorIdx = 0; i < 6; i +=2, colorIdx ++) + for (int i = 0, colorIdx = 0; i < blockSize && colorIdx < dyePalateSize; + i +=2, colorIdx ++) { color.value[colorIdx] = (hexDecode(description[pos + i]) << 4) + hexDecode(description[pos + i + 1]); } mColors.push_back(color); - pos += 6; + pos += blockSize; if (pos == size) return; @@ -82,20 +83,6 @@ int DyePalette::hexDecode(char c) return 0; } -/* -void DyePalette::addFirstColor(const int color[3]) -{ - Color c = { {color[0], color[1], color[2]} }; - mColors.insert(mColors.begin(), c); -} - -void DyePalette::addLastColor(const int color[3]) -{ - Color c = { {color[0], color[1], color[2]} }; - mColors.push_back(c); -} -*/ - void DyePalette::getColor(int intensity, int color[3]) const { if (intensity == 0) @@ -192,7 +179,7 @@ void DyePalette::getColor(double intensity, int color[3]) const color[2] = static_cast(rest * b1 + intensity * b2); } -void DyePalette::replaceColor(uint8_t *color) const +void DyePalette::replaceSColor(uint8_t *color) const { std::vector::const_iterator it = mColors.begin(); std::vector::const_iterator it_end = mColors.end(); @@ -215,7 +202,31 @@ void DyePalette::replaceColor(uint8_t *color) const } } -void DyePalette::replaceOGLColor(uint8_t *color) const +void DyePalette::replaceAColor(uint8_t *color) const +{ + std::vector::const_iterator it = mColors.begin(); + std::vector::const_iterator it_end = mColors.end(); + while (it != it_end) + { + const Color &col = *it; + ++ it; + if (it == it_end) + return; + const Color &col2 = *it; + if (color[1] == col.value[0] && color[2] == col.value[1] + && color[3] == col.value[2] && color[0] == col.value[3]) + { + color[3] = col2.value[0]; + color[2] = col2.value[1]; + color[1] = col2.value[2]; + color[0] = col2.value[3]; + return; + } + ++ it; + } +} + +void DyePalette::replaceSOGLColor(uint8_t *color) const { std::vector::const_iterator it = mColors.begin(); std::vector::const_iterator it_end = mColors.end(); @@ -238,6 +249,30 @@ void DyePalette::replaceOGLColor(uint8_t *color) const } } +void DyePalette::replaceAOGLColor(uint8_t *color) const +{ + std::vector::const_iterator it = mColors.begin(); + std::vector::const_iterator it_end = mColors.end(); + while (it != it_end) + { + const Color &col = *it; + ++ it; + if (it == it_end) + return; + const Color &col2 = *it; + if (color[2] == col.value[0] && color[1] == col.value[1] + && color[0] == col.value[2] && color[3] == col.value[3]) + { + color[0] = col2.value[0]; + color[1] = col2.value[1]; + color[2] = col2.value[2]; + color[3] = col2.value[3]; + return; + } + ++ it; + } +} + Dye::Dye(const std::string &description) { for (int i = 0; i < dyePalateSize; ++i) @@ -273,12 +308,13 @@ Dye::Dye(const std::string &description) case 'C': i = 5; break; case 'W': i = 6; break; case 'S': i = 7; break; + case 'A': i = 8; break; default: logger->log("Error, invalid dye: %s", description.c_str()); return; } mDyePalettes[i] = new DyePalette(description.substr( - pos + 2, next_pos - pos - 2)); + pos + 2, next_pos - pos - 2), i != 8 ? 6 : 8); ++next_pos; } while (next_pos < length); @@ -365,3 +401,12 @@ void Dye::instantiate(std::string &target, const std::string &palettes) target = s.str(); } + +int Dye::getType() const +{ + if (mDyePalettes[sPaleteIndex]) + return 1; + if (mDyePalettes[aPaleteIndex]) + return 2; + return 0; +} diff --git a/src/resources/dye.h b/src/resources/dye.h index 7fe4869ef..7e5ba6c99 100644 --- a/src/resources/dye.h +++ b/src/resources/dye.h @@ -28,7 +28,9 @@ #include -const int dyePalateSize = 8; +const int dyePalateSize = 9; +const int sPaleteIndex = 7; +const int aPaleteIndex = 8; /** * Class for performing a linear interpolation between colors. @@ -42,13 +44,7 @@ class DyePalette * The string is either a file name or a sequence of hexadecimal RGB * values separated by ',' and starting with '#'. */ - DyePalette(const std::string &pallete); - -/* - void addFirstColor(const int color[3]); - - void addLastColor(const int color[3]); -*/ + DyePalette(const std::string &pallete, int8_t blockSize); /** * Gets a pixel color depending on its intensity. First color is @@ -61,15 +57,31 @@ class DyePalette */ void getColor(double intensity, int color[3]) const; - void replaceColor(uint8_t *color) const; + /** + * replace colors for SDL for S dye. + */ + void replaceSColor(uint8_t *color) const; + + /** + * replace colors for SDL for S dye. + */ + void replaceAColor(uint8_t *color) const; + + /** + * replace colors for OpenGL for S dye. + */ + void replaceSOGLColor(uint8_t *color) const; - void replaceOGLColor(uint8_t *color) const; + /** + * replace colors for OpenGL for A dye. + */ + void replaceAOGLColor(uint8_t *color) const; int hexDecode(char c); private: struct Color - { unsigned char value[3]; }; + { unsigned char value[4]; }; std::vector mColors; }; @@ -106,16 +118,21 @@ class Dye const std::string &palettes); /** - * Check if dye is special dye (S) + * Return special dye palete (S) + */ + DyePalette *getSPalete() const + { return mDyePalettes[sPaleteIndex]; } + + /** + * Return special dye palete (A) */ - bool isSpecialDye() const - { return mDyePalettes[dyePalateSize - 1]; } + DyePalette *getAPalete() const + { return mDyePalettes[aPaleteIndex]; } /** - * Return special dye palete (S) + * Return dye type for S - 1, for A - 2, 0 for other */ - DyePalette *getSPalete() const - { return mDyePalettes[dyePalateSize - 1]; } + int getType() const; private: diff --git a/src/resources/openglimagehelper.cpp b/src/resources/openglimagehelper.cpp index 63c103e1f..aec68f32a 100644 --- a/src/resources/openglimagehelper.cpp +++ b/src/resources/openglimagehelper.cpp @@ -62,35 +62,59 @@ Resource *OpenGLImageHelper::load(SDL_RWops *rw, Dye const &dye) SDL_FreeSurface(tmpImage); uint32_t *pixels = static_cast(surf->pixels); - DyePalette *pal = dye.getSPalete(); + int type = dye.getType(); - if (pal) + switch (type) { - for (uint32_t *p_end = pixels + surf->w * surf->h; - pixels != p_end; ++pixels) + case 1: { - uint8_t *p = reinterpret_cast(pixels); - const int alpha = *p & 255; - if (!alpha) - continue; - pal->replaceOGLColor(p); + DyePalette *pal = dye.getSPalete(); + + if (pal) + { + for (uint32_t *p_end = pixels + surf->w * surf->h; + pixels != p_end; ++pixels) + { + uint8_t *p = reinterpret_cast(pixels); + const int alpha = *p & 255; + if (!alpha) + continue; + pal->replaceSOGLColor(p); + } + } + break; } - } - else - { - for (uint32_t *p_end = pixels + surf->w * surf->h; - pixels != p_end; ++pixels) + case 2: + { + DyePalette *pal = dye.getAPalete(); + if (pal) + { + for (uint32_t *p_end = pixels + surf->w * surf->h; + pixels != p_end; ++pixels) + { + pal->replaceAOGLColor(reinterpret_cast(pixels)); + } + } + break; + } + case 0: + default: { - const uint32_t p = *pixels; - const int alpha = (p >> 24) & 255; - if (!alpha) - continue; - int v[3]; - v[0] = (p) & 255; - v[1] = (p >> 8) & 255; - v[2] = (p >> 16 ) & 255; - dye.update(v); - *pixels = (v[0]) | (v[1] << 8) | (v[2] << 16) | (alpha << 24); + for (uint32_t *p_end = pixels + surf->w * surf->h; + pixels != p_end; ++pixels) + { + const uint32_t p = *pixels; + const int alpha = (p >> 24) & 255; + if (!alpha) + continue; + int v[3]; + v[0] = (p) & 255; + v[1] = (p >> 8) & 255; + v[2] = (p >> 16 ) & 255; + dye.update(v); + *pixels = (v[0]) | (v[1] << 8) | (v[2] << 16) | (alpha << 24); + } + break; } } diff --git a/src/resources/sdlimagehelper.cpp b/src/resources/sdlimagehelper.cpp index 6c281514e..78094b211 100644 --- a/src/resources/sdlimagehelper.cpp +++ b/src/resources/sdlimagehelper.cpp @@ -66,35 +66,58 @@ Resource *SDLImageHelper::load(SDL_RWops *rw, Dye const &dye) SDL_FreeSurface(tmpImage); uint32_t *pixels = static_cast(surf->pixels); - DyePalette *pal = dye.getSPalete(); + int type = dye.getType(); - if (pal) + switch (type) { - for (uint32_t *p_end = pixels + surf->w * surf->h; - pixels != p_end; ++pixels) + case 1: { - uint8_t *p = reinterpret_cast(pixels); - const int alpha = *p & 255; - if (!alpha) - continue; - pal->replaceColor(p + 1); + DyePalette *pal = dye.getSPalete(); + if (pal) + { + for (uint32_t *p_end = pixels + surf->w * surf->h; + pixels != p_end; ++pixels) + { + uint8_t *p = reinterpret_cast(pixels); + const int alpha = *p & 255; + if (!alpha) + continue; + pal->replaceSColor(p + 1); + } + } + break; } - } - else - { - for (uint32_t *p_end = pixels + surf->w * surf->h; - pixels != p_end; ++pixels) + case 2: { - const uint32_t p = *pixels; - const int alpha = p & 255; - if (!alpha) - continue; - int v[3]; - v[0] = (p >> 24) & 255; - v[1] = (p >> 16) & 255; - v[2] = (p >> 8 ) & 255; - dye.update(v); - *pixels = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | alpha; + DyePalette *pal = dye.getAPalete(); + if (pal) + { + for (uint32_t *p_end = pixels + surf->w * surf->h; + pixels != p_end; ++pixels) + { + pal->replaceAColor(reinterpret_cast(pixels)); + } + } + break; + } + case 0: + default: + { + for (uint32_t *p_end = pixels + surf->w * surf->h; + pixels != p_end; ++pixels) + { + const uint32_t p = *pixels; + const int alpha = p & 255; + if (!alpha) + continue; + int v[3]; + v[0] = (p >> 24) & 255; + v[1] = (p >> 16) & 255; + v[2] = (p >> 8 ) & 255; + dye.update(v); + *pixels = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | alpha; + } + break; } } -- cgit v1.2.3-60-g2f50