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); |
37 |
|
1 |
Palette::Palettes Palette::mInstances; |
38 |
|
|
|
39 |
|
|
const Color Palette::RAINBOW_COLORS[7] = |
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 |
|
363 |
Palette::Palette(const int size) : |
53 |
|
|
mRainbowTime(tick_time), |
54 |
|
|
mColors(Colors(size)), |
55 |
|
|
mCharColors(), |
56 |
|
1815 |
mGradVector() |
57 |
|
|
{ |
58 |
|
726 |
mInstances.insert(this); |
59 |
|
363 |
} |
60 |
|
|
|
61 |
|
1400 |
Palette::~Palette() |
62 |
|
|
{ |
63 |
|
700 |
mInstances.erase(this); |
64 |
|
350 |
} |
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 |
|
|
|
79 |
|
|
void Palette::advanceGradients() |
80 |
|
|
{ |
81 |
|
|
FOR_EACH (Palettes::const_iterator, it, mInstances) |
82 |
|
|
(*it)->advanceGradient(); |
83 |
|
|
} |
84 |
|
|
|
85 |
|
|
void Palette::advanceGradient() |
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 : |
109 |
|
|
RAINBOW_COLOR_COUNT); |
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 |
|
|
|
198 |
|
|
mRainbowTime = tick_time; |
199 |
|
|
} |
200 |
|
2 |
} |