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 "asylum/puzzles/lock.h"
24
25 #include "asylum/resources/worldstats.h"
26
27 #include "asylum/system/cursor.h"
28 #include "asylum/system/graphics.h"
29 #include "asylum/system/screen.h"
30
31 #include "asylum/views/scene.h"
32
33 #include "asylum/asylum.h"
34
35 namespace Asylum {
36
37 const int16 puzzleLockPolygons[16][2] = {
38 {159, 293}, {151, 318}, {179, 322}, {185, 298},
39 {212, 303}, {207, 327}, {234, 332}, {239, 308},
40 {149, 333}, {146, 365}, {172, 369}, {176, 338},
41 {202, 345}, {200, 375}, {226, 379}, {231, 347}
42 };
43
PuzzleLock(AsylumEngine * engine)44 PuzzleLock::PuzzleLock(AsylumEngine *engine) : Puzzle(engine) {
45 memset(&_frameIndexes, 0, sizeof(_frameIndexes));
46 _frameIndexes[0] = _frameIndexes[1] = _frameIndexes[2] = 4;
47 _incrementLock = false;
48 _counter = 0;
49 memset(&_ticks, 0, sizeof(_ticks));
50 }
51
~PuzzleLock()52 PuzzleLock::~PuzzleLock() {
53 }
54
saveLoadWithSerializer(Common::Serializer & s)55 void PuzzleLock::saveLoadWithSerializer(Common::Serializer &s) {
56 s.syncAsSint32LE(_frameIndexes[0]);
57 s.syncAsSint32LE(_frameIndexes[1]);
58 s.syncAsSint32LE(_frameIndexes[2]);
59 }
60
61 //////////////////////////////////////////////////////////////////////////
62 // Event Handling
63 //////////////////////////////////////////////////////////////////////////
init(const AsylumEvent &)64 bool PuzzleLock::init(const AsylumEvent &) {
65 getScreen()->clear();
66
67 getScreen()->setPalette(getWorld()->graphicResourceIds[14]);
68 getScreen()->setGammaLevel(getWorld()->graphicResourceIds[14]);
69
70 _vm->setGameFlag(kGameFlag115);
71
72 getCursor()->set(getWorld()->graphicResourceIds[41], 0, kCursorAnimationNone);
73
74 return true;
75 }
76
update(const AsylumEvent &)77 bool PuzzleLock::update(const AsylumEvent &) {
78 updateCursor();
79
80 // Draw screen
81 getScreen()->clearGraphicsInQueue();
82 getScreen()->fillRect(0, 0, 640, 480, 252);
83 getScreen()->draw(getWorld()->graphicResourceIds[13], 0, Common::Point(0, 0), kDrawFlagNone, true);
84
85 if (_frameIndexes[0] != 32 || _frameIndexes[1] != 28 || _frameIndexes[2] != 0) {
86 getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[15], (uint32)_frameIndexes[0], Common::Point(145, 292), kDrawFlagNone, 0, 1);
87 getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[15], (uint32)_frameIndexes[1], Common::Point(173, 297), kDrawFlagNone, 0, 1);
88 getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[15], (uint32)_frameIndexes[2], Common::Point(201, 302), kDrawFlagNone, 0, 1);
89 getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[40], (uint32)_frameIndexes[3], Common::Point(337, 127), kDrawFlagNone, 0, 1);
90
91 if (_frameIndexes[4] != -1)
92 getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[42], (uint32)_frameIndexes[4], Common::Point(318, 102), kDrawFlagNone, 0, 1);
93
94 if (_frameIndexes[5] != -1)
95 getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[43], (uint32)_frameIndexes[5], Common::Point(318, 99), kDrawFlagNone, 0, 1);
96
97 getScreen()->drawGraphicsInQueue();
98 getScreen()->copyBackBufferToScreen();
99 } else {
100 if (_frameIndexes[6] == 5)
101 getSound()->playSound(getWorld()->soundResourceIds[15], false, Config.sfxVolume - 10);
102
103 getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[16], (uint32)_frameIndexes[6], Common::Point(0, 264), kDrawFlagNone, 0, 1);
104
105 ++_counter;
106
107 if (_counter > 9) {
108 ++_frameIndexes[6];
109
110 if (_frameIndexes[6] > 7) {
111 getCursor()->hide();
112 getSharedData()->setFlag(kFlag1, true);
113 _vm->setGameFlag(kGameFlag52);
114 getSound()->playSound(getWorld()->soundResourceIds[16], false, Config.sfxVolume - 10);
115 _frameIndexes[6] = 0;
116 _counter = 0;
117 getSharedData()->reset();
118
119 exitPuzzle();
120 } else {
121 getScreen()->drawGraphicsInQueue();
122 getScreen()->copyBackBufferToScreen();
123 _counter = 0;
124 }
125 }
126 }
127
128 // Update frame indexes
129 for (uint32 i = 0; i < 3; i++) {
130 if (_frameIndexes[i] % ~3 && _frameIndexes[i]) {
131 ++_counter;
132
133 if (_counter > 3) {
134 if (_incrementLock)
135 ++_frameIndexes[i];
136 else
137 --_frameIndexes[i];
138
139 if (_frameIndexes[i] < 0)
140 _frameIndexes[i] = 43;
141
142 if (_frameIndexes[i] > 43)
143 _frameIndexes[i] = 0;
144
145 _counter = 0;
146 }
147 }
148 }
149
150 for (uint32 i = 0; i < 2; i++) {
151 if (_frameIndexes[i + 4] == -1) {
152 _ticks[i] = _vm->getTick();
153
154 if (rnd(1000) < 10)
155 _frameIndexes[i + 4] = 0;
156 } else {
157 if (_vm->getTick() > _ticks[i] + 200) {
158 ++_frameIndexes[i + 4];
159
160 if (_frameIndexes[i + 4] > 24)
161 _frameIndexes[i + 4] = -1;
162
163 _ticks[i] = _vm->getTick();
164 }
165 }
166 }
167
168 if (_frameIndexes[3]) {
169 if (_vm->getTick() > _ticks[2] + 100) {
170 ++_frameIndexes[3];
171
172 if (_frameIndexes[3] > 15)
173 _frameIndexes[3] = 0;
174
175 _ticks[2] = _vm->getTick();
176 }
177 } else {
178 _ticks[2] = _vm->getTick();
179
180 if (rnd(1000) < 10)
181 _frameIndexes[3] = 1;
182 }
183
184 return true;
185 }
186
mouseLeftDown(const AsylumEvent & evt)187 bool PuzzleLock::mouseLeftDown(const AsylumEvent &evt) {
188 if (_frameIndexes[6])
189 return false;
190
191 Common::Point mousePos = evt.mouse;
192
193 for (uint32 i = 0; i < 3; i++) {
194 if (hitTest(&puzzleLockPolygons[0], mousePos, 8 + 2 * i)) {
195 if (!(_frameIndexes[i] % ~3))
196 getSound()->playSound(getWorld()->soundResourceIds[14], false, Config.sfxVolume - 10);
197
198 _incrementLock = true;
199
200 ++_frameIndexes[i];
201
202 if (_frameIndexes[i] > 43)
203 _frameIndexes[i] = 0;
204 }
205 }
206
207 for (uint32 i = 0; i < 3; i++) {
208 if (hitTest(&puzzleLockPolygons[0], mousePos, 2 * i)) {
209 if (!(_frameIndexes[i] % ~3))
210 getSound()->playSound(getWorld()->soundResourceIds[14], false, Config.sfxVolume - 10);
211
212 _incrementLock = false;
213
214 --_frameIndexes[i];
215
216 if (_frameIndexes[i] < 0)
217 _frameIndexes[i] = 43;
218 }
219 }
220
221 return true;
222 }
223
mouseRightDown(const AsylumEvent &)224 bool PuzzleLock::mouseRightDown(const AsylumEvent &) {
225 exitPuzzle();
226
227 return true;
228 }
229
230 //////////////////////////////////////////////////////////////////////////
231 // Helpers
232 //////////////////////////////////////////////////////////////////////////
updateCursor()233 void PuzzleLock::updateCursor() {
234 Common::Point mousePos = getCursor()->position();
235
236 for (uint32 i = 0; i < 6; i++) {
237 if (hitTest(&puzzleLockPolygons[0], mousePos, 2 * i)) {
238 if (getCursor()->getAnimation() != kCursorAnimationMirror)
239 getCursor()->set(getWorld()->graphicResourceIds[41]);
240
241 return ;
242 }
243 }
244
245 if (getCursor()->getAnimation() == kCursorAnimationMirror)
246 getCursor()->set(getWorld()->graphicResourceIds[41], 0, kCursorAnimationNone);
247 }
248
249 } // End of namespace Asylum
250