1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "backends/cloud/cloudicon.h"
24 #include "common/memstream.h"
25 #include "common/system.h"
26 #include "image/png.h"
27
28 namespace Cloud {
29
30 const float CloudIcon::ALPHA_SPEED = 0.0005;
31 const float CloudIcon::ALPHA_MAX = 1;
32 const float CloudIcon::ALPHA_MIN = 0.6;
33
CloudIcon()34 CloudIcon::CloudIcon() {
35 initIcons();
36 hide();
37 _lastUpdateTime = g_system->getMillis();
38 }
39
~CloudIcon()40 CloudIcon::~CloudIcon() {
41 _icon.free();
42 _disabledIcon.free();
43 _alphaIcon.free();
44 }
45
show(CloudIcon::Type icon,int duration)46 void CloudIcon::show(CloudIcon::Type icon, int duration) {
47 if (_type == icon) {
48 return; // Nothing to do
49 }
50
51 if (icon != kNone) {
52 _state = kShown;
53 _type = icon;
54
55 if (duration) {
56 _hideTime = g_system->getMillis() + duration;
57 } else {
58 _hideTime = 0;
59 }
60 } else {
61 _state = kGoingToHide;
62 }
63 }
64
hide()65 void CloudIcon::hide() {
66 _state = kHidden;
67 _type = kNone;
68 _hideTime = 0;
69 _currentAlpha = 0;
70 _alphaRising = true;
71 }
72
getShownType() const73 CloudIcon::Type CloudIcon::getShownType() const {
74 return _type;
75 }
76
needsUpdate() const77 bool CloudIcon::needsUpdate() const {
78 uint32 delaySinceLastUpdate = g_system->getMillis() - _lastUpdateTime;
79 return delaySinceLastUpdate >= UPDATE_DELAY_MIN_MILLIS;
80 }
81
update()82 void CloudIcon::update() {
83 uint32 currentTime = g_system->getMillis();
84 uint32 delaySinceLastUpdate = currentTime - _lastUpdateTime;
85 _lastUpdateTime = currentTime;
86
87 switch (_state) {
88 case kHidden:
89 return; // Nothing to do
90 case kShown:
91 if (_alphaRising) {
92 if (_currentAlpha < ALPHA_MIN)
93 _currentAlpha += 5 * ALPHA_SPEED * delaySinceLastUpdate;
94 else
95 _currentAlpha += ALPHA_SPEED * delaySinceLastUpdate;
96 if (_currentAlpha > ALPHA_MAX) {
97 _currentAlpha = ALPHA_MAX;
98 _alphaRising = false;
99 }
100 } else {
101 _currentAlpha -= ALPHA_SPEED * delaySinceLastUpdate;
102 if (_currentAlpha < ALPHA_MIN) {
103 _currentAlpha = ALPHA_MIN;
104 _alphaRising = true;
105 }
106 }
107
108 if (_hideTime != 0 && _hideTime <= currentTime) {
109 _hideTime = 0;
110 _state = kGoingToHide;
111 }
112 break;
113 case kGoingToHide:
114 _currentAlpha -= 5 * ALPHA_SPEED * delaySinceLastUpdate;
115 if (_currentAlpha <= 0) {
116 hide();
117 }
118 break;
119 }
120
121 if (!_icon.getPixels() || !_disabledIcon.getPixels()) {
122 // Loading the icons failed. Don't try to draw them.
123 return;
124 }
125
126 if (_state != kHidden) {
127 makeAlphaIcon((_type == kDisabled ? _disabledIcon : _icon), _currentAlpha);
128 g_system->displayActivityIconOnOSD(&_alphaIcon);
129 } else {
130 g_system->displayActivityIconOnOSD(nullptr);
131 }
132 }
133
134 #include "backends/cloud/cloudicon_data.h"
135 #include "backends/cloud/cloudicon_disabled_data.h"
136
initIcons()137 void CloudIcon::initIcons() {
138 loadIcon(_icon, cloudicon_data, ARRAYSIZE(cloudicon_data));
139 loadIcon(_disabledIcon, cloudicon_disabled_data, ARRAYSIZE(cloudicon_disabled_data));
140 }
141
loadIcon(Graphics::Surface & icon,byte * data,uint32 size)142 void CloudIcon::loadIcon(Graphics::Surface &icon, byte *data, uint32 size) {
143 Image::PNGDecoder decoder;
144 Common::MemoryReadStream stream(data, size);
145 if (!decoder.loadStream(stream)) {
146 warning("CloudIcon::loadIcon: error decoding PNG");
147 return;
148 }
149
150 const Graphics::Surface *s = decoder.getSurface();
151 icon.copyFrom(*s);
152 }
153
makeAlphaIcon(const Graphics::Surface & icon,float alpha)154 void CloudIcon::makeAlphaIcon(const Graphics::Surface &icon, float alpha) {
155 _alphaIcon.copyFrom(icon);
156
157 byte *pixels = (byte *)_alphaIcon.getPixels();
158 for (int y = 0; y < _alphaIcon.h; y++) {
159 byte *row = pixels + y * _alphaIcon.pitch;
160 for (int x = 0; x < _alphaIcon.w; x++) {
161 uint32 srcColor;
162 if (_alphaIcon.format.bytesPerPixel == 2)
163 srcColor = READ_UINT16(row);
164 else if (_alphaIcon.format.bytesPerPixel == 3)
165 srcColor = READ_UINT24(row);
166 else
167 srcColor = READ_UINT32(row);
168
169 // Update color's alpha
170 byte r, g, b, a;
171 _alphaIcon.format.colorToARGB(srcColor, a, r, g, b);
172 a = (byte)(a * alpha);
173 uint32 color = _alphaIcon.format.ARGBToColor(a, r, g, b);
174
175 if (_alphaIcon.format.bytesPerPixel == 2)
176 *((uint16 *)row) = color;
177 else
178 *((uint32 *)row) = color;
179
180 row += _alphaIcon.format.bytesPerPixel;
181 }
182 }
183 }
184
185 } // End of namespace Cloud
186