GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/palette.cpp Lines: 9 79 11.4 %
Date: 2017-11-29 Branches: 0 46 0.0 %

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