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 /*
24  * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
25  * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
26  */
27 
28 /* Original name: TIMEOUT	The scheduling unit. */
29 
30 #include "avalanche/avalanche.h"
31 #include "avalanche/timer.h"
32 
33 namespace Avalanche {
34 
Timer(AvalancheEngine * vm)35 Timer::Timer(AvalancheEngine *vm) {
36 	_vm = vm;
37 
38 	resetVariables();
39 }
40 
41 /**
42  * Add a nex timer
43  * @remarks	Originally called 'set_up_timer'
44  */
addTimer(int32 duration,byte action,byte reason)45 void Timer::addTimer(int32 duration, byte action, byte reason) {
46 	byte i = 0;
47 	while ((i < 7) && (_times[i]._timeLeft != 0)) {
48 		if (_times[i]._reason == reason) // We only add a timer if it's not already in the array.
49 			return;
50 		i++;
51 	}
52 
53 	if (i == 7)
54 		return; // Oh dear... No timer left
55 
56 	// Everything's OK here!
57 	_times[i]._timeLeft = duration;
58 	_times[i]._action = action;
59 	_times[i]._reason = reason;
60 }
61 
62 /**
63  * Update the timers
64  * @remarks	Originally called 'one_tick'
65  */
updateTimer()66 void Timer::updateTimer() {
67 	if (_vm->_dropdown->isActive())
68 		return;
69 
70 	for (int i = 0; i < 7; i++) {
71 		if (_times[i]._timeLeft <= 0)
72 			continue;
73 
74 		_times[i]._timeLeft--;
75 
76 		if (_times[i]._timeLeft == 0) {
77 			switch (_times[i]._action) {
78 			case kProcOpenDrawbridge :
79 				openDrawbridge();
80 				break;
81 			case kProcAvariciusTalks :
82 				avariciusTalks();
83 				break;
84 			case kProcUrinate :
85 				urinate();
86 				break;
87 			case kProcToilet :
88 				toilet();
89 				break;
90 			case kProcBang:
91 				bang();
92 				break;
93 			case kProcBang2:
94 				bang2();
95 				break;
96 			case kProcStairs:
97 				stairs();
98 				break;
99 			case kProcCardiffSurvey:
100 				cardiffSurvey();
101 				break;
102 			case kProcCardiffReturn:
103 				cardiffReturn();
104 				break;
105 			case kProcCwytalotInHerts:
106 				cwytalotInHerts();
107 				break;
108 			case kProcGetTiedUp:
109 				getTiedUp();
110 				break;
111 			case kProcGetTiedUp2:
112 				getTiedUp2();
113 				break;
114 			case kProcHangAround:
115 				hangAround();
116 				break;
117 			case kProcHangAround2:
118 				hangAround2();
119 				break;
120 			case kProcAfterTheShootemup:
121 				afterTheShootemup();
122 				break;
123 			case kProcJacquesWakesUp:
124 				jacquesWakesUp();
125 				break;
126 			case kProcNaughtyDuke:
127 				naughtyDuke();
128 				break;
129 			case kProcNaughtyDuke2:
130 				naughtyDuke2();
131 				break;
132 			case kProcNaughtyDuke3:
133 				naughtyDuke3();
134 				break;
135 			case kProcJump:
136 				jump();
137 				break;
138 			case kProcSequence:
139 				_vm->_sequence->callSequencer();
140 				break;
141 			case kProcCrapulusSpludOut:
142 				crapulusSaysSpludOut();
143 				break;
144 			case kProcDawnDelay:
145 				_vm->fadeIn();
146 				break;
147 			case kProcBuyDrinks:
148 				buyDrinks();
149 				break;
150 			case kProcBuyWine:
151 				buyWine();
152 				break;
153 			case kProcCallsGuards:
154 				callsGuards();
155 				break;
156 			case kProcGreetsMonk:
157 				greetsMonk();
158 				break;
159 			case kProcFallDownOubliette:
160 				fallDownOubliette();
161 				break;
162 			case kProcMeetAvaroid:
163 				meetAvaroid();
164 				break;
165 			case kProcRiseUpOubliette:
166 				riseUpOubliette();
167 				break;
168 			case kProcRobinHoodAndGeida:
169 				robinHoodAndGeida();
170 				break;
171 			case kProcRobinHoodAndGeidaTalk:
172 				robinHoodAndGeidaTalk();
173 				break;
174 			case kProcAvalotReturns:
175 				avalotReturns();
176 				break;
177 			case kProcAvvySitDown:
178 				avvySitDown();
179 				break;
180 			case kProcGhostRoomPhew:
181 				ghostRoomPhew();
182 				break;
183 			case kProcArkataShouts:
184 				arkataShouts();
185 				break;
186 			case kProcWinning:
187 				winning();
188 				break;
189 			case kProcAvalotFalls:
190 				avalotFalls();
191 				break;
192 			case kProcSpludwickGoesToCauldron:
193 				spludwickGoesToCauldron();
194 				break;
195 			case kProcSpludwickLeavesCauldron:
196 				spludwickLeavesCauldron();
197 				break;
198 			case kProcGiveLuteToGeida:
199 				giveLuteToGeida();
200 				break;
201 			}
202 		}
203 	}
204 
205 	_vm->_roomCycles++; // Cycles since you've been in this room.
206 }
207 
loseTimer(byte which)208 void Timer::loseTimer(byte which) {
209 	for (int i = 0; i < 7; i++) {
210 		if (_times[i]._reason == which)
211 			_times[i]._timeLeft = 0; // Cancel this one!
212 	}
213 
214 }
215 
openDrawbridge()216 void Timer::openDrawbridge() {
217 	_vm->_drawbridgeOpen++;
218 	_vm->_background->draw(-1, -1, _vm->_drawbridgeOpen - 2);
219 
220 	if (_vm->_drawbridgeOpen == 4)
221 		_vm->_magics[1]._operation = kMagicNothing; // You may enter the drawbridge.
222 	else
223 		addTimer(7, kProcOpenDrawbridge, kReasonDrawbridgeFalls);
224 }
225 
avariciusTalks()226 void Timer::avariciusTalks() {
227 	_vm->_dialogs->displayScrollChain('Q', _vm->_avariciusTalk);
228 	_vm->_avariciusTalk++;
229 
230 	if (_vm->_avariciusTalk < 17)
231 		addTimer(177, kProcAvariciusTalks, kReasonAvariciusTalks);
232 	else
233 		_vm->incScore(3);
234 }
235 
urinate()236 void Timer::urinate() {
237 	_vm->_animation->_sprites[0]->turn(kDirUp);
238 	_vm->_animation->stopWalking();
239 	_vm->drawDirection();
240 	addTimer(14, kProcToilet, kReasonGoToToilet);
241 }
242 
toilet()243 void Timer::toilet() {
244 	_vm->_dialogs->displayText("That's better!");
245 }
246 
bang()247 void Timer::bang() {
248 	Common::String tmpStr = Common::String::format("%c< BANG! >", kControlItalic);
249 	_vm->_dialogs->displayText(tmpStr);
250 	addTimer(30, kProcBang2, kReasonExplosion);
251 }
252 
bang2()253 void Timer::bang2() {
254 	_vm->_dialogs->displayText("Hmm... sounds like Spludwick's up to something...");
255 }
256 
stairs()257 void Timer::stairs() {
258 	_vm->_sound->blip();
259 	_vm->_animation->_sprites[0]->walkTo(3);
260 	_vm->_background->draw(-1, -1, 1);
261 	_vm->_brummieStairs = 2;
262 	_vm->_magics[10]._operation = kMagicSpecial;
263 	_vm->_magics[10]._data = 2; // Reached the bottom of the stairs.
264 	_vm->_magics[3]._operation = kMagicNothing; // Stop them hitting the sides (or the game will hang.)
265 }
266 
cardiffSurvey()267 void Timer::cardiffSurvey() {
268 	if (_vm->_cardiffQuestionNum == 0) {
269 		_vm->_cardiffQuestionNum++;
270 		_vm->_dialogs->displayScrollChain('Q', 27);
271 	}
272 
273 	_vm->_dialogs->displayScrollChain('Z', _vm->_cardiffQuestionNum);
274 	_vm->_interrogation = _vm->_cardiffQuestionNum;
275 	addTimer(182, kProcCardiffSurvey, kReasonCardiffsurvey);
276 }
277 
cardiffReturn()278 void Timer::cardiffReturn() {
279 	_vm->_dialogs->displayScrollChain('Q', 28);
280 	cardiffSurvey(); // Add end of question.
281 }
282 
cwytalotInHerts()283 void Timer::cwytalotInHerts() {
284 	_vm->_dialogs->displayScrollChain('Q', 29);
285 }
286 
getTiedUp()287 void Timer::getTiedUp() {
288 	_vm->_dialogs->displayScrollChain('Q', 34); // ...Trouble!
289 	_vm->_userMovesAvvy = false;
290 	_vm->_beenTiedUp = true;
291 	_vm->_animation->stopWalking();
292 
293 	AnimationType *spr = _vm->_animation->_sprites[1];
294 	spr->stopWalk();
295 	spr->stopHoming();
296 	spr->_callEachStepFl = true;
297 	spr->_eachStepProc = Animation::kProcGrabAvvy;
298 	addTimer(70, kProcGetTiedUp2, kReasonGettingTiedUp);
299 }
300 
getTiedUp2()301 void Timer::getTiedUp2() {
302 	_vm->_animation->_sprites[0]->walkTo(3);
303 	_vm->_animation->_sprites[1]->walkTo(4);
304 	_vm->_magics[3]._operation = kMagicNothing; // No effect when you touch the boundaries.
305 	_vm->_friarWillTieYouUp = true;
306 }
307 
hangAround()308 void Timer::hangAround() {
309 	_vm->_animation->_sprites[1]->_doCheck = false;
310 
311 	AnimationType *avvy = _vm->_animation->_sprites[0];
312 	avvy->init(7, true); // Robin Hood
313 	_vm->setRoom(kPeopleRobinHood, kRoomRobins);
314 	_vm->_animation->appearPed(0, 1);
315 	_vm->_dialogs->displayScrollChain('Q', 39);
316 	avvy->walkTo(6);
317 	addTimer(55, kProcHangAround2, kReasonHangingAround);
318 }
319 
hangAround2()320 void Timer::hangAround2() {
321 	_vm->_dialogs->displayScrollChain('Q', 40);
322 	AnimationType *spr = _vm->_animation->_sprites[1];
323 	spr->_vanishIfStill = false;
324 	spr->walkTo(3);
325 	_vm->setRoom(kPeopleFriarTuck, kRoomRobins);
326 	_vm->_dialogs->displayScrollChain('Q', 41);
327 	_vm->_animation->_sprites[0]->remove();
328 	spr->remove(); // Get rid of Robin Hood and Friar Tuck.
329 
330 	addTimer(1, kProcAfterTheShootemup, kReasonHangingAround); // Immediately call the following proc (when you have a chance).
331 
332 	_vm->_tiedUp = false;
333 
334 	// We don't need the ShootEmUp during the whole game, it's only playable once.
335 	ShootEmUp *shootemup = new ShootEmUp(_vm);
336 	_shootEmUpScore = shootemup->run();
337 	delete shootemup;
338 }
339 
afterTheShootemup()340 void Timer::afterTheShootemup() {
341 	_vm->flipRoom(_vm->_room, 1);
342 
343 	_vm->_animation->_sprites[0]->init(0, true); // Avalot.
344 	_vm->_animation->appearPed(0, 1);
345 	_vm->_userMovesAvvy = true;
346 	_vm->_objects[kObjectCrossbow - 1] = true;
347 	_vm->refreshObjectList();
348 
349 	byte gain = (_shootEmUpScore + 5) / 10; // Rounding up.
350 	_vm->_dialogs->displayText(Common::String::format("%cYour score was %d.%c%cYou gain (%d \xf6 10) = %d points.", kControlItalic, _shootEmUpScore, kControlNewLine, kControlNewLine, _shootEmUpScore, gain));
351 
352 	if (gain > 20) {
353 		_vm->_dialogs->displayText("But we won't let you have more than 20 points!");
354 		_vm->incScore(20);
355 	} else
356 		_vm->incScore(gain);
357 
358 
359 	_vm->_dialogs->displayScrollChain('Q', 70);
360 }
361 
jacquesWakesUp()362 void Timer::jacquesWakesUp() {
363 	_vm->_jacquesState++;
364 
365 	switch (_vm->_jacquesState) { // Additional pictures.
366 	case 1 :
367 		_vm->_background->draw(-1, -1, 0); // Eyes open.
368 		_vm->_dialogs->displayScrollChain('Q', 45);
369 		break;
370 	case 2 : // Going through the door.
371 		_vm->_background->draw(-1, -1, 1); // Not on the floor.
372 		_vm->_background->draw(-1, -1, 2); // But going through the door.
373 		_vm->_magics[5]._operation = kMagicNothing; // You can't wake him up now.
374 		break;
375 	case 3 :  // Gone through the door.
376 		_vm->_background->draw(-1, -1, 1); // Not on the floor, either.
377 		_vm->_background->draw(-1, -1, 3); // He's gone... so the door's open.
378 		_vm->setRoom(kPeopleJacques, kRoomNowhere); // Gone!
379 		break;
380 	}
381 
382 	if (_vm->_jacquesState == 5) {
383 		_vm->_bellsAreRinging = true;
384 		_vm->_aylesIsAwake = true;
385 		_vm->incScore(2);
386 	}
387 
388 	switch (_vm->_jacquesState) {
389 	case 1:
390 	case 2:
391 	case 3:
392 		addTimer(12, kProcJacquesWakesUp, kReasonJacquesWakingUp);
393 		break;
394 	case 4:
395 		addTimer(24, kProcJacquesWakesUp, kReasonJacquesWakingUp);
396 		break;
397 	}
398 }
399 
naughtyDuke()400 void Timer::naughtyDuke() { // This is when the Duke comes in and takes your money.
401 	AnimationType *spr = _vm->_animation->_sprites[1];
402 	spr->init(9, false); // Here comes the Duke.
403 	_vm->_animation->appearPed(1, 0); // He starts at the door...
404 	spr->walkTo(2); // He walks over to you.
405 
406 	// Let's get the door opening.
407 	_vm->_background->draw(-1, -1, 0);
408 	_vm->_sequence->startNaughtyDukeSeq();
409 
410 	addTimer(50, kProcNaughtyDuke2, kReasonNaughtyDuke);
411 }
412 
naughtyDuke2()413 void Timer::naughtyDuke2() {
414 	AnimationType *spr = _vm->_animation->_sprites[1];
415 	_vm->_dialogs->displayScrollChain('Q', 48); // "Ha ha, it worked again!"
416 	spr->walkTo(0); // Walk to the door.
417 	spr->_vanishIfStill = true; // Then go away!
418 
419 	addTimer(32, kProcNaughtyDuke3, kReasonNaughtyDuke);
420 }
421 
naughtyDuke3()422 void Timer::naughtyDuke3() {
423 	_vm->_background->draw(-1, -1, 0);
424 	_vm->_sequence->startNaughtyDukeSeq();
425 }
426 
jump()427 void Timer::jump() {
428 	AnimationType *avvy = _vm->_animation->_sprites[0];
429 
430 	_vm->_jumpStatus++;
431 	switch (_vm->_jumpStatus) {
432 	case 1:
433 	case 2:
434 	case 3:
435 	case 5:
436 	case 7:
437 	case 9:
438 		avvy->_y--;
439 		break;
440 	case 12:
441 	case 13:
442 	case 14:
443 	case 16:
444 	case 18:
445 	case 19:
446 		avvy->_y++;
447 		break;
448 	}
449 
450 	if (_vm->_jumpStatus == 20) { // End of jump.
451 		_vm->_userMovesAvvy = true;
452 		_vm->_jumpStatus = 0;
453 	} else // Still jumping.
454 		addTimer(1, kProcJump, kReasonJumping);
455 
456 	if ((_vm->_jumpStatus == 10) // You're at the highest point of your jump.
457 			&& (_vm->_room == kRoomInsideCardiffCastle)
458 			&& (_vm->_arrowInTheDoor == true)
459 			&& (_vm->_animation->inField(2))) { // Beside the wall
460 		// Grab the arrow!
461 		if (_vm->_carryNum >= kCarryLimit)
462 			_vm->_dialogs->displayText("You fail to grab it, because your hands are full.");
463 		else {
464 			_vm->_background->draw(-1, -1, 1);
465 			_vm->_arrowInTheDoor = false; // You've got it.
466 			_vm->_objects[kObjectBolt - 1] = true;
467 			_vm->refreshObjectList();
468 			_vm->_dialogs->displayScrollChain('Q', 50);
469 			_vm->incScore(3);
470 		}
471 	}
472 }
473 
crapulusSaysSpludOut()474 void Timer::crapulusSaysSpludOut() {
475 	_vm->_dialogs->displayScrollChain('Q', 56);
476 	_vm->_crapulusWillTell = false;
477 }
478 
buyDrinks()479 void Timer::buyDrinks() {
480 	_vm->_background->draw(-1, -1, 10); // Malagauche gets up again.
481 	_vm->_malagauche = 0;
482 
483 	_vm->_dialogs->displayScrollChain('D', _vm->_drinking); // Display message about it.
484 	_vm->_animation->wobble(); // Do the special effects.
485 	_vm->_dialogs->displayScrollChain('D', 1); // That'll be thruppence.
486 	if (_vm->decreaseMoney(3)) // Pay 3d.
487 		_vm->_dialogs->displayScrollChain('D', 3); // Tell 'em you paid up.
488 	_vm->_parser->drink();
489 }
490 
buyWine()491 void Timer::buyWine() {
492 	_vm->_background->draw(-1, -1, 10); // Malagauche gets up again.
493 	_vm->_malagauche = 0;
494 
495 	_vm->_dialogs->displayScrollChain('D', 50); // You buy the wine.
496 	_vm->_dialogs->displayScrollChain('D', 1); // It'll be thruppence.
497 	if (_vm->decreaseMoney(3)) {
498 		_vm->_dialogs->displayScrollChain('D', 4); // You paid up.
499 		_vm->_objects[kObjectWine - 1] = true;
500 		_vm->refreshObjectList();
501 		_vm->_wineState = 1; // OK Wine.
502 	}
503 }
504 
callsGuards()505 void Timer::callsGuards() {
506 	_vm->_dialogs->displayScrollChain('Q', 58); // "GUARDS!!!"
507 	_vm->gameOver();
508 }
509 
greetsMonk()510 void Timer::greetsMonk() {
511 	_vm->_dialogs->displayScrollChain('Q', 59);
512 	_vm->_enteredLustiesRoomAsMonk = true;
513 }
514 
fallDownOubliette()515 void Timer::fallDownOubliette() {
516 	_vm->_magics[8]._operation = kMagicNothing;
517 
518 	AnimationType *avvy = _vm->_animation->_sprites[0];
519 	avvy->_moveY++; // Increments dx/dy!
520 	avvy->_y += avvy->_moveY;   // Dowwwn we go...
521 	addTimer(3, kProcFallDownOubliette, kReasonFallingDownOubliette);
522 }
523 
meetAvaroid()524 void Timer::meetAvaroid() {
525 	if (_vm->_metAvaroid) {
526 		Common::String tmpStr = Common::String::format("You can't expect to be %cthat%c lucky twice in a row!",
527 			kControlItalic, kControlRoman);
528 		_vm->_dialogs->displayText(tmpStr);
529 		_vm->gameOver();
530 	} else {
531 		_vm->_dialogs->displayScrollChain('Q', 60);
532 		_vm->_metAvaroid = true;
533 		addTimer(1, kProcRiseUpOubliette, kReasonRisingUpOubliette);
534 
535 		AnimationType *avvy = _vm->_animation->_sprites[0];
536 		avvy->_facingDir = kDirLeft;
537 		avvy->_x = 151;
538 		avvy->_moveX = -3;
539 		avvy->_moveY = -5;
540 
541 		_vm->_graphics->setBackgroundColor(kColorGreen);
542 	}
543 }
544 
riseUpOubliette()545 void Timer::riseUpOubliette() {
546 	AnimationType *avvy = _vm->_animation->_sprites[0];
547 	avvy->_visible = true;
548 	avvy->_moveY++; // Decrements dx/dy!
549 	avvy->_y -= avvy->_moveY; // Uuuupppp we go...
550 	if (avvy->_moveY > 0)
551 		addTimer(3, kProcRiseUpOubliette, kReasonRisingUpOubliette);
552 	else
553 		_vm->_userMovesAvvy = true;
554 }
555 
robinHoodAndGeida()556 void Timer::robinHoodAndGeida() {
557 	AnimationType *avvy = _vm->_animation->_sprites[0];
558 	avvy->init(7, true);
559 	_vm->_animation->appearPed(0, 6);
560 	avvy->walkTo(5);
561 
562 	AnimationType *spr = _vm->_animation->_sprites[1];
563 	spr->stopWalk();
564 	spr->_facingDir = kDirLeft;
565 	addTimer(20, kProcRobinHoodAndGeidaTalk, kReasonRobinHoodAndGeida);
566 	_vm->_geidaFollows = false;
567 }
568 
robinHoodAndGeidaTalk()569 void Timer::robinHoodAndGeidaTalk() {
570 	_vm->_dialogs->displayScrollChain('Q', 66);
571 
572 	AnimationType *avvy = _vm->_animation->_sprites[0];
573 	AnimationType *spr = _vm->_animation->_sprites[1];
574 	avvy->walkTo(1);
575 	spr->walkTo(1);
576 	avvy->_vanishIfStill = true;
577 	spr->_vanishIfStill = true;
578 
579 	addTimer(162, kProcAvalotReturns, kReasonRobinHoodAndGeida);
580 }
581 
avalotReturns()582 void Timer::avalotReturns() {
583 	AnimationType *avvy = _vm->_animation->_sprites[0];
584 	AnimationType *spr = _vm->_animation->_sprites[1];
585 	avvy->remove();
586 	spr->remove();
587 	avvy->init(0, true);
588 	_vm->_animation->appearPed(0, 0);
589 	_vm->_dialogs->displayScrollChain('Q', 67);
590 	_vm->_userMovesAvvy = true;
591 }
592 
593 /**
594  * This is used when you sit down in the pub in Notts. It loops around
595  * so that it will happen when Avvy stops walking.
596  * @remarks	Originally called 'avvy_sit_down'
597  */
avvySitDown()598 void Timer::avvySitDown() {
599 	AnimationType *avvy = _vm->_animation->_sprites[0];
600 	if (avvy->_homing)    // Still walking.
601 		addTimer(1, kProcAvvySitDown, kReasonSittingDown);
602 	else {
603 		_vm->_background->draw(-1, -1, 2);
604 		_vm->_sittingInPub = true;
605 		_vm->_userMovesAvvy = false;
606 		avvy->_visible = false;
607 	}
608 }
609 
ghostRoomPhew()610 void Timer::ghostRoomPhew() {
611 	Common::String tmpStr = Common::String::format("%cPHEW!%c You're glad to get out of %cthere!",
612 		kControlItalic, kControlRoman, kControlItalic);
613 	_vm->_dialogs->displayText(tmpStr);
614 }
615 
arkataShouts()616 void Timer::arkataShouts() {
617 	if (_vm->_teetotal)
618 		return;
619 
620 	_vm->_dialogs->displayScrollChain('Q', 76);
621 	addTimer(160, kProcArkataShouts, kReasonArkataShouts);
622 }
623 
624 /**
625  * @remarks Contains the content of the function 'winning_pic', originally located in PINGO.
626  */
winning()627 void Timer::winning() {
628 	_vm->_dialogs->displayScrollChain('Q', 79);
629 
630 	// This was originally located in winning_pic:
631 	CursorMan.showMouse(false);
632 	_vm->_graphics->saveScreen();
633 	_vm->fadeOut();
634 	_vm->_graphics->drawWinningPic();
635 	_vm->_graphics->refreshScreen();
636 	_vm->fadeIn();
637 
638 	// Waiting for a keypress or a left mouseclick:
639 	Common::Event event;
640 	bool escape = false;
641 	while (!_vm->shouldQuit() && !escape) {
642 		_vm->_graphics->refreshScreen();
643 		while (_vm->getEvent(event)) {
644 			if ((event.type == Common::EVENT_LBUTTONUP) || (event.type == Common::EVENT_KEYDOWN)) {
645 				escape = true;
646 				break;
647 			}
648 		}
649 	}
650 
651 	_vm->fadeOut();
652 	_vm->_graphics->restoreScreen();
653 	_vm->_graphics->removeBackup();
654 	_vm->fadeIn();
655 	CursorMan.showMouse(true);
656 	// winning_pic's end.
657 
658 	_vm->callVerb(kVerbCodeScore);
659 	_vm->_dialogs->displayText(" T H E    E N D ");
660 	_vm->_letMeOut = true;
661 }
662 
avalotFalls()663 void Timer::avalotFalls() {
664 	AnimationType *avvy = _vm->_animation->_sprites[0];
665 	if (avvy->_stepNum < 5) {
666 		avvy->_stepNum++;
667 		addTimer(3, kProcAvalotFalls, kReasonFallingOver);
668 	} else {
669 		Common::String toDisplay = Common::String::format("%c%c%c%c%c%c%c%c%c%c%c%c%cZ%c",
670 			kControlNewLine, kControlNewLine, kControlNewLine, kControlNewLine,
671 			kControlNewLine, kControlNewLine, kControlInsertSpaces, kControlInsertSpaces,
672 			kControlInsertSpaces, kControlInsertSpaces, kControlInsertSpaces,
673 			kControlInsertSpaces, kControlRegister, kControlIcon);
674 		_vm->_dialogs->displayText(toDisplay);
675 	}
676 }
677 
spludwickGoesToCauldron()678 void Timer::spludwickGoesToCauldron() {
679 	if (_vm->_animation->_sprites[1]->_homing)
680 		addTimer(1, kProcSpludwickGoesToCauldron, kReasonSpludwickWalk);
681 	else
682 		addTimer(17, kProcSpludwickLeavesCauldron, kReasonSpludwickWalk);
683 }
684 
spludwickLeavesCauldron()685 void Timer::spludwickLeavesCauldron() {
686 	_vm->_animation->_sprites[1]->_callEachStepFl = true; // So that normal procs will continue.
687 }
688 
giveLuteToGeida()689 void Timer::giveLuteToGeida() { // Moved here from Acci.
690 	_vm->_dialogs->displayScrollChain('Q', 86);
691 	_vm->incScore(4);
692 	_vm->_lustieIsAsleep = true;
693 	_vm->_sequence->startGeidaLuteSeq();
694 }
695 
resetVariables()696 void Timer::resetVariables() {
697 	for (int i = 0; i < 7; i++) {
698 		_times[i]._timeLeft = 0;
699 		_times[i]._action = 0;
700 		_times[i]._reason = 0;
701 	}
702 
703 	_shootEmUpScore = 0;
704 }
705 
706 } // End of namespace Avalanche.
707