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.0005f;
31 const float CloudIcon::ALPHA_MAX = 1.f;
32 const float CloudIcon::ALPHA_MIN = 0.6f;
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(true) - _lastUpdateTime;
79 return delaySinceLastUpdate >= UPDATE_DELAY_MIN_MILLIS;
80 }
81
update()82 void CloudIcon::update() {
83 uint32 currentTime = g_system->getMillis(true);
84 uint32 delaySinceLastUpdate = currentTime - _lastUpdateTime;
85 _lastUpdateTime = currentTime;
86
87 switch (_state) {
88 default:
89 // fallthrough intended
90 case kHidden:
91 return; // Nothing to do
92 case kShown:
93 if (_alphaRising) {
94 if (_currentAlpha < ALPHA_MIN)
95 _currentAlpha += 5 * ALPHA_SPEED * delaySinceLastUpdate;
96 else
97 _currentAlpha += ALPHA_SPEED * delaySinceLastUpdate;
98 if (_currentAlpha > ALPHA_MAX) {
99 _currentAlpha = ALPHA_MAX;
100 _alphaRising = false;
101 }
102 } else {
103 _currentAlpha -= ALPHA_SPEED * delaySinceLastUpdate;
104 if (_currentAlpha < ALPHA_MIN) {
105 _currentAlpha = ALPHA_MIN;
106 _alphaRising = true;
107 }
108 }
109
110 if (_hideTime != 0 && _hideTime <= currentTime) {
111 _hideTime = 0;
112 _state = kGoingToHide;
113 }
114 break;
115 case kGoingToHide:
116 _currentAlpha -= 5 * ALPHA_SPEED * delaySinceLastUpdate;
117 if (_currentAlpha <= 0) {
118 hide();
119 }
120 break;
121 }
122
123 if (!_icon.getPixels() || !_disabledIcon.getPixels()) {
124 // Loading the icons failed. Don't try to draw them.
125 return;
126 }
127
128 if (_state != kHidden) {
129 makeAlphaIcon((_type == kDisabled ? _disabledIcon : _icon), _currentAlpha);
130 g_system->displayActivityIconOnOSD(&_alphaIcon);
131 } else {
132 g_system->displayActivityIconOnOSD(nullptr);
133 }
134 }
135
136 #include "backends/cloud/cloudicon_data.h"
137 #include "backends/cloud/cloudicon_disabled_data.h"
138
initIcons()139 void CloudIcon::initIcons() {
140 loadIcon(_icon, cloudicon_data, ARRAYSIZE(cloudicon_data));
141 loadIcon(_disabledIcon, cloudicon_disabled_data, ARRAYSIZE(cloudicon_disabled_data));
142 }
143
loadIcon(Graphics::Surface & icon,byte * data,uint32 size)144 void CloudIcon::loadIcon(Graphics::Surface &icon, byte *data, uint32 size) {
145 Image::PNGDecoder decoder;
146 Common::MemoryReadStream stream(data, size);
147 if (!decoder.loadStream(stream)) {
148 warning("CloudIcon::loadIcon: error decoding PNG");
149 return;
150 }
151
152 const Graphics::Surface *s = decoder.getSurface();
153 icon.copyFrom(*s);
154 }
155
makeAlphaIcon(const Graphics::Surface & icon,float alpha)156 void CloudIcon::makeAlphaIcon(const Graphics::Surface &icon, float alpha) {
157 _alphaIcon.copyFrom(icon);
158
159 byte *pixels = (byte *)_alphaIcon.getPixels();
160 for (int y = 0; y < _alphaIcon.h; y++) {
161 byte *row = pixels + y * _alphaIcon.pitch;
162 for (int x = 0; x < _alphaIcon.w; x++) {
163 uint32 srcColor;
164 if (_alphaIcon.format.bytesPerPixel == 2)
165 srcColor = READ_UINT16(row);
166 else if (_alphaIcon.format.bytesPerPixel == 3)
167 srcColor = READ_UINT24(row);
168 else
169 srcColor = READ_UINT32(row);
170
171 // Update color's alpha
172 byte r, g, b, a;
173 _alphaIcon.format.colorToARGB(srcColor, a, r, g, b);
174 a = (byte)(a * alpha);
175 uint32 color = _alphaIcon.format.ARGBToColor(a, r, g, b);
176
177 if (_alphaIcon.format.bytesPerPixel == 2)
178 *((uint16 *)row) = color;
179 else
180 *((uint32 *)row) = color;
181
182 row += _alphaIcon.format.bytesPerPixel;
183 }
184 }
185 }
186
187 } // End of namespace Cloud
188