From 8e5f09c54a7c48e24f2c5be073c75b4f93b5fd15 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Mon, 21 Dec 2015 00:58:50 +0300 Subject: Move dye related files into dye directory. --- src/CMakeLists.txt | 18 +- src/Makefile.am | 12 +- src/gui/theme.cpp | 3 +- src/particle/particle.cpp | 3 +- src/particle/particleemitter.cpp | 3 +- src/resources/atlas/atlasmanager.cpp | 3 +- src/resources/db/palettedb.cpp | 2 +- src/resources/dye.cpp | 385 -------------------- src/resources/dye.h | 93 ----- src/resources/dye/dye.cpp | 385 ++++++++++++++++++++ src/resources/dye/dye.h | 93 +++++ src/resources/dye/dye_unittest.cc | 254 +++++++++++++ src/resources/dye/dyecolor.h | 53 +++ src/resources/dye/dyepalette.cpp | 586 ++++++++++++++++++++++++++++++ src/resources/dye/dyepalette.h | 88 +++++ src/resources/dye_unittest.cc | 255 ------------- src/resources/dyecolor.h | 53 --- src/resources/dyepalette.cpp | 586 ------------------------------ src/resources/dyepalette.h | 88 ----- src/resources/imagehelper.cpp | 4 +- src/resources/openglimagehelper.cpp | 5 +- src/resources/resourcemanager.cpp | 3 +- src/resources/safeopenglimagehelper.cpp | 5 +- src/resources/sdl2imagehelper.cpp | 5 +- src/resources/sdl2softwareimagehelper.cpp | 3 +- src/resources/sdlimagehelper.cpp | 5 +- src/resources/sprite/spritedef.cpp | 3 +- src/resources/surfaceimagehelper.cpp | 3 +- src/simpleanimation.cpp | 3 +- src/test/testlauncher.cpp | 5 +- 30 files changed, 1510 insertions(+), 1497 deletions(-) delete mode 100644 src/resources/dye.cpp delete mode 100644 src/resources/dye.h create mode 100644 src/resources/dye/dye.cpp create mode 100644 src/resources/dye/dye.h create mode 100644 src/resources/dye/dye_unittest.cc create mode 100644 src/resources/dye/dyecolor.h create mode 100644 src/resources/dye/dyepalette.cpp create mode 100644 src/resources/dye/dyepalette.h delete mode 100644 src/resources/dye_unittest.cc delete mode 100644 src/resources/dyecolor.h delete mode 100644 src/resources/dyepalette.cpp delete mode 100644 src/resources/dyepalette.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4a980ec19..c07b1d2c3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -622,11 +622,11 @@ SET(SRCS resources/delayedmanager.h resources/db/deaddb.cpp resources/db/deaddb.h - resources/dye.cpp - resources/dye.h - resources/dyecolor.h - resources/dyepalette.cpp - resources/dyepalette.h + resources/dye/dye.cpp + resources/dye/dye.h + resources/dye/dyecolor.h + resources/dye/dyepalette.cpp + resources/dye/dyepalette.h resources/effectdescription.h resources/emoteinfo.h resources/emotesprite.h @@ -1336,10 +1336,10 @@ SET(DYE_CMD_SRCS resources/db/palettedb.h resources/delayedmanager.cpp resources/delayedmanager.h - resources/dye.cpp - resources/dye.h - resources/dyepalette.cpp - resources/dyepalette.h + resources/dye/dye.cpp + resources/dye/dye.h + resources/dye/dyepalette.cpp + resources/dye/dyepalette.h resources/effectdescription.h resources/emoteinfo.h resources/emotesprite.h diff --git a/src/Makefile.am b/src/Makefile.am index d11d4b5cb..10f5afb7a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -320,11 +320,11 @@ SRC += events/actionevent.h \ resources/attack.h \ resources/cursor.cpp \ resources/cursor.h \ - resources/dye.cpp \ - resources/dye.h \ - resources/dyecolor.h \ - resources/dyepalette.cpp \ - resources/dyepalette.h \ + resources/dye/dye.cpp \ + resources/dye/dye.h \ + resources/dye/dyecolor.h \ + resources/dye/dyepalette.cpp \ + resources/dye/dyepalette.h \ resources/fboinfo.h \ resources/frame.h \ resources/image.cpp \ @@ -1689,7 +1689,7 @@ manaplustests_SOURCES = ${manaplus_SOURCES} \ utils/mathutils_unittest.cc \ utils/stringutils_unittest.cc \ utils/xmlutils_unittest.cc \ - resources/dye_unittest.cc \ + resources/dye/dye_unittest.cc \ resources/mstack_unittest.cc endif diff --git a/src/gui/theme.cpp b/src/gui/theme.cpp index c98e463dc..9da58cd13 100644 --- a/src/gui/theme.cpp +++ b/src/gui/theme.cpp @@ -32,11 +32,12 @@ #include "gui/skin.h" #include "gui/themeinfo.h" -#include "resources/dyepalette.h" #include "resources/image.h" #include "resources/imagerect.h" #include "resources/resourcemanager.h" +#include "resources/dye/dyepalette.h" + #include "utils/dtor.h" #include "utils/files.h" #include "utils/physfstools.h" diff --git a/src/particle/particle.cpp b/src/particle/particle.cpp index dc566bb4e..8fd4ecead 100644 --- a/src/particle/particle.cpp +++ b/src/particle/particle.cpp @@ -23,7 +23,6 @@ #include "particle/particle.h" #include "configuration.h" -#include "resources/dye.h" #include "logger.h" #include "particle/animationparticle.h" @@ -33,6 +32,8 @@ #include "resources/resourcemanager.h" +#include "resources/dye/dye.h" + #include "utils/dtor.h" #include "utils/mathutils.h" diff --git a/src/particle/particleemitter.cpp b/src/particle/particleemitter.cpp index 739bd915b..b0c5f7e9c 100644 --- a/src/particle/particleemitter.cpp +++ b/src/particle/particleemitter.cpp @@ -29,11 +29,12 @@ #include "particle/animationparticle.h" #include "particle/rotationalparticle.h" -#include "resources/dye.h" #include "resources/image.h" #include "resources/imageset.h" #include "resources/resourcemanager.h" +#include "resources/dye/dye.h" + #include "debug.h" static const float SIN45 = 0.707106781F; diff --git a/src/resources/atlas/atlasmanager.cpp b/src/resources/atlas/atlasmanager.cpp index a81a6c10d..345720442 100644 --- a/src/resources/atlas/atlasmanager.cpp +++ b/src/resources/atlas/atlasmanager.cpp @@ -33,7 +33,6 @@ #include "utils/physfsrwops.h" #include "utils/sdlcheckutils.h" -#include "resources/dye.h" #include "resources/imagehelper.h" #include "resources/openglimagehelper.h" #include "resources/resourcemanager.h" @@ -43,6 +42,8 @@ #include "resources/atlas/atlasresource.h" #include "resources/atlas/textureatlas.h" +#include "resources/dye/dye.h" + #include "debug.h" AtlasManager::AtlasManager() diff --git a/src/resources/db/palettedb.cpp b/src/resources/db/palettedb.cpp index fe2fc3bae..12a807fc2 100644 --- a/src/resources/db/palettedb.cpp +++ b/src/resources/db/palettedb.cpp @@ -24,7 +24,7 @@ #include "utils/files.h" -#include "resources/dyecolor.h" +#include "resources/dye/dyecolor.h" #include diff --git a/src/resources/dye.cpp b/src/resources/dye.cpp deleted file mode 100644 index c7287ee8a..000000000 --- a/src/resources/dye.cpp +++ /dev/null @@ -1,385 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2007-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2015 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "resources/dye.h" - -#include "logger.h" - -#include "resources/dyepalette.h" - -#include "utils/delete2.h" - -#include - -#include - -#include "debug.h" - -Dye::Dye(const std::string &description) -{ - for (int i = 0; i < dyePalateSize; ++i) - mDyePalettes[i] = nullptr; - - if (description.empty()) - return; - - size_t next_pos = 0; - const size_t length = description.length(); - do - { - const size_t pos = next_pos; - next_pos = description.find(';', pos); - - if (next_pos == std::string::npos) - next_pos = length; - - if (next_pos <= pos + 3 || description[pos + 1] != ':') - { - logger->log("Error, invalid dye: %s", description.c_str()); - return; - } - - int i = 0; - - switch (description[pos]) - { - case 'R': i = 0; break; - case 'G': i = 1; break; - case 'Y': i = 2; break; - case 'B': i = 3; break; - case 'M': i = 4; break; - 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), i != 8 ? 6 : 8); - ++next_pos; - } - while (next_pos < length); -} - -Dye::~Dye() -{ - for (int i = 0; i < dyePalateSize; ++i) - delete2(mDyePalettes[i]) -} - -void Dye::instantiate(std::string &restrict target, - const std::string &restrict palettes) -{ - size_t next_pos = target.find('|'); - - if (next_pos == std::string::npos || palettes.empty()) - return; - - ++next_pos; - - std::ostringstream s; - s << target.substr(0, next_pos); - size_t last_pos = target.length(), pal_pos = 0; - do - { - const size_t pos = next_pos; - next_pos = target.find(';', pos); - - if (next_pos == std::string::npos) - next_pos = last_pos; - - if (next_pos == pos + 1 && pal_pos != std::string::npos) - { - const size_t pal_next_pos = palettes.find(';', pal_pos); - s << target[pos] << ':'; - if (pal_next_pos == std::string::npos) - { - s << palettes.substr(pal_pos); - s << target.substr(next_pos); - break; - } - s << palettes.substr(pal_pos, pal_next_pos - pal_pos); - pal_pos = pal_next_pos + 1; - } - else if (next_pos > pos + 2) - { - s << target.substr(pos, next_pos - pos); - } - else - { - logger->log("Error, invalid dye placeholder: %s", target.c_str()); - return; - } - s << target[next_pos]; - ++next_pos; - } - while (next_pos < last_pos); - - target = s.str(); -} - -int Dye::getType() const -{ - if (mDyePalettes[sPaleteIndex]) - return 1; - if (mDyePalettes[aPaleteIndex]) - return 2; - return 0; -} - -void Dye::normalDye(uint32_t *restrict pixels, const int bufSize) const -{ - if (!pixels) - return; - -#ifdef ENABLE_CILKPLUS - cilk_for (int ptr = 0; ptr < bufSize; ptr ++) - { - const uint32_t p = pixels[ptr]; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const int alpha = p & 0xff000000; -#else - const int alpha = p & 0xff; -#endif - if (alpha) - { - unsigned int color[3]; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - color[0] = (p) & 255U; - color[1] = (p >> 8U) & 255U; - color[2] = (p >> 16U) & 255U; -#else - color[0] = (p >> 24U) & 255U; - color[1] = (p >> 16U) & 255U; - color[2] = (p >> 8U) & 255U; -#endif - const unsigned int cmax = std::max( - color[0], std::max(color[1], color[2])); - if (cmax == 0) - goto endlabel; - - const unsigned int cmin = std::min( - color[0], std::min(color[1], color[2])); - const unsigned int intensity = color[0] + color[1] + color[2]; - unsigned int i; - - if (cmin != cmax && (cmin != 0 || (intensity != cmax - && intensity != 2 * cmax))) - { - // not pure - goto endlabel; - } - - i = (color[0] != 0) | ((color[1] != 0) << 1) - | ((color[2] != 0) << 2); - - if (mDyePalettes[i - 1]) - mDyePalettes[i - 1]->getColor(cmax, color); - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - pixels[ptr] = (color[0]) | (color[1] << 8) - | (color[2] << 16) | alpha; -#else - pixels[ptr] = (color[0] << 24) | (color[1] << 16) - | (color[2] << 8) | alpha; -#endif - } -endlabel:{} - } - -#else // ENABLE_CILKPLUS - - for (uint32_t *p_end = pixels + static_cast(bufSize); - pixels != p_end; - ++ pixels) - { - const uint32_t p = *pixels; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const int alpha = p & 0xff000000; -#else - const int alpha = p & 0xff; -#endif - if (!alpha) - continue; - unsigned int color[3]; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - color[0] = (p) & 255U; - color[1] = (p >> 8U) & 255U; - color[2] = (p >> 16U) & 255U; -#else - color[0] = (p >> 24U) & 255U; - color[1] = (p >> 16U) & 255U; - color[2] = (p >> 8U) & 255U; -#endif - - const unsigned int cmax = std::max( - color[0], std::max(color[1], color[2])); - if (cmax == 0) - continue; - - const unsigned int cmin = std::min( - color[0], std::min(color[1], color[2])); - const unsigned int intensity = color[0] + color[1] + color[2]; - - if (cmin != cmax && (cmin != 0 || (intensity != cmax - && intensity != 2 * cmax))) - { - // not pure - continue; - } - - const unsigned int i = (color[0] != 0) | ((color[1] != 0) << 1) - | ((color[2] != 0) << 2); - - if (mDyePalettes[i - 1]) - mDyePalettes[i - 1]->getColor(cmax, color); - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - *pixels = (color[0]) | (color[1] << 8) - | (color[2] << 16) | alpha; -#else - *pixels = (color[0] << 24) | (color[1] << 16) - | (color[2] << 8) | alpha; -#endif - } -#endif // ENABLE_CILKPLUS -} - -void Dye::normalOGLDye(uint32_t *restrict pixels, const int bufSize) const -{ - if (!pixels) - return; - -#ifdef ENABLE_CILKPLUS - cilk_for (int ptr = 0; ptr < bufSize; ptr ++) - { - const uint32_t p = pixels[ptr]; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const int alpha = p & 255; -#else - const int alpha = p & 0xff000000; -#endif - if (alpha) - { - unsigned int color[3]; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - color[0] = (p >> 24U) & 255U; - color[1] = (p >> 16U) & 255U; - color[2] = (p >> 8U) & 255U; -#else - color[0] = (p) & 255U; - color[1] = (p >> 8U) & 255U; - color[2] = (p >> 16U) & 255U; -#endif - - const unsigned int cmax = std::max( - color[0], std::max(color[1], color[2])); - if (cmax == 0) - goto endlabel; - - const unsigned int cmin = std::min( - color[0], std::min(color[1], color[2])); - const unsigned int intensity = color[0] + color[1] + color[2]; - - if (cmin != cmax && (cmin != 0 || (intensity != cmax - && intensity != 2 * cmax))) - { - // not pure - goto endlabel; - } - - const unsigned int i = (color[0] != 0) | ((color[1] != 0) << 1) - | ((color[2] != 0) << 2); - - if (mDyePalettes[i - 1]) - mDyePalettes[i - 1]->getColor(cmax, color); - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - pixels[ptr] = (color[0] << 24) | (color[1] << 16) - | (color[2] << 8) | alpha; -#else - pixels[ptr] = (color[0]) | (color[1] << 8) - | (color[2] << 16) | alpha; -#endif - } -endlabel:{} - } - -#else // ENABLE_CILKPLUS - - for (uint32_t *p_end = pixels + static_cast(bufSize); - pixels != p_end; - ++ pixels) - { - const uint32_t p = *pixels; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const int alpha = p & 255; -#else - const int alpha = p & 0xff000000; -#endif - if (!alpha) - continue; - unsigned int color[3]; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - color[0] = (p >> 24U) & 255U; - color[1] = (p >> 16U) & 255U; - color[2] = (p >> 8U) & 255U; -#else - color[0] = (p) & 255U; - color[1] = (p >> 8U) & 255U; - color[2] = (p >> 16U) & 255U; -#endif - - const unsigned int cmax = std::max( - color[0], std::max(color[1], color[2])); - if (cmax == 0) - continue; - - const unsigned int cmin = std::min( - color[0], std::min(color[1], color[2])); - const unsigned int intensity = color[0] + color[1] + color[2]; - - if (cmin != cmax && (cmin != 0 || (intensity != cmax - && intensity != 2 * cmax))) - { - // not pure - continue; - } - - const unsigned int i = (color[0] != 0) | ((color[1] != 0) << 1) - | ((color[2] != 0) << 2); - - if (mDyePalettes[i - 1]) - mDyePalettes[i - 1]->getColor(cmax, color); - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - *pixels = (color[0] << 24) | (color[1] << 16) - | (color[2] << 8) | alpha; -#else - *pixels = (color[0]) | (color[1] << 8) - | (color[2] << 16) | alpha; -#endif - } -#endif // ENABLE_CILKPLUS -} diff --git a/src/resources/dye.h b/src/resources/dye.h deleted file mode 100644 index 353092ddf..000000000 --- a/src/resources/dye.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2007-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2015 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef RESOURCES_DYE_H -#define RESOURCES_DYE_H - -#include - -#include "localconsts.h" - -class DyePalette; - -const int dyePalateSize = 9; -const int sPaleteIndex = 7; -const int aPaleteIndex = 8; - -/** - * Class for dispatching pixel-recoloring amongst several palettes. - */ -class Dye final -{ - public: - /** - * Creates a set of palettes based on the given string. - * - * The parts of string are separated by semi-colons. Each part starts - * by an uppercase letter, followed by a colon and then a palette name. - */ - explicit Dye(const std::string &dye); - - A_DELETE_COPY(Dye) - - /** - * Destroys the associated palettes. - */ - ~Dye(); - - /** - * Fills the blank in a dye placeholder with some palette names. - */ - static void instantiate(std::string &restrict target, - const std::string &restrict palettes); - - /** - * Return special dye palete (S) - */ - const DyePalette *getSPalete() const A_WARN_UNUSED - { return mDyePalettes[sPaleteIndex]; } - - /** - * Return special dye palete (A) - */ - const DyePalette *getAPalete() const A_WARN_UNUSED - { return mDyePalettes[aPaleteIndex]; } - - /** - * Return dye type for S - 1, for A - 2, 0 for other - */ - int getType() const A_WARN_UNUSED; - - void normalDye(uint32_t *restrict pixels, const int bufSize) const; - - void normalOGLDye(uint32_t *restrict pixels, const int bufSize) const; - - private: - /** - * The order of the palettes, as well as their uppercase letter, is: - * - * Red, Green, Yellow, Blue, Magenta, White (or rather gray), Simple. - */ - DyePalette *mDyePalettes[dyePalateSize]; -}; - -#endif // RESOURCES_DYE_H diff --git a/src/resources/dye/dye.cpp b/src/resources/dye/dye.cpp new file mode 100644 index 000000000..3b7904122 --- /dev/null +++ b/src/resources/dye/dye.cpp @@ -0,0 +1,385 @@ +/* + * The ManaPlus Client + * Copyright (C) 2007-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2015 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "resources/dye/dye.h" + +#include "logger.h" + +#include "resources/dye/dyepalette.h" + +#include "utils/delete2.h" + +#include + +#include + +#include "debug.h" + +Dye::Dye(const std::string &description) +{ + for (int i = 0; i < dyePalateSize; ++i) + mDyePalettes[i] = nullptr; + + if (description.empty()) + return; + + size_t next_pos = 0; + const size_t length = description.length(); + do + { + const size_t pos = next_pos; + next_pos = description.find(';', pos); + + if (next_pos == std::string::npos) + next_pos = length; + + if (next_pos <= pos + 3 || description[pos + 1] != ':') + { + logger->log("Error, invalid dye: %s", description.c_str()); + return; + } + + int i = 0; + + switch (description[pos]) + { + case 'R': i = 0; break; + case 'G': i = 1; break; + case 'Y': i = 2; break; + case 'B': i = 3; break; + case 'M': i = 4; break; + 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), i != 8 ? 6 : 8); + ++next_pos; + } + while (next_pos < length); +} + +Dye::~Dye() +{ + for (int i = 0; i < dyePalateSize; ++i) + delete2(mDyePalettes[i]) +} + +void Dye::instantiate(std::string &restrict target, + const std::string &restrict palettes) +{ + size_t next_pos = target.find('|'); + + if (next_pos == std::string::npos || palettes.empty()) + return; + + ++next_pos; + + std::ostringstream s; + s << target.substr(0, next_pos); + size_t last_pos = target.length(), pal_pos = 0; + do + { + const size_t pos = next_pos; + next_pos = target.find(';', pos); + + if (next_pos == std::string::npos) + next_pos = last_pos; + + if (next_pos == pos + 1 && pal_pos != std::string::npos) + { + const size_t pal_next_pos = palettes.find(';', pal_pos); + s << target[pos] << ':'; + if (pal_next_pos == std::string::npos) + { + s << palettes.substr(pal_pos); + s << target.substr(next_pos); + break; + } + s << palettes.substr(pal_pos, pal_next_pos - pal_pos); + pal_pos = pal_next_pos + 1; + } + else if (next_pos > pos + 2) + { + s << target.substr(pos, next_pos - pos); + } + else + { + logger->log("Error, invalid dye placeholder: %s", target.c_str()); + return; + } + s << target[next_pos]; + ++next_pos; + } + while (next_pos < last_pos); + + target = s.str(); +} + +int Dye::getType() const +{ + if (mDyePalettes[sPaleteIndex]) + return 1; + if (mDyePalettes[aPaleteIndex]) + return 2; + return 0; +} + +void Dye::normalDye(uint32_t *restrict pixels, const int bufSize) const +{ + if (!pixels) + return; + +#ifdef ENABLE_CILKPLUS + cilk_for (int ptr = 0; ptr < bufSize; ptr ++) + { + const uint32_t p = pixels[ptr]; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const int alpha = p & 0xff000000; +#else + const int alpha = p & 0xff; +#endif + if (alpha) + { + unsigned int color[3]; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + color[0] = (p) & 255U; + color[1] = (p >> 8U) & 255U; + color[2] = (p >> 16U) & 255U; +#else + color[0] = (p >> 24U) & 255U; + color[1] = (p >> 16U) & 255U; + color[2] = (p >> 8U) & 255U; +#endif + const unsigned int cmax = std::max( + color[0], std::max(color[1], color[2])); + if (cmax == 0) + goto endlabel; + + const unsigned int cmin = std::min( + color[0], std::min(color[1], color[2])); + const unsigned int intensity = color[0] + color[1] + color[2]; + unsigned int i; + + if (cmin != cmax && (cmin != 0 || (intensity != cmax + && intensity != 2 * cmax))) + { + // not pure + goto endlabel; + } + + i = (color[0] != 0) | ((color[1] != 0) << 1) + | ((color[2] != 0) << 2); + + if (mDyePalettes[i - 1]) + mDyePalettes[i - 1]->getColor(cmax, color); + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + pixels[ptr] = (color[0]) | (color[1] << 8) + | (color[2] << 16) | alpha; +#else + pixels[ptr] = (color[0] << 24) | (color[1] << 16) + | (color[2] << 8) | alpha; +#endif + } +endlabel:{} + } + +#else // ENABLE_CILKPLUS + + for (uint32_t *p_end = pixels + static_cast(bufSize); + pixels != p_end; + ++ pixels) + { + const uint32_t p = *pixels; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const int alpha = p & 0xff000000; +#else + const int alpha = p & 0xff; +#endif + if (!alpha) + continue; + unsigned int color[3]; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + color[0] = (p) & 255U; + color[1] = (p >> 8U) & 255U; + color[2] = (p >> 16U) & 255U; +#else + color[0] = (p >> 24U) & 255U; + color[1] = (p >> 16U) & 255U; + color[2] = (p >> 8U) & 255U; +#endif + + const unsigned int cmax = std::max( + color[0], std::max(color[1], color[2])); + if (cmax == 0) + continue; + + const unsigned int cmin = std::min( + color[0], std::min(color[1], color[2])); + const unsigned int intensity = color[0] + color[1] + color[2]; + + if (cmin != cmax && (cmin != 0 || (intensity != cmax + && intensity != 2 * cmax))) + { + // not pure + continue; + } + + const unsigned int i = (color[0] != 0) | ((color[1] != 0) << 1) + | ((color[2] != 0) << 2); + + if (mDyePalettes[i - 1]) + mDyePalettes[i - 1]->getColor(cmax, color); + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + *pixels = (color[0]) | (color[1] << 8) + | (color[2] << 16) | alpha; +#else + *pixels = (color[0] << 24) | (color[1] << 16) + | (color[2] << 8) | alpha; +#endif + } +#endif // ENABLE_CILKPLUS +} + +void Dye::normalOGLDye(uint32_t *restrict pixels, const int bufSize) const +{ + if (!pixels) + return; + +#ifdef ENABLE_CILKPLUS + cilk_for (int ptr = 0; ptr < bufSize; ptr ++) + { + const uint32_t p = pixels[ptr]; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const int alpha = p & 255; +#else + const int alpha = p & 0xff000000; +#endif + if (alpha) + { + unsigned int color[3]; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + color[0] = (p >> 24U) & 255U; + color[1] = (p >> 16U) & 255U; + color[2] = (p >> 8U) & 255U; +#else + color[0] = (p) & 255U; + color[1] = (p >> 8U) & 255U; + color[2] = (p >> 16U) & 255U; +#endif + + const unsigned int cmax = std::max( + color[0], std::max(color[1], color[2])); + if (cmax == 0) + goto endlabel; + + const unsigned int cmin = std::min( + color[0], std::min(color[1], color[2])); + const unsigned int intensity = color[0] + color[1] + color[2]; + + if (cmin != cmax && (cmin != 0 || (intensity != cmax + && intensity != 2 * cmax))) + { + // not pure + goto endlabel; + } + + const unsigned int i = (color[0] != 0) | ((color[1] != 0) << 1) + | ((color[2] != 0) << 2); + + if (mDyePalettes[i - 1]) + mDyePalettes[i - 1]->getColor(cmax, color); + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + pixels[ptr] = (color[0] << 24) | (color[1] << 16) + | (color[2] << 8) | alpha; +#else + pixels[ptr] = (color[0]) | (color[1] << 8) + | (color[2] << 16) | alpha; +#endif + } +endlabel:{} + } + +#else // ENABLE_CILKPLUS + + for (uint32_t *p_end = pixels + static_cast(bufSize); + pixels != p_end; + ++ pixels) + { + const uint32_t p = *pixels; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const int alpha = p & 255; +#else + const int alpha = p & 0xff000000; +#endif + if (!alpha) + continue; + unsigned int color[3]; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + color[0] = (p >> 24U) & 255U; + color[1] = (p >> 16U) & 255U; + color[2] = (p >> 8U) & 255U; +#else + color[0] = (p) & 255U; + color[1] = (p >> 8U) & 255U; + color[2] = (p >> 16U) & 255U; +#endif + + const unsigned int cmax = std::max( + color[0], std::max(color[1], color[2])); + if (cmax == 0) + continue; + + const unsigned int cmin = std::min( + color[0], std::min(color[1], color[2])); + const unsigned int intensity = color[0] + color[1] + color[2]; + + if (cmin != cmax && (cmin != 0 || (intensity != cmax + && intensity != 2 * cmax))) + { + // not pure + continue; + } + + const unsigned int i = (color[0] != 0) | ((color[1] != 0) << 1) + | ((color[2] != 0) << 2); + + if (mDyePalettes[i - 1]) + mDyePalettes[i - 1]->getColor(cmax, color); + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + *pixels = (color[0] << 24) | (color[1] << 16) + | (color[2] << 8) | alpha; +#else + *pixels = (color[0]) | (color[1] << 8) + | (color[2] << 16) | alpha; +#endif + } +#endif // ENABLE_CILKPLUS +} diff --git a/src/resources/dye/dye.h b/src/resources/dye/dye.h new file mode 100644 index 000000000..02e1b3f05 --- /dev/null +++ b/src/resources/dye/dye.h @@ -0,0 +1,93 @@ +/* + * The ManaPlus Client + * Copyright (C) 2007-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2015 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef RESOURCES_DYE_DYE_H +#define RESOURCES_DYE_DYE_H + +#include + +#include "localconsts.h" + +class DyePalette; + +const int dyePalateSize = 9; +const int sPaleteIndex = 7; +const int aPaleteIndex = 8; + +/** + * Class for dispatching pixel-recoloring amongst several palettes. + */ +class Dye final +{ + public: + /** + * Creates a set of palettes based on the given string. + * + * The parts of string are separated by semi-colons. Each part starts + * by an uppercase letter, followed by a colon and then a palette name. + */ + explicit Dye(const std::string &dye); + + A_DELETE_COPY(Dye) + + /** + * Destroys the associated palettes. + */ + ~Dye(); + + /** + * Fills the blank in a dye placeholder with some palette names. + */ + static void instantiate(std::string &restrict target, + const std::string &restrict palettes); + + /** + * Return special dye palete (S) + */ + const DyePalette *getSPalete() const A_WARN_UNUSED + { return mDyePalettes[sPaleteIndex]; } + + /** + * Return special dye palete (A) + */ + const DyePalette *getAPalete() const A_WARN_UNUSED + { return mDyePalettes[aPaleteIndex]; } + + /** + * Return dye type for S - 1, for A - 2, 0 for other + */ + int getType() const A_WARN_UNUSED; + + void normalDye(uint32_t *restrict pixels, const int bufSize) const; + + void normalOGLDye(uint32_t *restrict pixels, const int bufSize) const; + + private: + /** + * The order of the palettes, as well as their uppercase letter, is: + * + * Red, Green, Yellow, Blue, Magenta, White (or rather gray), Simple. + */ + DyePalette *mDyePalettes[dyePalateSize]; +}; + +#endif // RESOURCES_DYE_DYE_H diff --git a/src/resources/dye/dye_unittest.cc b/src/resources/dye/dye_unittest.cc new file mode 100644 index 000000000..1ee109ffa --- /dev/null +++ b/src/resources/dye/dye_unittest.cc @@ -0,0 +1,254 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "catch.hpp" + +#include "resources/dye/dye.h" +#include "resources/dye/dyepalette.h" + +#include "debug.h" + +TEST_CASE("Dye replaceSOGLColor 1") +{ + DyePalette palette("#00ff00,000011", 6); + uint8_t data[4]; + data[0] = 0x01; + data[1] = 0x02; + data[2] = 0x03; + data[3] = 0x10; + palette.replaceSOGLColor(reinterpret_cast(&data[0]), 1); + REQUIRE(0x01 == data[0]); + REQUIRE(0x02 == data[1]); + REQUIRE(0x03 == data[2]); + REQUIRE(0x10 == data[3]); +} + +TEST_CASE("Dye replaceSOGLColor 2") +{ + DyePalette palette("#01ff02,030411", 6); + uint8_t data[4]; + data[0] = 0x01; + data[1] = 0xff; + data[2] = 0x02; + data[3] = 0x20; + palette.replaceSOGLColor(reinterpret_cast(&data[0]), 1); + REQUIRE(0x03 == data[0]); + REQUIRE(0x04 == data[1]); + REQUIRE(0x11 == data[2]); + REQUIRE(0x20 == data[3]); +} + +TEST_CASE("Dye replaceSOGLColor 3") +{ + DyePalette palette("#404040,200000,0100ee,102030", 6); + uint8_t data[4]; + data[0] = 0x01; + data[1] = 0x00; + data[2] = 0xee; + data[3] = 0x40; + palette.replaceSOGLColor(reinterpret_cast(&data[0]), 1); + REQUIRE(0x10 == data[0]); + REQUIRE(0x20 == data[1]); + REQUIRE(0x30 == data[2]); + REQUIRE(0x40 == data[3]); +} + + +TEST_CASE("Dye replaceAOGLColor 1") +{ + DyePalette palette("#00ff0010,00001120", 8); + uint8_t data[4]; + data[0] = 0x01; + data[1] = 0x02; + data[2] = 0x03; + data[3] = 0x10; + palette.replaceAOGLColor(reinterpret_cast(&data[0]), 1); + REQUIRE(0x01 == data[0]); + REQUIRE(0x02 == data[1]); + REQUIRE(0x03 == data[2]); + REQUIRE(0x10 == data[3]); +} + +TEST_CASE("Dye replaceAOGLColor 2") +{ + DyePalette palette("#00ff0120,020311ff", 8); + uint8_t data[4]; + data[0] = 0x00; + data[1] = 0xff; + data[2] = 0x01; + data[3] = 0x20; + palette.replaceAOGLColor(reinterpret_cast(&data[0]), 1); + REQUIRE(0x02 == data[0]); + REQUIRE(0x03 == data[1]); + REQUIRE(0x11 == data[2]); + REQUIRE(0xff == data[3]); +} + +TEST_CASE("Dye replaceAOGLColor 3") +{ + DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8); + uint8_t data[4]; + data[0] = 0x01; + data[1] = 0x00; + data[2] = 0xee; + data[3] = 0x40; + palette.replaceAOGLColor(reinterpret_cast(&data[0]), 1); + REQUIRE(0x10 == data[0]); + REQUIRE(0x20 == data[1]); + REQUIRE(0x30 == data[2]); + REQUIRE(0xff == data[3]); +} + + +TEST_CASE("Dye replaceSColor 1") +{ + DyePalette palette("#00ff00,000011", 6); + uint8_t data[4]; + data[0] = 0x01; + data[1] = 0x02; + data[2] = 0x03; + data[3] = 0x10; + palette.replaceSColor(reinterpret_cast(&data[0]), 1); + REQUIRE(0x01 == data[0]); + REQUIRE(0x02 == data[1]); + REQUIRE(0x03 == data[2]); + REQUIRE(0x10 == data[3]); +} + +TEST_CASE("Dye replaceSColor 2") +{ + DyePalette palette("#403020,706050", 6); + uint8_t data[4]; + data[0] = 0x10; + data[1] = 0x20; + data[2] = 0x30; + data[3] = 0x40; + palette.replaceSColor(reinterpret_cast(&data[0]), 1); + REQUIRE(0x10 == data[0]); + REQUIRE(0x50 == data[1]); + REQUIRE(0x60 == data[2]); + REQUIRE(0x70 == data[3]); +} + +TEST_CASE("Dye replaceSColor 3") +{ + DyePalette palette("#123456,000000,ff3020,706050", 6); + uint8_t data[4]; + data[0] = 0x10; + data[1] = 0x20; + data[2] = 0x30; + data[3] = 0xff; + palette.replaceSColor(reinterpret_cast(&data[0]), 1); + REQUIRE(0x10 == data[0]); + REQUIRE(0x50 == data[1]); + REQUIRE(0x60 == data[2]); + REQUIRE(0x70 == data[3]); +} + + +TEST_CASE("Dye replaceAColor 1") +{ + DyePalette palette("#00ff0010,00001120", 8); + uint8_t data[4]; + data[0] = 0x01; + data[1] = 0x02; + data[2] = 0x03; + data[3] = 0x10; + palette.replaceAColor(reinterpret_cast(&data[0]), 1); + REQUIRE(0x01 == data[0]); + REQUIRE(0x02 == data[1]); + REQUIRE(0x03 == data[2]); + REQUIRE(0x10 == data[3]); +} + +TEST_CASE("Dye replaceAColor 2") +{ + DyePalette palette("#02ff0120,040311ff", 8); + uint8_t data[4]; + data[0] = 0x20; + data[1] = 0x01; + data[2] = 0xff; + data[3] = 0x02; + palette.replaceAColor(reinterpret_cast(&data[0]), 1); + REQUIRE(0xff == data[0]); + REQUIRE(0x11 == data[1]); + REQUIRE(0x03 == data[2]); + REQUIRE(0x04 == data[3]); +} + +TEST_CASE("Dye replaceAColor 3") +{ + DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8); + uint8_t data[4]; + data[0] = 0x40; + data[1] = 0xee; + data[2] = 0x00; + data[3] = 0x01; + palette.replaceAColor(reinterpret_cast(&data[0]), 1); + REQUIRE(0xff == data[0]); + REQUIRE(0x30 == data[1]); + REQUIRE(0x20 == data[2]); + REQUIRE(0x10 == data[3]); +} + +TEST_CASE("Dye normalDye 1") +{ + Dye dye("R:#203040,506070"); + uint8_t data[4]; + data[0] = 0x55; + data[1] = 0x00; + data[2] = 0x00; + data[3] = 0x50; + dye.normalDye(reinterpret_cast(&data[0]), 1); + REQUIRE(0x55 == data[0]); + REQUIRE(0x28 == data[1]); + REQUIRE(0x1e == data[2]); + REQUIRE(0x14 == data[3]); +} + +TEST_CASE("Dye normalDye 2") +{ + Dye dye("G:#203040,506070"); + uint8_t data[4]; + data[0] = 0x60; + data[1] = 0x00; + data[2] = 0x50; + data[3] = 0x00; + dye.normalDye(reinterpret_cast(&data[0]), 1); + REQUIRE(0x60 == data[0]); + REQUIRE(0x28 == data[1]); + REQUIRE(0x1e == data[2]); + REQUIRE(0x14 == data[3]); +} + +TEST_CASE("Dye normalOGLDye 1") +{ + Dye dye("R:#203040,506070"); + uint8_t data[4]; + data[0] = 0x55; + data[1] = 0x00; + data[2] = 0x00; + data[3] = 0x50; + dye.normalOGLDye(reinterpret_cast(&data[0]), 1); + REQUIRE(0x15 == data[0]); + REQUIRE(0x20 == data[1]); + REQUIRE(0x2a == data[2]); + REQUIRE(0x50 == data[3]); +} diff --git a/src/resources/dye/dyecolor.h b/src/resources/dye/dyecolor.h new file mode 100644 index 000000000..4e8864c66 --- /dev/null +++ b/src/resources/dye/dyecolor.h @@ -0,0 +1,53 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013-2015 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef RESOURCES_DYE_DYECOLOR_H +#define RESOURCES_DYE_DYECOLOR_H + +#include "localconsts.h" + +struct DyeColor final +{ + DyeColor() + { + value[3] = 255; + } + + DyeColor(const uint8_t r, const uint8_t g, const uint8_t b) + { + value[0] = r; + value[1] = g; + value[2] = b; + value[3] = 255; + } + + DyeColor(const uint8_t r, const uint8_t g, const uint8_t b, + const uint8_t a) + { + value[0] = r; + value[1] = g; + value[2] = b; + value[3] = a; + } + + uint8_t value[4]; +}; + +#endif // RESOURCES_DYE_DYECOLOR_H diff --git a/src/resources/dye/dyepalette.cpp b/src/resources/dye/dyepalette.cpp new file mode 100644 index 000000000..2dd71f2ec --- /dev/null +++ b/src/resources/dye/dyepalette.cpp @@ -0,0 +1,586 @@ +/* + * The ManaPlus Client + * Copyright (C) 2007-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2015 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "resources/dye/dyepalette.h" + +#include "logger.h" + +#ifndef DYECMD +#include "resources/db/palettedb.h" +#endif + +#include + +#include + +#include "debug.h" + +DyePalette::DyePalette(const std::string &description, + const uint8_t blockSize) : + mColors() +{ + const size_t size = static_cast(description.length()); + if (size == 0) + return; + + if (description[0] == '#') + { + size_t pos = 1; + for ( ; ; ) + { + if (pos + blockSize > size) + break; + + DyeColor color(0, 0, 0, 0); + + for (size_t i = 0, colorIdx = 0; i < blockSize && colorIdx < 4; + i += 2, colorIdx ++) + { + color.value[colorIdx] = static_cast(( + hexDecode(description[pos + i]) << 4) + + hexDecode(description[pos + i + 1])); + } + mColors.push_back(color); + pos += blockSize; + + if (pos == size) + return; + if (description[pos] != ',') + break; + + ++pos; + } + } +#ifndef DYECMD + else if (description[0] == '@') + { + size_t pos = 1; + for ( ; pos < size ; ) + { + const size_t idx = description.find(',', pos); + if (idx == std::string::npos) + return; + if (idx == pos) + break; + mColors.push_back(PaletteDB::getColor( + description.substr(pos, idx - pos))); + pos = idx + 1; + } + } +#endif + logger->log("Error, invalid embedded palette: %s", description.c_str()); +} + +unsigned int DyePalette::hexDecode(const signed char c) +{ + if ('0' <= c && c <= '9') + return c - '0'; + else if ('A' <= c && c <= 'F') + return c - 'A' + 10; + else if ('a' <= c && c <= 'f') + return c - 'a' + 10; + else + return 0; +} + +void DyePalette::getColor(const unsigned int intensity, + unsigned int (&color)[3]) const +{ + if (intensity == 0) + { + color[0] = 0; + color[1] = 0; + color[2] = 0; + return; + } + + const int last = static_cast(mColors.size()); + if (last == 0) + return; + + const int intLast = intensity * last; + const int i = intLast / 255; + const int t = intLast % 255; + + int j = t != 0 ? i : i - 1; + + if (j >= last) + j = 0; + + // Get the exact color if any, the next color otherwise. + const DyeColor &colorJ = mColors[j]; + const int r2 = colorJ.value[0]; + const int g2 = colorJ.value[1]; + const int b2 = colorJ.value[2]; + + if (t == 0) + { + // Exact color. + color[0] = r2; + color[1] = g2; + color[2] = b2; + return; + } + + // Get the previous color. First color is implicitly black. + if (i > 0 && i < last + 1) + { + const DyeColor &colorI = mColors[i - 1]; + const int t2 = 255 - t; + // Perform a linear interpolation. + color[0] = (t2 * colorI.value[0] + t * r2) / 255; + color[1] = (t2 * colorI.value[1] + t * g2) / 255; + color[2] = (t2 * colorI.value[2] + t * b2) / 255; + } + else + { + // Perform a linear interpolation. + color[0] = (t * r2) / 255; + color[1] = (t * g2) / 255; + color[2] = (t * b2) / 255; + } +} + +void DyePalette::getColor(double intensity, int (&color)[3]) const +{ + // Nothing to do here + if (mColors.empty()) + return; + + // Force range + if (intensity > 1.0) + intensity = 1.0; + else if (intensity < 0.0) + intensity = 0.0; + + // Scale up + intensity *= static_cast(mColors.size() - 1); + + // Color indices + const int i = static_cast(floor(intensity)); + const int j = static_cast(ceil(intensity)); + const DyeColor &colorI = mColors[i]; + + if (i == j) + { + // Exact color. + color[0] = colorI.value[0]; + color[1] = colorI.value[1]; + color[2] = colorI.value[2]; + return; + } + + intensity -= i; + const double rest = 1 - intensity; + const DyeColor &colorJ = mColors[j]; + + // Perform the interpolation. + color[0] = static_cast(rest * colorI.value[0] + + intensity * colorJ.value[0]); + color[1] = static_cast(rest * colorI.value[1] + + intensity * colorJ.value[1]); + color[2] = static_cast(rest * colorI.value[2] + + intensity * colorJ.value[2]); +} + +void DyePalette::replaceSColor(uint32_t *restrict pixels, + const int bufSize) const +{ + std::vector::const_iterator it_end = mColors.end(); + const size_t sz = mColors.size(); + if (!sz || !pixels) + return; + if (sz % 2) + -- it_end; + +#ifdef ENABLE_CILKPLUS + cilk_for (int ptr = 0; ptr < bufSize; ptr ++) + { + uint8_t *const p = reinterpret_cast(&pixels[ptr]); +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const int alpha = pixels[ptr] & 0xff000000; + const unsigned int data = pixels[ptr] & 0x00ffffff; +#else + const int alpha = *p & 0xff; + const unsigned int data = pixels[ptr] & 0xffffff00; +#endif +// logger->log("c:%04d %08x", c, *pixels); +// logger->log("data: %08x", data); + if (!alpha) + { +// logger->log("skip: %08x", *pixels); + } + else + { + std::vector::const_iterator it = mColors.begin(); + while (it != it_end) + { + const DyeColor &col = *it; + ++ it; + const DyeColor &col2 = *it; + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int coldata = (col.value[2] << 16U) + | (col.value[1] << 8U) | (col.value[0]); +#else + const unsigned int coldata = (col.value[2] << 8U) + | (col.value[1] << 16U) | (col.value[0] << 24U); +#endif +// logger->log("coldata: %08x", coldata); + if (data == coldata) + { +// logger->log("correct"); + p[3] = col2.value[0]; + p[2] = col2.value[1]; + p[1] = col2.value[2]; + break; + } + ++ it; + } + } + } +#else // ENABLE_CILKPLUS + + for (uint32_t *p_end = pixels + static_cast(bufSize); + pixels != p_end; + ++ pixels) + { + uint8_t *const p = reinterpret_cast(pixels); +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const int alpha = *pixels & 0xff000000; + const unsigned int data = (*pixels) & 0x00ffffff; +#else + const int alpha = *p & 0xff; + const unsigned int data = (*pixels) & 0xffffff00; +#endif +// logger->log("c:%04d %08x", c, *pixels); +// logger->log("data: %08x", data); + if (!alpha) + { +// logger->log("skip: %08x", *pixels); + continue; + } + + std::vector::const_iterator it = mColors.begin(); + while (it != it_end) + { + const DyeColor &col = *it; + ++ it; + const DyeColor &col2 = *it; + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int coldata = (col.value[2] << 16U) + | (col.value[1] << 8U) | (col.value[0]); +#else + const unsigned int coldata = (col.value[2] << 8U) + | (col.value[1] << 16U) | (col.value[0] << 24U); +#endif +// logger->log("coldata: %08x", coldata); + if (data == coldata) + { +// logger->log("correct"); + p[3] = col2.value[0]; + p[2] = col2.value[1]; + p[1] = col2.value[2]; + break; + } + + ++ it; + } + } +#endif // ENABLE_CILKPLUS +} + +void DyePalette::replaceAColor(uint32_t *restrict pixels, + const int bufSize) const +{ + std::vector::const_iterator it_end = mColors.end(); + const size_t sz = mColors.size(); + if (!sz || !pixels) + return; + if (sz % 2) + -- it_end; + +#ifdef ENABLE_CILKPLUS + cilk_for (int ptr = 0; ptr < bufSize; ptr ++) + { + uint8_t *const p = reinterpret_cast(&pixels[ptr]); + const unsigned int data = pixels[ptr]; + + std::vector::const_iterator it = mColors.begin(); + while (it != it_end) + { + const DyeColor &col = *it; + ++ it; + const DyeColor &col2 = *it; + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int coldata = (col.value[3] << 24U) + | (col.value[2] << 16U) + | (col.value[1] << 8U) + | (col.value[0]); +#else + const unsigned int coldata = (col.value[3]) + | (col.value[2] << 8U) + | (col.value[1] << 16U) | + (col.value[0] << 24U); +#endif + + if (data == coldata) + { + p[3] = col2.value[0]; + p[2] = col2.value[1]; + p[1] = col2.value[2]; + p[0] = col2.value[3]; + break; + } + + ++ it; + } + } + +#else // ENABLE_CILKPLUS + + for (uint32_t *p_end = pixels + static_cast(bufSize); + pixels != p_end; + ++pixels) + { + uint8_t *const p = reinterpret_cast(pixels); + const unsigned int data = *pixels; + + std::vector::const_iterator it = mColors.begin(); + while (it != it_end) + { + const DyeColor &col = *it; + ++ it; + const DyeColor &col2 = *it; + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int coldata = (col.value[3] << 24U) + | (col.value[2] << 16U) + | (col.value[1] << 8U) + | (col.value[0]); +#else + const unsigned int coldata = (col.value[3]) + | (col.value[2] << 8U) + | (col.value[1] << 16U) | + (col.value[0] << 24U); +#endif + + if (data == coldata) + { + p[3] = col2.value[0]; + p[2] = col2.value[1]; + p[1] = col2.value[2]; + p[0] = col2.value[3]; + break; + } + + ++ it; + } + } +#endif // ENABLE_CILKPLUS +} + +void DyePalette::replaceSOGLColor(uint32_t *restrict pixels, + const int bufSize) const +{ + std::vector::const_iterator it_end = mColors.end(); + const size_t sz = mColors.size(); + if (!sz || !pixels) + return; + if (sz % 2) + -- it_end; + +#ifdef ENABLE_CILKPLUS + cilk_for (int ptr = 0; ptr < bufSize; ptr ++) + { + uint8_t *const p = reinterpret_cast(&pixels[ptr]); +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const int alpha = *p & 0xff; + const unsigned int data = (pixels[ptr]) & 0xffffff00; +#else + const int alpha = pixels[ptr] & 0xff000000; + const unsigned int data = (pixels[ptr]) & 0x00ffffff; +#endif + if (alpha) + { + std::vector::const_iterator it = mColors.begin(); + while (it != it_end) + { + const DyeColor &col = *it; + ++ it; + const DyeColor &col2 = *it; + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int coldata = (col.value[0] << 24) + | (col.value[1] << 16) | (col.value[2] << 8); +#else + const unsigned int coldata = (col.value[0]) + | (col.value[1] << 8) | (col.value[2] << 16); +#endif + if (data == coldata) + { + p[0] = col2.value[0]; + p[1] = col2.value[1]; + p[2] = col2.value[2]; + break; + } + + ++ it; + } + } + } + +#else // ENABLE_CILKPLUS + + for (uint32_t *p_end = pixels + static_cast(bufSize); + pixels != p_end; + ++pixels) + { + uint8_t *const p = reinterpret_cast(pixels); +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const int alpha = *p & 0xff; + const unsigned int data = (*pixels) & 0xffffff00; +#else + const int alpha = *pixels & 0xff000000; + const unsigned int data = (*pixels) & 0x00ffffff; +#endif + if (!alpha) + continue; + + std::vector::const_iterator it = mColors.begin(); + while (it != it_end) + { + const DyeColor &col = *it; + ++ it; + const DyeColor &col2 = *it; + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int coldata = (col.value[0] << 24) + | (col.value[1] << 16) | (col.value[2] << 8); +#else + const unsigned int coldata = (col.value[0]) + | (col.value[1] << 8) | (col.value[2] << 16); +#endif + if (data == coldata) + { + p[0] = col2.value[0]; + p[1] = col2.value[1]; + p[2] = col2.value[2]; + break; + } + + ++ it; + } + } +#endif // ENABLE_CILKPLUS +} + +void DyePalette::replaceAOGLColor(uint32_t *restrict pixels, + const int bufSize) const +{ + std::vector::const_iterator it_end = mColors.end(); + const size_t sz = mColors.size(); + if (!sz || !pixels) + return; + if (sz % 2) + -- it_end; + +#ifdef ENABLE_CILKPLUS + cilk_for (int ptr = 0; ptr < bufSize; ptr ++) + { + uint8_t *const p = reinterpret_cast(&pixels[ptr]); + const unsigned int data = pixels[ptr]; + + std::vector::const_iterator it = mColors.begin(); + while (it != it_end) + { + const DyeColor &col = *it; + ++ it; + const DyeColor &col2 = *it; + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int coldata = (col.value[0] << 24U) + | (col.value[1] << 16U) + | (col.value[2] << 8U) + | col.value[3]; +#else + const unsigned int coldata = (col.value[0]) + | (col.value[1] << 8U) + | (col.value[2] << 16U) + | (col.value[3] << 24U); +#endif + if (data == coldata) + { + p[0] = col2.value[0]; + p[1] = col2.value[1]; + p[2] = col2.value[2]; + p[3] = col2.value[3]; + break; + } + + ++ it; + } + } + +#else // ENABLE_CILKPLUS + + for (uint32_t *p_end = pixels + static_cast(bufSize); + pixels != p_end; + ++pixels) + { + uint8_t *const p = reinterpret_cast(pixels); + const unsigned int data = *pixels; + + std::vector::const_iterator it = mColors.begin(); + while (it != it_end) + { + const DyeColor &col = *it; + ++ it; + const DyeColor &col2 = *it; + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int coldata = (col.value[0] << 24U) + | (col.value[1] << 16U) + | (col.value[2] << 8U) + | col.value[3]; +#else + const unsigned int coldata = (col.value[0]) + | (col.value[1] << 8U) + | (col.value[2] << 16U) + | (col.value[3] << 24U); +#endif + if (data == coldata) + { + p[0] = col2.value[0]; + p[1] = col2.value[1]; + p[2] = col2.value[2]; + p[3] = col2.value[3]; + break; + } + + ++ it; + } + } +#endif // ENABLE_CILKPLUS +} diff --git a/src/resources/dye/dyepalette.h b/src/resources/dye/dyepalette.h new file mode 100644 index 000000000..33d16fa50 --- /dev/null +++ b/src/resources/dye/dyepalette.h @@ -0,0 +1,88 @@ +/* + * The ManaPlus Client + * Copyright (C) 2007-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2015 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef RESOURCES_DYE_DYEPALETTE_H +#define RESOURCES_DYE_DYEPALETTE_H + +#include "resources/dye/dyecolor.h" + +#include +#include + +#include "localconsts.h" + +/** + * Class for performing a linear interpolation between colors. + */ +class DyePalette final +{ + public: + /** + * Creates a palette based on the given string. + * The string is either a file name or a sequence of hexadecimal RGB + * values separated by ',' and starting with '#'. + */ + DyePalette(const std::string &pallete, const uint8_t blockSize); + + A_DELETE_COPY(DyePalette) + + /** + * Gets a pixel color depending on its intensity. First color is + * implicitly black (0, 0, 0). + */ + void getColor(const unsigned int intensity, + unsigned int (&color)[3]) const; + + /** + * Gets a pixel color depending on its intensity. + */ + void getColor(double intensity, int (&color)[3]) const; + + /** + * replace colors for SDL for S dye. + */ + void replaceSColor(uint32_t *restrict pixels, const int bufSize) const; + + /** + * replace colors for SDL for S dye. + */ + void replaceAColor(uint32_t *restrict pixels, const int bufSize) const; + + /** + * replace colors for OpenGL for S dye. + */ + void replaceSOGLColor(uint32_t *restrict pixels, + const int bufSize) const; + + /** + * replace colors for OpenGL for A dye. + */ + void replaceAOGLColor(uint32_t *restrict pixels, + const int bufSize) const; + + static unsigned int hexDecode(const signed char c) A_WARN_UNUSED; + + private: + std::vector mColors; +}; + +#endif // RESOURCES_DYE_DYEPALETTE_H diff --git a/src/resources/dye_unittest.cc b/src/resources/dye_unittest.cc deleted file mode 100644 index aeee85e12..000000000 --- a/src/resources/dye_unittest.cc +++ /dev/null @@ -1,255 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2013 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "catch.hpp" - -#include "resources/dye.h" - -#include "resources/dyepalette.h" - -#include "debug.h" - -TEST_CASE("Dye replaceSOGLColor 1") -{ - DyePalette palette("#00ff00,000011", 6); - uint8_t data[4]; - data[0] = 0x01; - data[1] = 0x02; - data[2] = 0x03; - data[3] = 0x10; - palette.replaceSOGLColor(reinterpret_cast(&data[0]), 1); - REQUIRE(0x01 == data[0]); - REQUIRE(0x02 == data[1]); - REQUIRE(0x03 == data[2]); - REQUIRE(0x10 == data[3]); -} - -TEST_CASE("Dye replaceSOGLColor 2") -{ - DyePalette palette("#01ff02,030411", 6); - uint8_t data[4]; - data[0] = 0x01; - data[1] = 0xff; - data[2] = 0x02; - data[3] = 0x20; - palette.replaceSOGLColor(reinterpret_cast(&data[0]), 1); - REQUIRE(0x03 == data[0]); - REQUIRE(0x04 == data[1]); - REQUIRE(0x11 == data[2]); - REQUIRE(0x20 == data[3]); -} - -TEST_CASE("Dye replaceSOGLColor 3") -{ - DyePalette palette("#404040,200000,0100ee,102030", 6); - uint8_t data[4]; - data[0] = 0x01; - data[1] = 0x00; - data[2] = 0xee; - data[3] = 0x40; - palette.replaceSOGLColor(reinterpret_cast(&data[0]), 1); - REQUIRE(0x10 == data[0]); - REQUIRE(0x20 == data[1]); - REQUIRE(0x30 == data[2]); - REQUIRE(0x40 == data[3]); -} - - -TEST_CASE("Dye replaceAOGLColor 1") -{ - DyePalette palette("#00ff0010,00001120", 8); - uint8_t data[4]; - data[0] = 0x01; - data[1] = 0x02; - data[2] = 0x03; - data[3] = 0x10; - palette.replaceAOGLColor(reinterpret_cast(&data[0]), 1); - REQUIRE(0x01 == data[0]); - REQUIRE(0x02 == data[1]); - REQUIRE(0x03 == data[2]); - REQUIRE(0x10 == data[3]); -} - -TEST_CASE("Dye replaceAOGLColor 2") -{ - DyePalette palette("#00ff0120,020311ff", 8); - uint8_t data[4]; - data[0] = 0x00; - data[1] = 0xff; - data[2] = 0x01; - data[3] = 0x20; - palette.replaceAOGLColor(reinterpret_cast(&data[0]), 1); - REQUIRE(0x02 == data[0]); - REQUIRE(0x03 == data[1]); - REQUIRE(0x11 == data[2]); - REQUIRE(0xff == data[3]); -} - -TEST_CASE("Dye replaceAOGLColor 3") -{ - DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8); - uint8_t data[4]; - data[0] = 0x01; - data[1] = 0x00; - data[2] = 0xee; - data[3] = 0x40; - palette.replaceAOGLColor(reinterpret_cast(&data[0]), 1); - REQUIRE(0x10 == data[0]); - REQUIRE(0x20 == data[1]); - REQUIRE(0x30 == data[2]); - REQUIRE(0xff == data[3]); -} - - -TEST_CASE("Dye replaceSColor 1") -{ - DyePalette palette("#00ff00,000011", 6); - uint8_t data[4]; - data[0] = 0x01; - data[1] = 0x02; - data[2] = 0x03; - data[3] = 0x10; - palette.replaceSColor(reinterpret_cast(&data[0]), 1); - REQUIRE(0x01 == data[0]); - REQUIRE(0x02 == data[1]); - REQUIRE(0x03 == data[2]); - REQUIRE(0x10 == data[3]); -} - -TEST_CASE("Dye replaceSColor 2") -{ - DyePalette palette("#403020,706050", 6); - uint8_t data[4]; - data[0] = 0x10; - data[1] = 0x20; - data[2] = 0x30; - data[3] = 0x40; - palette.replaceSColor(reinterpret_cast(&data[0]), 1); - REQUIRE(0x10 == data[0]); - REQUIRE(0x50 == data[1]); - REQUIRE(0x60 == data[2]); - REQUIRE(0x70 == data[3]); -} - -TEST_CASE("Dye replaceSColor 3") -{ - DyePalette palette("#123456,000000,ff3020,706050", 6); - uint8_t data[4]; - data[0] = 0x10; - data[1] = 0x20; - data[2] = 0x30; - data[3] = 0xff; - palette.replaceSColor(reinterpret_cast(&data[0]), 1); - REQUIRE(0x10 == data[0]); - REQUIRE(0x50 == data[1]); - REQUIRE(0x60 == data[2]); - REQUIRE(0x70 == data[3]); -} - - -TEST_CASE("Dye replaceAColor 1") -{ - DyePalette palette("#00ff0010,00001120", 8); - uint8_t data[4]; - data[0] = 0x01; - data[1] = 0x02; - data[2] = 0x03; - data[3] = 0x10; - palette.replaceAColor(reinterpret_cast(&data[0]), 1); - REQUIRE(0x01 == data[0]); - REQUIRE(0x02 == data[1]); - REQUIRE(0x03 == data[2]); - REQUIRE(0x10 == data[3]); -} - -TEST_CASE("Dye replaceAColor 2") -{ - DyePalette palette("#02ff0120,040311ff", 8); - uint8_t data[4]; - data[0] = 0x20; - data[1] = 0x01; - data[2] = 0xff; - data[3] = 0x02; - palette.replaceAColor(reinterpret_cast(&data[0]), 1); - REQUIRE(0xff == data[0]); - REQUIRE(0x11 == data[1]); - REQUIRE(0x03 == data[2]); - REQUIRE(0x04 == data[3]); -} - -TEST_CASE("Dye replaceAColor 3") -{ - DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8); - uint8_t data[4]; - data[0] = 0x40; - data[1] = 0xee; - data[2] = 0x00; - data[3] = 0x01; - palette.replaceAColor(reinterpret_cast(&data[0]), 1); - REQUIRE(0xff == data[0]); - REQUIRE(0x30 == data[1]); - REQUIRE(0x20 == data[2]); - REQUIRE(0x10 == data[3]); -} - -TEST_CASE("Dye normalDye 1") -{ - Dye dye("R:#203040,506070"); - uint8_t data[4]; - data[0] = 0x55; - data[1] = 0x00; - data[2] = 0x00; - data[3] = 0x50; - dye.normalDye(reinterpret_cast(&data[0]), 1); - REQUIRE(0x55 == data[0]); - REQUIRE(0x28 == data[1]); - REQUIRE(0x1e == data[2]); - REQUIRE(0x14 == data[3]); -} - -TEST_CASE("Dye normalDye 2") -{ - Dye dye("G:#203040,506070"); - uint8_t data[4]; - data[0] = 0x60; - data[1] = 0x00; - data[2] = 0x50; - data[3] = 0x00; - dye.normalDye(reinterpret_cast(&data[0]), 1); - REQUIRE(0x60 == data[0]); - REQUIRE(0x28 == data[1]); - REQUIRE(0x1e == data[2]); - REQUIRE(0x14 == data[3]); -} - -TEST_CASE("Dye normalOGLDye 1") -{ - Dye dye("R:#203040,506070"); - uint8_t data[4]; - data[0] = 0x55; - data[1] = 0x00; - data[2] = 0x00; - data[3] = 0x50; - dye.normalOGLDye(reinterpret_cast(&data[0]), 1); - REQUIRE(0x15 == data[0]); - REQUIRE(0x20 == data[1]); - REQUIRE(0x2a == data[2]); - REQUIRE(0x50 == data[3]); -} diff --git a/src/resources/dyecolor.h b/src/resources/dyecolor.h deleted file mode 100644 index 2a3b32968..000000000 --- a/src/resources/dyecolor.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2013-2015 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef RESOURCES_DYECOLOR_H -#define RESOURCES_DYECOLOR_H - -#include "localconsts.h" - -struct DyeColor final -{ - DyeColor() - { - value[3] = 255; - } - - DyeColor(const uint8_t r, const uint8_t g, const uint8_t b) - { - value[0] = r; - value[1] = g; - value[2] = b; - value[3] = 255; - } - - DyeColor(const uint8_t r, const uint8_t g, const uint8_t b, - const uint8_t a) - { - value[0] = r; - value[1] = g; - value[2] = b; - value[3] = a; - } - - uint8_t value[4]; -}; - -#endif // RESOURCES_DYECOLOR_H diff --git a/src/resources/dyepalette.cpp b/src/resources/dyepalette.cpp deleted file mode 100644 index 4ff93c1f1..000000000 --- a/src/resources/dyepalette.cpp +++ /dev/null @@ -1,586 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2007-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2015 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "resources/dyepalette.h" - -#include "logger.h" - -#ifndef DYECMD -#include "resources/db/palettedb.h" -#endif - -#include - -#include - -#include "debug.h" - -DyePalette::DyePalette(const std::string &description, - const uint8_t blockSize) : - mColors() -{ - const size_t size = static_cast(description.length()); - if (size == 0) - return; - - if (description[0] == '#') - { - size_t pos = 1; - for ( ; ; ) - { - if (pos + blockSize > size) - break; - - DyeColor color(0, 0, 0, 0); - - for (size_t i = 0, colorIdx = 0; i < blockSize && colorIdx < 4; - i += 2, colorIdx ++) - { - color.value[colorIdx] = static_cast(( - hexDecode(description[pos + i]) << 4) - + hexDecode(description[pos + i + 1])); - } - mColors.push_back(color); - pos += blockSize; - - if (pos == size) - return; - if (description[pos] != ',') - break; - - ++pos; - } - } -#ifndef DYECMD - else if (description[0] == '@') - { - size_t pos = 1; - for ( ; pos < size ; ) - { - const size_t idx = description.find(',', pos); - if (idx == std::string::npos) - return; - if (idx == pos) - break; - mColors.push_back(PaletteDB::getColor( - description.substr(pos, idx - pos))); - pos = idx + 1; - } - } -#endif - logger->log("Error, invalid embedded palette: %s", description.c_str()); -} - -unsigned int DyePalette::hexDecode(const signed char c) -{ - if ('0' <= c && c <= '9') - return c - '0'; - else if ('A' <= c && c <= 'F') - return c - 'A' + 10; - else if ('a' <= c && c <= 'f') - return c - 'a' + 10; - else - return 0; -} - -void DyePalette::getColor(const unsigned int intensity, - unsigned int (&color)[3]) const -{ - if (intensity == 0) - { - color[0] = 0; - color[1] = 0; - color[2] = 0; - return; - } - - const int last = static_cast(mColors.size()); - if (last == 0) - return; - - const int intLast = intensity * last; - const int i = intLast / 255; - const int t = intLast % 255; - - int j = t != 0 ? i : i - 1; - - if (j >= last) - j = 0; - - // Get the exact color if any, the next color otherwise. - const DyeColor &colorJ = mColors[j]; - const int r2 = colorJ.value[0]; - const int g2 = colorJ.value[1]; - const int b2 = colorJ.value[2]; - - if (t == 0) - { - // Exact color. - color[0] = r2; - color[1] = g2; - color[2] = b2; - return; - } - - // Get the previous color. First color is implicitly black. - if (i > 0 && i < last + 1) - { - const DyeColor &colorI = mColors[i - 1]; - const int t2 = 255 - t; - // Perform a linear interpolation. - color[0] = (t2 * colorI.value[0] + t * r2) / 255; - color[1] = (t2 * colorI.value[1] + t * g2) / 255; - color[2] = (t2 * colorI.value[2] + t * b2) / 255; - } - else - { - // Perform a linear interpolation. - color[0] = (t * r2) / 255; - color[1] = (t * g2) / 255; - color[2] = (t * b2) / 255; - } -} - -void DyePalette::getColor(double intensity, int (&color)[3]) const -{ - // Nothing to do here - if (mColors.empty()) - return; - - // Force range - if (intensity > 1.0) - intensity = 1.0; - else if (intensity < 0.0) - intensity = 0.0; - - // Scale up - intensity *= static_cast(mColors.size() - 1); - - // Color indices - const int i = static_cast(floor(intensity)); - const int j = static_cast(ceil(intensity)); - const DyeColor &colorI = mColors[i]; - - if (i == j) - { - // Exact color. - color[0] = colorI.value[0]; - color[1] = colorI.value[1]; - color[2] = colorI.value[2]; - return; - } - - intensity -= i; - const double rest = 1 - intensity; - const DyeColor &colorJ = mColors[j]; - - // Perform the interpolation. - color[0] = static_cast(rest * colorI.value[0] + - intensity * colorJ.value[0]); - color[1] = static_cast(rest * colorI.value[1] + - intensity * colorJ.value[1]); - color[2] = static_cast(rest * colorI.value[2] + - intensity * colorJ.value[2]); -} - -void DyePalette::replaceSColor(uint32_t *restrict pixels, - const int bufSize) const -{ - std::vector::const_iterator it_end = mColors.end(); - const size_t sz = mColors.size(); - if (!sz || !pixels) - return; - if (sz % 2) - -- it_end; - -#ifdef ENABLE_CILKPLUS - cilk_for (int ptr = 0; ptr < bufSize; ptr ++) - { - uint8_t *const p = reinterpret_cast(&pixels[ptr]); -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const int alpha = pixels[ptr] & 0xff000000; - const unsigned int data = pixels[ptr] & 0x00ffffff; -#else - const int alpha = *p & 0xff; - const unsigned int data = pixels[ptr] & 0xffffff00; -#endif -// logger->log("c:%04d %08x", c, *pixels); -// logger->log("data: %08x", data); - if (!alpha) - { -// logger->log("skip: %08x", *pixels); - } - else - { - std::vector::const_iterator it = mColors.begin(); - while (it != it_end) - { - const DyeColor &col = *it; - ++ it; - const DyeColor &col2 = *it; - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int coldata = (col.value[2] << 16U) - | (col.value[1] << 8U) | (col.value[0]); -#else - const unsigned int coldata = (col.value[2] << 8U) - | (col.value[1] << 16U) | (col.value[0] << 24U); -#endif -// logger->log("coldata: %08x", coldata); - if (data == coldata) - { -// logger->log("correct"); - p[3] = col2.value[0]; - p[2] = col2.value[1]; - p[1] = col2.value[2]; - break; - } - ++ it; - } - } - } -#else // ENABLE_CILKPLUS - - for (uint32_t *p_end = pixels + static_cast(bufSize); - pixels != p_end; - ++ pixels) - { - uint8_t *const p = reinterpret_cast(pixels); -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const int alpha = *pixels & 0xff000000; - const unsigned int data = (*pixels) & 0x00ffffff; -#else - const int alpha = *p & 0xff; - const unsigned int data = (*pixels) & 0xffffff00; -#endif -// logger->log("c:%04d %08x", c, *pixels); -// logger->log("data: %08x", data); - if (!alpha) - { -// logger->log("skip: %08x", *pixels); - continue; - } - - std::vector::const_iterator it = mColors.begin(); - while (it != it_end) - { - const DyeColor &col = *it; - ++ it; - const DyeColor &col2 = *it; - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int coldata = (col.value[2] << 16U) - | (col.value[1] << 8U) | (col.value[0]); -#else - const unsigned int coldata = (col.value[2] << 8U) - | (col.value[1] << 16U) | (col.value[0] << 24U); -#endif -// logger->log("coldata: %08x", coldata); - if (data == coldata) - { -// logger->log("correct"); - p[3] = col2.value[0]; - p[2] = col2.value[1]; - p[1] = col2.value[2]; - break; - } - - ++ it; - } - } -#endif // ENABLE_CILKPLUS -} - -void DyePalette::replaceAColor(uint32_t *restrict pixels, - const int bufSize) const -{ - std::vector::const_iterator it_end = mColors.end(); - const size_t sz = mColors.size(); - if (!sz || !pixels) - return; - if (sz % 2) - -- it_end; - -#ifdef ENABLE_CILKPLUS - cilk_for (int ptr = 0; ptr < bufSize; ptr ++) - { - uint8_t *const p = reinterpret_cast(&pixels[ptr]); - const unsigned int data = pixels[ptr]; - - std::vector::const_iterator it = mColors.begin(); - while (it != it_end) - { - const DyeColor &col = *it; - ++ it; - const DyeColor &col2 = *it; - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int coldata = (col.value[3] << 24U) - | (col.value[2] << 16U) - | (col.value[1] << 8U) - | (col.value[0]); -#else - const unsigned int coldata = (col.value[3]) - | (col.value[2] << 8U) - | (col.value[1] << 16U) | - (col.value[0] << 24U); -#endif - - if (data == coldata) - { - p[3] = col2.value[0]; - p[2] = col2.value[1]; - p[1] = col2.value[2]; - p[0] = col2.value[3]; - break; - } - - ++ it; - } - } - -#else // ENABLE_CILKPLUS - - for (uint32_t *p_end = pixels + static_cast(bufSize); - pixels != p_end; - ++pixels) - { - uint8_t *const p = reinterpret_cast(pixels); - const unsigned int data = *pixels; - - std::vector::const_iterator it = mColors.begin(); - while (it != it_end) - { - const DyeColor &col = *it; - ++ it; - const DyeColor &col2 = *it; - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int coldata = (col.value[3] << 24U) - | (col.value[2] << 16U) - | (col.value[1] << 8U) - | (col.value[0]); -#else - const unsigned int coldata = (col.value[3]) - | (col.value[2] << 8U) - | (col.value[1] << 16U) | - (col.value[0] << 24U); -#endif - - if (data == coldata) - { - p[3] = col2.value[0]; - p[2] = col2.value[1]; - p[1] = col2.value[2]; - p[0] = col2.value[3]; - break; - } - - ++ it; - } - } -#endif // ENABLE_CILKPLUS -} - -void DyePalette::replaceSOGLColor(uint32_t *restrict pixels, - const int bufSize) const -{ - std::vector::const_iterator it_end = mColors.end(); - const size_t sz = mColors.size(); - if (!sz || !pixels) - return; - if (sz % 2) - -- it_end; - -#ifdef ENABLE_CILKPLUS - cilk_for (int ptr = 0; ptr < bufSize; ptr ++) - { - uint8_t *const p = reinterpret_cast(&pixels[ptr]); -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const int alpha = *p & 0xff; - const unsigned int data = (pixels[ptr]) & 0xffffff00; -#else - const int alpha = pixels[ptr] & 0xff000000; - const unsigned int data = (pixels[ptr]) & 0x00ffffff; -#endif - if (alpha) - { - std::vector::const_iterator it = mColors.begin(); - while (it != it_end) - { - const DyeColor &col = *it; - ++ it; - const DyeColor &col2 = *it; - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int coldata = (col.value[0] << 24) - | (col.value[1] << 16) | (col.value[2] << 8); -#else - const unsigned int coldata = (col.value[0]) - | (col.value[1] << 8) | (col.value[2] << 16); -#endif - if (data == coldata) - { - p[0] = col2.value[0]; - p[1] = col2.value[1]; - p[2] = col2.value[2]; - break; - } - - ++ it; - } - } - } - -#else // ENABLE_CILKPLUS - - for (uint32_t *p_end = pixels + static_cast(bufSize); - pixels != p_end; - ++pixels) - { - uint8_t *const p = reinterpret_cast(pixels); -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const int alpha = *p & 0xff; - const unsigned int data = (*pixels) & 0xffffff00; -#else - const int alpha = *pixels & 0xff000000; - const unsigned int data = (*pixels) & 0x00ffffff; -#endif - if (!alpha) - continue; - - std::vector::const_iterator it = mColors.begin(); - while (it != it_end) - { - const DyeColor &col = *it; - ++ it; - const DyeColor &col2 = *it; - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int coldata = (col.value[0] << 24) - | (col.value[1] << 16) | (col.value[2] << 8); -#else - const unsigned int coldata = (col.value[0]) - | (col.value[1] << 8) | (col.value[2] << 16); -#endif - if (data == coldata) - { - p[0] = col2.value[0]; - p[1] = col2.value[1]; - p[2] = col2.value[2]; - break; - } - - ++ it; - } - } -#endif // ENABLE_CILKPLUS -} - -void DyePalette::replaceAOGLColor(uint32_t *restrict pixels, - const int bufSize) const -{ - std::vector::const_iterator it_end = mColors.end(); - const size_t sz = mColors.size(); - if (!sz || !pixels) - return; - if (sz % 2) - -- it_end; - -#ifdef ENABLE_CILKPLUS - cilk_for (int ptr = 0; ptr < bufSize; ptr ++) - { - uint8_t *const p = reinterpret_cast(&pixels[ptr]); - const unsigned int data = pixels[ptr]; - - std::vector::const_iterator it = mColors.begin(); - while (it != it_end) - { - const DyeColor &col = *it; - ++ it; - const DyeColor &col2 = *it; - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int coldata = (col.value[0] << 24U) - | (col.value[1] << 16U) - | (col.value[2] << 8U) - | col.value[3]; -#else - const unsigned int coldata = (col.value[0]) - | (col.value[1] << 8U) - | (col.value[2] << 16U) - | (col.value[3] << 24U); -#endif - if (data == coldata) - { - p[0] = col2.value[0]; - p[1] = col2.value[1]; - p[2] = col2.value[2]; - p[3] = col2.value[3]; - break; - } - - ++ it; - } - } - -#else // ENABLE_CILKPLUS - - for (uint32_t *p_end = pixels + static_cast(bufSize); - pixels != p_end; - ++pixels) - { - uint8_t *const p = reinterpret_cast(pixels); - const unsigned int data = *pixels; - - std::vector::const_iterator it = mColors.begin(); - while (it != it_end) - { - const DyeColor &col = *it; - ++ it; - const DyeColor &col2 = *it; - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int coldata = (col.value[0] << 24U) - | (col.value[1] << 16U) - | (col.value[2] << 8U) - | col.value[3]; -#else - const unsigned int coldata = (col.value[0]) - | (col.value[1] << 8U) - | (col.value[2] << 16U) - | (col.value[3] << 24U); -#endif - if (data == coldata) - { - p[0] = col2.value[0]; - p[1] = col2.value[1]; - p[2] = col2.value[2]; - p[3] = col2.value[3]; - break; - } - - ++ it; - } - } -#endif // ENABLE_CILKPLUS -} diff --git a/src/resources/dyepalette.h b/src/resources/dyepalette.h deleted file mode 100644 index 467ec0ac1..000000000 --- a/src/resources/dyepalette.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2007-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2015 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef RESOURCES_DYEPALETTE_H -#define RESOURCES_DYEPALETTE_H - -#include "resources/dyecolor.h" - -#include -#include - -#include "localconsts.h" - -/** - * Class for performing a linear interpolation between colors. - */ -class DyePalette final -{ - public: - /** - * Creates a palette based on the given string. - * The string is either a file name or a sequence of hexadecimal RGB - * values separated by ',' and starting with '#'. - */ - DyePalette(const std::string &pallete, const uint8_t blockSize); - - A_DELETE_COPY(DyePalette) - - /** - * Gets a pixel color depending on its intensity. First color is - * implicitly black (0, 0, 0). - */ - void getColor(const unsigned int intensity, - unsigned int (&color)[3]) const; - - /** - * Gets a pixel color depending on its intensity. - */ - void getColor(double intensity, int (&color)[3]) const; - - /** - * replace colors for SDL for S dye. - */ - void replaceSColor(uint32_t *restrict pixels, const int bufSize) const; - - /** - * replace colors for SDL for S dye. - */ - void replaceAColor(uint32_t *restrict pixels, const int bufSize) const; - - /** - * replace colors for OpenGL for S dye. - */ - void replaceSOGLColor(uint32_t *restrict pixels, - const int bufSize) const; - - /** - * replace colors for OpenGL for A dye. - */ - void replaceAOGLColor(uint32_t *restrict pixels, - const int bufSize) const; - - static unsigned int hexDecode(const signed char c) A_WARN_UNUSED; - - private: - std::vector mColors; -}; - -#endif // RESOURCES_DYEPALETTE_H diff --git a/src/resources/imagehelper.cpp b/src/resources/imagehelper.cpp index 18e415972..c46c4e09c 100644 --- a/src/resources/imagehelper.cpp +++ b/src/resources/imagehelper.cpp @@ -24,8 +24,8 @@ #include "logger.h" -#include "resources/dye.h" -#include "resources/dyepalette.h" +#include "resources/dye/dye.h" +#include "resources/dye/dyepalette.h" #include "utils/sdlcheckutils.h" diff --git a/src/resources/openglimagehelper.cpp b/src/resources/openglimagehelper.cpp index 8cdf6beec..da6fba531 100644 --- a/src/resources/openglimagehelper.cpp +++ b/src/resources/openglimagehelper.cpp @@ -39,10 +39,11 @@ #include "render/opengl/mgl.h" #include "render/opengl/mglcheck.h" -#include "resources/dye.h" -#include "resources/dyepalette.h" #include "resources/image.h" +#include "resources/dye/dye.h" +#include "resources/dye/dyepalette.h" + #include "utils/sdlcheckutils.h" #include diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp index cf16c77d6..3b624a2a9 100644 --- a/src/resources/resourcemanager.cpp +++ b/src/resources/resourcemanager.cpp @@ -32,13 +32,14 @@ #include "resources/atlas/atlasmanager.h" #include "resources/atlas/atlasresource.h" #endif -#include "resources/dye.h" #include "resources/image.h" #include "resources/imagehelper.h" #include "resources/imageset.h" #include "resources/sdlmusic.h" #include "resources/soundeffect.h" +#include "resources/dye/dye.h" + #include "resources/sprite/spritedef.h" #include "utils/delete2.h" diff --git a/src/resources/safeopenglimagehelper.cpp b/src/resources/safeopenglimagehelper.cpp index da6b750dd..0f12a746f 100644 --- a/src/resources/safeopenglimagehelper.cpp +++ b/src/resources/safeopenglimagehelper.cpp @@ -36,10 +36,11 @@ #include "render/opengl/mgl.h" #include "render/opengl/mglcheck.h" -#include "resources/dye.h" -#include "resources/dyepalette.h" #include "resources/image.h" +#include "resources/dye/dye.h" +#include "resources/dye/dyepalette.h" + #include "utils/sdlcheckutils.h" #include diff --git a/src/resources/sdl2imagehelper.cpp b/src/resources/sdl2imagehelper.cpp index 41ce52cdd..184174bce 100644 --- a/src/resources/sdl2imagehelper.cpp +++ b/src/resources/sdl2imagehelper.cpp @@ -24,10 +24,11 @@ #include "resources/sdl2imagehelper.h" -#include "resources/dye.h" -#include "resources/dyepalette.h" #include "resources/resourcemanager.h" +#include "resources/dye/dye.h" +#include "resources/dye/dyepalette.h" + #include "logger.h" #include "main.h" diff --git a/src/resources/sdl2softwareimagehelper.cpp b/src/resources/sdl2softwareimagehelper.cpp index b8bd7f6f4..a28bea0c6 100644 --- a/src/resources/sdl2softwareimagehelper.cpp +++ b/src/resources/sdl2softwareimagehelper.cpp @@ -24,9 +24,10 @@ #include "resources/sdl2softwareimagehelper.h" -#include "resources/dye.h" #include "resources/resourcemanager.h" +#include "resources/dye/dye.h" + #include "logger.h" #include "main.h" diff --git a/src/resources/sdlimagehelper.cpp b/src/resources/sdlimagehelper.cpp index e0018b868..89bd36958 100644 --- a/src/resources/sdlimagehelper.cpp +++ b/src/resources/sdlimagehelper.cpp @@ -27,10 +27,11 @@ #include "logger.h" #include "main.h" -#include "resources/dye.h" -#include "resources/dyepalette.h" #include "resources/image.h" +#include "resources/dye/dye.h" +#include "resources/dye/dyepalette.h" + #include "utils/sdlcheckutils.h" #include diff --git a/src/resources/sprite/spritedef.cpp b/src/resources/sprite/spritedef.cpp index dda4a8378..42c076f5a 100644 --- a/src/resources/sprite/spritedef.cpp +++ b/src/resources/sprite/spritedef.cpp @@ -32,10 +32,11 @@ #include "resources/action.h" #include "resources/animation.h" -#include "resources/dye.h" #include "resources/imageset.h" #include "resources/resourcemanager.h" +#include "resources/dye/dye.h" + #include "resources/sprite/spritereference.h" #include "debug.h" diff --git a/src/resources/surfaceimagehelper.cpp b/src/resources/surfaceimagehelper.cpp index 9e31e9c6f..dbaf0516e 100644 --- a/src/resources/surfaceimagehelper.cpp +++ b/src/resources/surfaceimagehelper.cpp @@ -24,9 +24,10 @@ #include "resources/surfaceimagehelper.h" -#include "resources/dye.h" #include "resources/resourcemanager.h" +#include "resources/dye/dye.h" + #include "logger.h" #include "main.h" diff --git a/src/simpleanimation.cpp b/src/simpleanimation.cpp index 9a82fe9fa..877b51e7c 100644 --- a/src/simpleanimation.cpp +++ b/src/simpleanimation.cpp @@ -27,10 +27,11 @@ #include "render/graphics.h" #include "resources/animation.h" -#include "resources/dye.h" #include "resources/imageset.h" #include "resources/resourcemanager.h" +#include "resources/dye/dye.h" + #include "utils/delete2.h" #include "debug.h" diff --git a/src/test/testlauncher.cpp b/src/test/testlauncher.cpp index 7f8dc0d2a..6dc659685 100644 --- a/src/test/testlauncher.cpp +++ b/src/test/testlauncher.cpp @@ -37,8 +37,6 @@ #include "utils/physfscheckutils.h" #include "utils/physfsrwops.h" -#include "resources/dye.h" -#include "resources/dyepalette.h" #include "resources/image.h" #include "resources/imagewriter.h" #include "resources/mstack.h" @@ -47,6 +45,9 @@ #include "resources/surfaceimagehelper.h" #include "resources/wallpaper.h" +#include "resources/dye/dye.h" +#include "resources/dye/dyepalette.h" + #include #ifdef WIN32 -- cgit v1.2.3-60-g2f50