ManaPlus
palette.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2008 Douglas Boffey <[email protected]>
4  * Copyright (C) 2009 The Mana World Development Team
5  * Copyright (C) 2009-2010 The Mana Developers
6  * Copyright (C) 2011-2019 The ManaPlus Developers
7  * Copyright (C) 2019-2021 Andrei Karas
8  *
9  * This file is part of The ManaPlus Client.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <http://www.gnu.org/licenses/>.
23  */
24 
25 #include "gui/palette.h"
26 
27 #include "utils/foreach.h"
28 #include "utils/timer.h"
29 
30 #ifndef USE_SDL2
31 #include <cmath>
32 #endif // USE_SDL2
33 
34 #include "debug.h"
35 
36 const Color Palette::BLACK = Color(0, 0, 0, 255);
38 
40 {
41  Color(255, 0, 0, 255),
42  Color(255, 153, 0, 255),
43  Color(255, 255, 0, 255),
44  Color(0, 153, 0, 255),
45  Color(0, 204, 204, 255),
46  Color(51, 0, 153, 255),
47  Color(153, 0, 153, 255)
48 };
49 
50 const int Palette::RAINBOW_COLOR_COUNT = 7;
51 
52 Palette::Palette(const int size) :
53  mRainbowTime(tick_time),
55  mCharColors(),
56  mGradVector()
57 {
58  mInstances.insert(this);
59 }
60 
62 {
63  mInstances.erase(this);
64 }
65 
66 const Color& Palette::getCharColor(const signed char c, bool &valid) const
67 {
68  const CharColors::const_iterator it = mCharColors.find(c);
69  if (it != mCharColors.end())
70  {
71  valid = true;
72  return mColors[(*it).second].color;
73  }
74 
75  valid = false;
76  return BLACK;
77 }
78 
80 {
81  FOR_EACH (Palettes::const_iterator, it, mInstances)
82  (*it)->advanceGradient();
83 }
84 
86 {
87  const int time = get_elapsed_time(mRainbowTime);
88  if (time > 5)
89  {
90  // For slower systems, advance can be greater than one (advance > 1
91  // skips advance-1 steps). Should make gradient look the same
92  // independent of the framerate.
93  const int advance = time / 5;
94 
95  for (size_t i = 0, sz = mGradVector.size(); i < sz; i++)
96  {
97  ColorElem *const elem A_NONNULLPOINTER = mGradVector[i];
98  if (elem == nullptr)
99  continue;
100 
101  int delay = elem->delay;
102  const GradientTypeT &grad = elem->grad;
103 
104  if (grad == GradientType::PULSE)
105  delay = delay / 20;
106 
107  const int numOfColors = (elem->grad == GradientType::SPECTRUM ? 6 :
108  grad == GradientType::PULSE ? 127 :
110 
111  elem->gradientIndex = (elem->gradientIndex + advance)
112  % (delay * numOfColors);
113 
114  const int gradIndex = elem->gradientIndex;
115  const int pos = delay != 0 ? (gradIndex % delay) : gradIndex;
116  int colIndex;
117  if (delay != 0)
118  colIndex = gradIndex / delay;
119  else
120  colIndex = gradIndex;
121 
122  Color &color = elem->color;
123  int colVal;
124 
125  if (grad == GradientType::PULSE)
126  {
127  colVal = CAST_S32(255.0 *
128  sin(M_PI * colIndex / numOfColors));
129 
130  const Color &col = elem->testColor;
131 
132  color.r = ((colVal * col.r) / 255) % (col.r + 1);
133  color.g = ((colVal * col.g) / 255) % (col.g + 1);
134  color.b = ((colVal * col.b) / 255) % (col.b + 1);
135  }
136  else if (grad == GradientType::SPECTRUM)
137  {
138  if ((colIndex % 2) != 0)
139  { // falling curve
140  if (delay != 0)
141  {
142  colVal = CAST_S32(255.0 *
143  (cos(M_PI * pos / delay) + 1) / 2);
144  }
145  else
146  {
147  colVal = CAST_S32(255.0 *
148  (cos(M_PI * pos) + 1) / 2);
149  }
150  }
151  else
152  { // ascending curve
153  if (delay != 0)
154  {
155  colVal = CAST_S32(255.0 * (cos(M_PI *
156  (delay - pos) / delay) + 1) / 2);
157  }
158  else
159  {
160  colVal = CAST_S32(255.0 * (cos(M_PI *
161  (delay - pos)) + 1) / 2);
162  }
163  }
164 
165  color.r = (colIndex == 0 || colIndex == 5) ? 255 :
166  (colIndex == 1 || colIndex == 4) ? colVal : 0;
167  color.g = (colIndex == 1 || colIndex == 2) ? 255 :
168  (colIndex == 0 || colIndex == 3) ? colVal : 0;
169  color.b = (colIndex == 3 || colIndex == 4) ? 255 :
170  (colIndex == 2 || colIndex == 5) ? colVal : 0;
171  }
172  else if (elem->grad == GradientType::RAINBOW)
173  {
174  const Color &startCol = RAINBOW_COLORS[colIndex];
175  const Color &destCol
176  = RAINBOW_COLORS[(colIndex + 1) % numOfColors];
177  double startColVal;
178  double destColVal;
179 
180  if (delay != 0)
181  startColVal = (cos(M_PI * pos / delay) + 1) / 2;
182  else
183  startColVal = 0;
184 
185  destColVal = 1 - startColVal;
186 
187  color.r = CAST_S32(startColVal
188  * startCol.r + destColVal * destCol.r);
189 
190  color.g = CAST_S32(startColVal
191  * startCol.g + destColVal * destCol.g);
192 
193  color.b = CAST_S32(startColVal
194  * startCol.b + destColVal * destCol.b);
195  }
196  }
197 
199  }
200 }
#define CAST_S32
Definition: cast.h:30
Definition: color.h:76
unsigned int b
Definition: color.h:245
unsigned int r
Definition: color.h:235
unsigned int g
Definition: color.h:240
Colors mColors
Definition: palette.h:154
Palette(const int size)
Definition: palette.cpp:52
void advanceGradient()
Definition: palette.cpp:85
virtual ~Palette()
Definition: palette.cpp:61
const Color & getCharColor(const signed char c, bool &valid) const
Definition: palette.cpp:66
std::set< Palette * > Palettes
Definition: palette.h:87
static const Color RAINBOW_COLORS[7]
Definition: palette.h:81
static const int RAINBOW_COLOR_COUNT
Definition: palette.h:82
static Palettes mInstances
Definition: palette.h:88
static void advanceGradients()
Definition: palette.cpp:79
CharColors mCharColors
Definition: palette.h:155
static const Color BLACK
Definition: palette.h:48
std::vector< ColorElem * > mGradVector
Definition: palette.h:156
int mRainbowTime
Definition: palette.h:85
std::vector< ColorElem > Colors
Definition: palette.h:152
#define FOR_EACH(type, iter, array)
Definition: foreach.h:25
GradientType ::T GradientTypeT
Definition: gradienttype.h:38
#define A_NONNULLPOINTER
Definition: localconsts.h:266
volatile int tick_time
Definition: timer.cpp:53
int size()
Definition: emotedb.cpp:306
std::map< std::string, DyeColor > mColors
Definition: palettedb.cpp:37
int get_elapsed_time(const int startTime)
Definition: timer.cpp:94