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 "hopkins/hopkins.h"
24 #include "hopkins/graphics.h"
25 #include "hopkins/files.h"
26 #include "hopkins/saveload.h"
27 #include "hopkins/sound.h"
28 #include "hopkins/talk.h"
29 
30 #include "common/scummsys.h"
31 #include "common/config-manager.h"
32 #include "common/debug-channels.h"
33 #include "common/events.h"
34 #include "common/file.h"
35 
36 namespace Hopkins {
37 
HopkinsEngine(OSystem * syst,const HopkinsGameDescription * gameDesc)38 HopkinsEngine::HopkinsEngine(OSystem *syst, const HopkinsGameDescription *gameDesc) : Engine(syst),
39 		_gameDescription(gameDesc), _randomSource("Hopkins") {
40 	DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level");
41 	DebugMan.addDebugChannel(kDebugGraphics, "Graphics", "Graphics debug level");
42 	_animMan = new AnimationManager(this);
43 	_computer = new ComputerManager(this);
44 	_dialog = new DialogsManager(this);
45 	_debug = new Debugger(this);
46 	_events = new EventsManager(this);
47 	_fileIO = new FileManager(this);
48 	_fontMan = new FontManager(this);
49 	_globals = new Globals(this);
50 	_graphicsMan = new GraphicsManager(this);
51 	_linesMan = new LinesManager(this);
52 	_menuMan = new MenuManager(this);
53 	_objectsMan = new ObjectsManager(this);
54 	_saveLoad = new SaveLoadManager(this);
55 	_script = new ScriptManager(this);
56 	_soundMan = new SoundManager(this);
57 	_talkMan = new TalkManager(this);
58 
59 	_startGameSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
60 }
61 
~HopkinsEngine()62 HopkinsEngine::~HopkinsEngine() {
63 	delete _talkMan;
64 	delete _soundMan;
65 	delete _script;
66 	delete _saveLoad;
67 	delete _objectsMan;
68 	delete _menuMan;
69 	delete _linesMan;
70 	delete _graphicsMan;
71 	delete _globals;
72 	delete _fontMan;
73 	delete _fileIO;
74 	delete _events;
75 	delete _debug;
76 	delete _dialog;
77 	delete _computer;
78 	delete _animMan;
79 }
80 
generateSaveName(int slot)81 Common::String HopkinsEngine::generateSaveName(int slot) {
82 	return Common::String::format("%s.%03d", _targetName.c_str(), slot);
83 }
84 
85 /**
86  * Returns true if it is currently okay to restore a game
87  */
canLoadGameStateCurrently()88 bool HopkinsEngine::canLoadGameStateCurrently() {
89 	return !_globals->_exitId && !_globals->_cityMapEnabledFl && _events->_mouseFl && _globals->_curRoomNum != 0;
90 }
91 
92 /**
93  * Returns true if it is currently okay to save the game
94  */
canSaveGameStateCurrently()95 bool HopkinsEngine::canSaveGameStateCurrently() {
96 	return !_globals->_exitId && !_globals->_cityMapEnabledFl && _events->_mouseFl
97 		&& _globals->_curRoomNum != 0 && !isUnderwaterSubScene();
98 }
99 
100 /**
101  * Load the savegame at the specified slot index
102  */
loadGameState(int slot)103 Common::Error HopkinsEngine::loadGameState(int slot) {
104 	return _saveLoad->loadGame(slot);
105 }
106 
107 /**
108  * Save the game to the given slot index, and with the given name
109  */
saveGameState(int slot,const Common::String & desc)110 Common::Error HopkinsEngine::saveGameState(int slot, const Common::String &desc) {
111 	return _saveLoad->saveGame(slot, desc);
112 }
113 
run()114 Common::Error HopkinsEngine::run() {
115 	_globals->setConfig();
116 	_fileIO->initCensorship();
117 	initializeSystem();
118 
119 	if (!getIsDemo())
120 		runFull();
121 	else if (getPlatform() == Common::kPlatformLinux)
122 		runLinuxDemo();
123 	else if (getPlatform() == Common::kPlatformWindows)
124 		runWin95Demo();
125 	else {
126 		warning("Unhandled version, switching to Linux demo. Please report this version to ScummVM developers");
127 		runLinuxDemo();
128 	}
129 
130 	return Common::kNoError;
131 }
132 
runWin95Demo()133 bool HopkinsEngine::runWin95Demo() {
134 	_objectsMan->loadObjects();
135 	_objectsMan->changeObject(14);
136 	_objectsMan->addObject(14);
137 	_objectsMan->_helicopterFl = false;
138 
139 	_globals->_eventMode = EVENTMODE_IGNORE;
140 
141 	_graphicsMan->clearScreen();
142 	_graphicsMan->clearPalette();
143 
144 	if (_startGameSlot == -1) {
145 		_graphicsMan->loadImage("H2");
146 		_graphicsMan->fadeInLong();
147 
148 		if (!_events->_escKeyFl)
149 			playIntro();
150 	}
151 
152 	_events->_rateCounter = 0;
153 	_globals->_eventMode = EVENTMODE_IGNORE;
154 	_globals->_speed = 1;
155 	_events->delay(500);
156 	_globals->_eventMode = EVENTMODE_DEFAULT;
157 	if (_events->_rateCounter > 475)
158 		_globals->_speed = 2;
159 	if (_events->_rateCounter > 700)
160 		_globals->_speed = 3;
161 
162 	if (_startGameSlot == -1)
163 		_graphicsMan->fadeOutShort();
164 
165 	_globals->_eventMode = EVENTMODE_IGNORE;
166 	_globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR");
167 
168 	_globals->_characterType = CHARACTER_HOPKINS;
169 	_objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0;
170 	_globals->_saveData->reset();
171 	_globals->_exitId = 0;
172 
173 	if (getLanguage() != Common::PL_POL)
174 		if (!displayAdultDisclaimer())
175 			return Common::kNoError;
176 
177 	if (_startGameSlot != -1)
178 		_saveLoad->loadGame(_startGameSlot);
179 
180 	for (;;) {
181 		if (_globals->_exitId == 300)
182 			_globals->_exitId = 0;
183 
184 		if (!_globals->_exitId) {
185 			_globals->_exitId = _menuMan->menu();
186 			if (_globals->_exitId == -1) {
187 				_globals->_characterSpriteBuf = _globals->freeMemory(_globals->_characterSpriteBuf);
188 				restoreSystem();
189 				return false;
190 			}
191 		}
192 
193 		if (shouldQuit())
194 			return false;
195 
196 		_globals->_curRoomNum = _globals->_exitId;
197 
198 		switch (_globals->_exitId) {
199 		case 1:
200 			// Handles room: Apartment
201 			_linesMan->setMaxLineIdx(40);
202 			_globals->_characterMaxPosY = 435;
203 			_objectsMan->sceneControl2("IM01", "IM01", "ANIM01", "IM01", 2, true);
204 			break;
205 
206 		case 3:
207 			// - Displays bank attack when leaving the apartment
208 			// - Handles room: bottom of the apartment
209 			if (!_globals->_saveData->_data[svBankAttackAnimPlayedFl]) {
210 				_soundMan->playSound(3);
211 				if (getPlatform() == Common::kPlatformOS2 || getPlatform() == Common::kPlatformBeOS)
212 					_graphicsMan->loadImage("fond");
213 				else {
214 					switch (_globals->_language) {
215 					case LANG_FR:
216 						_graphicsMan->loadImage("fondfr");
217 						break;
218 					case LANG_EN:
219 						_graphicsMan->loadImage("fondan");
220 						break;
221 					case LANG_SP:
222 						_graphicsMan->loadImage("fondes");
223 						break;
224 					}
225 				}
226 				_graphicsMan->fadeInLong();
227 				_events->delay(500);
228 				_graphicsMan->fadeOutLong();
229 				_globals->_eventMode = EVENTMODE_IGNORE;
230 				_soundMan->_specialSoundNum = 2;
231 				_graphicsMan->clearScreen();
232 				_graphicsMan->clearPalette();
233 				if (!_globals->_censorshipFl)
234 					_animMan->playAnim("BANQUE.ANM", "BANKUK.ANM", 200, 28, 200);
235 				else
236 					_animMan->playAnim("BANKUK.ANM", "BANQUE.ANM", 200, 28, 200);
237 				_soundMan->_specialSoundNum = 0;
238 				_soundMan->removeSample(1);
239 				_soundMan->removeSample(2);
240 				_soundMan->removeSample(3);
241 				_soundMan->removeSample(4);
242 				_graphicsMan->fadeOutShort();
243 				_globals->_saveData->_data[svBankAttackAnimPlayedFl] = 1;
244 			}
245 			_linesMan->setMaxLineIdx(5);
246 			_globals->_characterMaxPosY = 450;
247 			_objectsMan->sceneControl2("IM03", "IM03", "ANIM03", "IM03", 2, false);
248 			break;
249 
250 		case 4:
251 			// Handle room: City map
252 			_globals->_disableInventFl = true;
253 			_objectsMan->handleCityMap();
254 			_globals->_disableInventFl = false;
255 			break;
256 
257 		case 5:
258 			// Handle room: Outside the bank
259 			_linesMan->setMaxLineIdx(5);
260 			_globals->_characterMaxPosY = 455;
261 
262 			if (_globals->_saveData->_data[svFreedHostageFl]) {
263 				if (_globals->_saveData->_data[svFreedHostageFl] == 1)
264 					_objectsMan->sceneControl2("IM05", "IM05A", "ANIM05B", "IM05", 3, false);
265 			} else {
266 				_objectsMan->sceneControl2("IM05", "IM05", "ANIM05", "IM05", 3, false);
267 			}
268 			break;
269 
270 		case 6:
271 			_linesMan->setMaxLineIdx(20);
272 			_globals->_characterMaxPosY = 460;
273 			_objectsMan->sceneControl2("IM06", "IM06", "ANIM06", "IM06", 2, true);
274 			break;
275 
276 		case 7:
277 			if (_globals->_saveData->_data[svBombBoxOpenedFl])
278 				_objectsMan->sceneControl("BOMBEB", "BOMBE", "BOMBE", "BOMBE", 2, true);
279 			else
280 				_objectsMan->sceneControl("BOMBEA", "BOMBE", "BOMBE", "BOMBE", 2, true);
281 			break;
282 
283 		case 8:
284 			_linesMan->setMaxLineIdx(15);
285 			_globals->_characterMaxPosY = 450;
286 			_objectsMan->sceneControl2("IM08", "IM08", "ANIM08", "IM08", 2, true);
287 			break;
288 
289 		case 9:
290 			_globals->_characterMaxPosY = 440;
291 			_linesMan->setMaxLineIdx(20);
292 			if (_globals->_saveData->_data[svBombDisarmedFl])
293 			  _objectsMan->sceneControl2("IM09", "IM09", "ANIM09", "IM09", 10, true);
294 			else
295 			  bombExplosion();
296 			break;
297 
298 		case 10:
299 			_objectsMan->sceneControl("IM10", "IM10", "ANIM10", "IM10", 9, false);
300 			break;
301 
302 		case 11:
303 			_linesMan->setMaxLineIdx(20);
304 			_globals->_characterMaxPosY = 450;
305 			_objectsMan->sceneControl2("IM11", "IM11", "ANIM11", "IM11", 2, false);
306 			break;
307 
308 		case 12:
309 			_globals->_characterMaxPosY = 450;
310 			_linesMan->setMaxLineIdx(20);
311 			if (_globals->_saveData->_data[svBombDisarmedFl]) {
312 				if (_globals->_language == LANG_FR)
313 					_graphicsMan->loadImage("ENDFR");
314 				else
315 					_graphicsMan->loadImage("ENDUK");
316 				_graphicsMan->fadeInLong();
317 				_events->mouseOn();
318 				do {
319 					_events->refreshScreenAndEvents();
320 				} while (_events->getMouseButton() != 1);
321 				_graphicsMan->fadeOutLong();
322 				restoreSystem();
323 			} else
324 				bombExplosion();
325 			break;
326 
327 		case 13:
328 		case 14:
329 		case 15:
330 			handleNotAvailable(11);
331 			break;
332 
333 		case 16:
334 		case 24:
335 		case 25:
336 		case 26:
337 		case 27:
338 		case 28:
339 		case 29:
340 		case 30:
341 		case 31:
342 		case 33:
343 		case 32:
344 		case 34:
345 			handleNotAvailable(4);
346 			break;
347 
348 		case 17:
349 			handleNotAvailable(1);
350 			break;
351 
352 		case 111:
353 			_objectsMan->sceneControl("IM111", "IM111", "ANIM111", "IM111", 10, false);
354 			break;
355 
356 		case 112:
357 			_objectsMan->sceneControl("IM112", "IM112", "ANIM112", "IM112", 10, false);
358 			break;
359 
360 		case 113:
361 			_globals->_exitId = 0;
362 			_globals->_prevScreenId = _globals->_screenId;
363 			_globals->_saveData->_data[svLastPrevScreenId] = _globals->_screenId;
364 			_globals->_screenId = 113;
365 			_globals->_saveData->_data[svLastScreenId] = _globals->_screenId;
366 			_computer->showComputer(COMPUTER_HOPKINS);
367 			_graphicsMan->clearScreen();
368 			_graphicsMan->updateScreen();
369 			memset(_graphicsMan->_frontBuffer, 0, 307200);
370 			memset(_graphicsMan->_backBuffer, 0, 307200);
371 			_graphicsMan->clearPalette();
372 			_graphicsMan->resetDirtyRects();
373 			break;
374 
375 		case 114:
376 			_globals->_prevScreenId = _globals->_screenId;
377 			_globals->_saveData->_data[svLastPrevScreenId] = _globals->_screenId;
378 			_globals->_screenId = 114;
379 			_globals->_saveData->_data[svLastScreenId] = _globals->_screenId;
380 			_globals->_exitId = 0;
381 			_computer->showComputer(COMPUTER_SAMANTHA);
382 			_graphicsMan->clearScreen();
383 			break;
384 
385 		case 115:
386 			_globals->_exitId = 0;
387 			_globals->_prevScreenId = _globals->_screenId;
388 			_globals->_saveData->_data[svLastPrevScreenId] = _globals->_screenId;
389 			_globals->_screenId = 115;
390 			_globals->_saveData->_data[svLastScreenId] = _globals->_screenId;
391 			_computer->showComputer(COMPUTER_PUBLIC);
392 			_graphicsMan->clearScreen();
393 			break;
394 
395 		case 150:
396 			_soundMan->playSound(28);
397 			_globals->_eventMode = EVENTMODE_ALT; // CHECKME!
398 			_graphicsMan->clearScreen();
399 			_graphicsMan->clearPalette();
400 			_animMan->playAnim("JOUR1A.ANM", "JOUR1A.ANM", 12, 12, 2000);
401 			_globals->_eventMode = EVENTMODE_DEFAULT;
402 			_globals->_exitId = 300;
403 			break;
404 
405 		case 151:
406 			if (_fileIO->fileExists("JOUR3A.ANM")) {
407 				// The Polish demo uses the animation file than the complete versions
408 				_soundMan->playSound(16);
409 				_globals->_eventMode = EVENTMODE_IGNORE;
410 
411 				_graphicsMan->clearScreen();
412 				_graphicsMan->clearPalette();
413 				_graphicsMan->_fadingFl = true;
414 				_animMan->playAnim("JOUR3A.ANM", "JOUR3A.ANM", 12, 12, 2000);
415 			} else {
416 				// The other demos only display a nag screen
417 				_soundMan->playSound(28);
418 				_globals->_eventMode = EVENTMODE_ALT; // CHECKME!
419 				_graphicsMan->clearScreen();
420 				_graphicsMan->clearPalette();
421 				_graphicsMan->loadImage("njour3a");
422 				_graphicsMan->fadeInLong();
423 				_events->delay(5000);
424 				_graphicsMan->fadeOutLong();
425 			}
426 
427 			_globals->_exitId = 300;
428 			_globals->_eventMode = EVENTMODE_DEFAULT;
429 			break;
430 
431 		case 152:
432 			_soundMan->playSound(28);
433 			_globals->_eventMode = EVENTMODE_ALT; // CHECKME!
434 			_graphicsMan->clearScreen();
435 			_graphicsMan->clearPalette();
436 			_animMan->playAnim("JOUR4A.ANM", "JOUR4A.ANM", 12, 12, 2000);
437 			_globals->_eventMode = EVENTMODE_DEFAULT;
438 			_globals->_exitId = 300;
439 			break;
440 		}
441 	}
442 	return true;
443 }
444 
runLinuxDemo()445 bool HopkinsEngine::runLinuxDemo() {
446 	_objectsMan->loadObjects();
447 	_objectsMan->changeObject(14);
448 	_objectsMan->addObject(14);
449 	_objectsMan->_helicopterFl = false;
450 
451 	_events->mouseOff();
452 
453 	_graphicsMan->clearScreen();
454 
455 	if (_startGameSlot == -1) {
456 		_graphicsMan->loadImage("LINUX");
457 		_graphicsMan->fadeInLong();
458 		_events->delay(1500);
459 		_graphicsMan->fadeOutLong();
460 
461 		_graphicsMan->loadImage("H2");
462 		_graphicsMan->fadeInLong();
463 		_events->delay(500);
464 		_graphicsMan->fadeOutLong();
465 
466 		if (!_events->_escKeyFl)
467 			playIntro();
468 	}
469 
470 	_globals->_eventMode = EVENTMODE_DEFAULT;
471 	_globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR");
472 	_globals->_characterType = CHARACTER_HOPKINS;
473 	_objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0;
474 	_globals->_saveData->reset();
475 	_globals->_exitId = 0;
476 
477 	if (_startGameSlot != -1)
478 		_saveLoad->loadGame(_startGameSlot);
479 
480 	for (;;) {
481 		if (_globals->_exitId == 300)
482 			_globals->_exitId = 0;
483 
484 		if (!_globals->_exitId) {
485 			_globals->_exitId = _menuMan->menu();
486 			if (_globals->_exitId == -1) {
487 				if (!shouldQuit())
488 					endLinuxDemo();
489 				_globals->_characterSpriteBuf = _globals->freeMemory(_globals->_characterSpriteBuf);
490 				restoreSystem();
491 			}
492 		}
493 
494 		if (shouldQuit())
495 			return false;
496 
497 		_globals->_curRoomNum = _globals->_exitId;
498 
499 		switch (_globals->_exitId) {
500 		case 17:
501 		case 18:
502 		case 19:
503 		case 20:
504 		case 22:
505 		case 23:
506 		case 24:
507 		case 27:
508 		case 28:
509 		case 29:
510 		case 30:
511 		case 31:
512 		case 32:
513 		case 34:
514 		case 38:
515 			displayNotAvailable();
516 			break;
517 
518 		case 1:
519 			_linesMan->setMaxLineIdx(40);
520 			_globals->_characterMaxPosY = 435;
521 			_objectsMan->sceneControl2("IM01", "IM01", "ANIM01", "IM01", 1, true);
522 			break;
523 
524 		case 3:
525 			if (!_globals->_saveData->_data[svBankAttackAnimPlayedFl]) {
526 				_soundMan->playSound(3);
527 				if (getPlatform() == Common::kPlatformOS2 || getPlatform() == Common::kPlatformBeOS)
528 					_graphicsMan->loadImage("fond");
529 				else {
530 					switch (_globals->_language) {
531 					case LANG_FR:
532 						_graphicsMan->loadImage("fondfr");
533 						break;
534 					case LANG_EN:
535 						_graphicsMan->loadImage("fondan");
536 						break;
537 					case LANG_SP:
538 						_graphicsMan->loadImage("fondes");
539 						break;
540 					}
541 				}
542 				_graphicsMan->fadeInLong();
543 				_events->delay(500);
544 				_graphicsMan->fadeOutLong();
545 				_globals->_eventMode = EVENTMODE_IGNORE;
546 				_soundMan->_specialSoundNum = 2;
547 
548 				_graphicsMan->clearScreen();
549 				_graphicsMan->clearPalette();
550 				_graphicsMan->_fadingFl = true;
551 
552 				if (!_globals->_censorshipFl)
553 					_animMan->playAnim("BANQUE.ANM", "BANKUK.ANM", 200, 28, 200);
554 				else
555 					_animMan->playAnim("BANKUK.ANM", "BANQUE.ANM", 200, 28, 200);
556 				_soundMan->_specialSoundNum = 0;
557 				_soundMan->removeSample(1);
558 				_soundMan->removeSample(2);
559 				_soundMan->removeSample(3);
560 				_soundMan->removeSample(4);
561 				_globals->_saveData->_data[svBankAttackAnimPlayedFl] = 1;
562 			}
563 
564 			_linesMan->setMaxLineIdx(5);
565 			_globals->_characterMaxPosY = 450;
566 			_objectsMan->sceneControl2("IM03", "IM03", "ANIM03", "IM03", 2, false);
567 			break;
568 
569 		case 4:
570 			_globals->_disableInventFl = true;
571 			_objectsMan->handleCityMap();
572 			_globals->_disableInventFl = false;
573 			break;
574 
575 		case 5:
576 			_linesMan->setMaxLineIdx(5);
577 			_globals->_characterMaxPosY = 455;
578 			if (_globals->_saveData->_data[svFreedHostageFl] == 1)
579 					_objectsMan->sceneControl2("IM05", "IM05A", "ANIM05B", "IM05", 3, false);
580 			else
581 				_objectsMan->sceneControl2("IM05", "IM05", "ANIM05", "IM05", 3, false);
582 			break;
583 
584 		case 6:
585 			_linesMan->setMaxLineIdx(20);
586 			_globals->_characterMaxPosY = 460;
587 			_objectsMan->sceneControl2("IM06", "IM06", "ANIM06", "IM06", 2, true);
588 			break;
589 
590 		case 7:
591 			if (_globals->_saveData->_data[svBombBoxOpenedFl])
592 				_objectsMan->sceneControl("BOMBEB", "BOMBE", "BOMBE", "BOMBE", 2, true);
593 			else
594 				_objectsMan->sceneControl("BOMBEA", "BOMBE", "BOMBE", "BOMBE", 2, true);
595 			break;
596 
597 		case 8:
598 			_linesMan->setMaxLineIdx(15);
599 			_globals->_characterMaxPosY = 450;
600 			_objectsMan->sceneControl2("IM08", "IM08", "ANIM08", "IM08", 2, true);
601 			break;
602 
603 		case 9:
604 			_linesMan->setMaxLineIdx(20);
605 			_globals->_characterMaxPosY = 440;
606 
607 			if (!_globals->_saveData->_data[svBombDisarmedFl])
608 				bombExplosion();
609 			else
610 				_objectsMan->sceneControl2("IM09", "IM09", "ANIM09", "IM09", 10, true);
611 			break;
612 
613 		case 10:
614 			_objectsMan->sceneControl("IM10", "IM10", "ANIM10", "IM10", 9, false);
615 			break;
616 
617 		case 11:
618 			_linesMan->setMaxLineIdx(20);
619 			_globals->_characterMaxPosY = 450;
620 			_objectsMan->sceneControl2("IM11", "IM11", "ANIM11", "IM11", 2, false);
621 			break;
622 
623 		case 12:
624 			_linesMan->setMaxLineIdx(20);
625 			_globals->_characterMaxPosY = 450;
626 			if (_globals->_saveData->_data[svBombDisarmedFl])
627 				_objectsMan->sceneControl2("IM12", "IM12", "ANIM12", "IM12", 1, false);
628 			else
629 				bombExplosion();
630 			break;
631 
632 		case 13:
633 			_linesMan->setMaxLineIdx(40);
634 			_globals->_characterMaxPosY = 440;
635 			_objectsMan->sceneControl2("IM13", "IM13", "ANIM13", "IM13", 1, true);
636 			break;
637 
638 		case 14:
639 			_linesMan->setMaxLineIdx(40);
640 			_globals->_characterMaxPosY = 440;
641 			_objectsMan->sceneControl2("IM14", "IM14", "ANIM14", "IM14", 1, true);
642 			break;
643 
644 		case 15:
645 			_objectsMan->sceneControl("IM15", "IM15", "ANIM15", "IM15", 29, false);
646 			break;
647 
648 		case 16:
649 			_linesMan->setMaxLineIdx(5);
650 			_globals->_characterMaxPosY = 450;
651 
652 			if (_globals->_saveData->_data[svForestAvailableFl] == 1) {
653 				_objectsMan->sceneControl2("IM16", "IM16A", "ANIM16", "IM16", 7, true);
654 			} else if (!_globals->_saveData->_data[svForestAvailableFl]) {
655 				_objectsMan->sceneControl2("IM16", "IM16", "ANIM16", "IM16", 7, true);
656 			}
657 			break;
658 
659 		case 25:
660 			_linesMan->setMaxLineIdx(20);
661 			_globals->_characterMaxPosY = 445;
662 			_objectsMan->sceneControl2("IM25", "IM25", "ANIM25", "IM25", 30, true);
663 			break;
664 
665 		case 26:
666 			_linesMan->setMaxLineIdx(40);
667 			_globals->_characterMaxPosY = 435;
668 			_objectsMan->sceneControl2("IM26", "IM26", "ANIM26", "IM26", 30, true);
669 			break;
670 
671 		case 33:
672 			_objectsMan->sceneControl("IM33", "IM33", "ANIM33", "IM33", 8, false);
673 			break;
674 
675 		case 35:
676 			displayEndDemo();
677 			break;
678 
679 		case 111:
680 			_objectsMan->sceneControl("IM111", "IM111", "ANIM111", "IM111", 10, false);
681 			break;
682 
683 		case 112:
684 			_objectsMan->sceneControl("IM112", "IM112", "ANIM112", "IM112", 10, false);
685 			break;
686 
687 		case 113:
688 			_globals->_exitId = 0;
689 			_globals->_prevScreenId = _globals->_screenId;
690 			_globals->_saveData->_data[svLastPrevScreenId] = _globals->_screenId;
691 			_globals->_screenId = 113;
692 			_globals->_saveData->_data[svLastScreenId] = 113;
693 			_computer->showComputer(COMPUTER_HOPKINS);
694 
695 			_graphicsMan->clearScreen();
696 			_graphicsMan->updateScreen();
697 			memset(_graphicsMan->_frontBuffer, 0, 307200);
698 			memset(_graphicsMan->_backBuffer, 0, 307200);
699 			_graphicsMan->clearPalette();
700 			_graphicsMan->resetDirtyRects();
701 			break;
702 
703 		case 114:
704 			_globals->_exitId = 0;
705 			_globals->_prevScreenId = _globals->_screenId;
706 			_globals->_saveData->_data[svLastPrevScreenId] = _globals->_screenId;
707 			_globals->_screenId = 114;
708 			_globals->_saveData->_data[svLastScreenId] = 114;
709 			_computer->showComputer(COMPUTER_SAMANTHA);
710 			_graphicsMan->clearScreen();
711 			break;
712 
713 		case 115:
714 			_globals->_exitId = 0;
715 			_globals->_prevScreenId = _globals->_screenId;
716 			_globals->_saveData->_data[svLastPrevScreenId] = _globals->_screenId;
717 			_globals->_screenId = 115;
718 			_globals->_saveData->_data[svLastScreenId] = 115;
719 			_computer->showComputer(COMPUTER_PUBLIC);
720 			_graphicsMan->clearScreen();
721 			break;
722 
723 		case 150:
724 			_soundMan->playSound(16);
725 			_globals->_eventMode = EVENTMODE_IGNORE;
726 
727 			_graphicsMan->clearScreen();
728 			_graphicsMan->clearPalette();
729 			_graphicsMan->_fadingFl = true;
730 			_animMan->playAnim("JOUR1A.ANM", "JOUR1A.ANM", 12, 12, 2000);
731 			_globals->_eventMode = EVENTMODE_DEFAULT;
732 			_globals->_exitId = 300;
733 			break;
734 
735 		case 151:
736 			_soundMan->playSound(16);
737 			_globals->_eventMode = EVENTMODE_IGNORE;
738 
739 			_graphicsMan->clearScreen();
740 			_graphicsMan->clearPalette();
741 			_graphicsMan->_fadingFl = true;
742 			_animMan->playAnim("JOUR3A.ANM", "JOUR3A.ANM", 12, 12, 2000);
743 			_globals->_eventMode = EVENTMODE_DEFAULT;
744 			_globals->_exitId = 300;
745 			break;
746 
747 		case 152:
748 			_soundMan->playSound(16);
749 			_globals->_eventMode = EVENTMODE_IGNORE;
750 
751 			_graphicsMan->clearScreen();
752 			_graphicsMan->clearPalette();
753 			_graphicsMan->_fadingFl = true;
754 			_animMan->playAnim("JOUR4A.ANM", "JOUR4A.ANM", 12, 12, 2000);
755 			_globals->_eventMode = EVENTMODE_DEFAULT;
756 			_globals->_exitId = 300;
757 			break;
758 		}
759 	}
760 	return true;
761 }
762 
runFull()763 bool HopkinsEngine::runFull() {
764 	if (_startGameSlot == -1 && getPlatform() == Common::kPlatformLinux)
765 		_soundMan->playSound(16);
766 
767 	_objectsMan->loadObjects();
768 	_objectsMan->changeObject(14);
769 	_objectsMan->addObject(14);
770 
771 	if (getPlatform() == Common::kPlatformLinux) {
772 		_objectsMan->_helicopterFl = false;
773 		_events->mouseOff();
774 		// No code has been added to display the version as it's wrong
775 		// in my copy: it mentions a Win95 version v4 using DirectDraw (Strangerke)
776 	} else if (getPlatform() == Common::kPlatformWindows) {
777 		_objectsMan->_helicopterFl = false;
778 		_globals->_eventMode = EVENTMODE_IGNORE;
779 		// This code displays the game version.
780 		// It wasn't present in the original and could be put in the debugger
781 		// It has been added there for debug purposes
782 		if (_startGameSlot == -1) {
783 			_graphicsMan->loadImage("VERSW");
784 			_graphicsMan->fadeInLong();
785 			_events->delay(500);
786 			_graphicsMan->fadeOutLong();
787 		}
788 		_graphicsMan->clearVesaScreen();
789 	} else {
790 		// This piece of code, though named "display_version" in the original,
791 		// displays a "loading please wait" screen.
792 		if (_startGameSlot == -1) {
793 			_graphicsMan->loadImage("VERSW");
794 			_graphicsMan->fadeInLong();
795 			_events->delay(500);
796 			_graphicsMan->fadeOutLong();
797 		}
798 		_graphicsMan->clearVesaScreen();
799 
800 		_globals->_eventMode = EVENTMODE_IGNORE;
801 	}
802 
803 	_graphicsMan->clearScreen();
804 	_graphicsMan->clearPalette();
805 
806 	if (_startGameSlot == -1) {
807 		if (getPlatform() == Common::kPlatformLinux) {
808 			_graphicsMan->loadImage("H2");
809 			_graphicsMan->fadeInLong();
810 			_events->delay(500);
811 			_graphicsMan->fadeOutLong();
812 			_globals->_speed = 2;
813 			_globals->_eventMode = EVENTMODE_IGNORE;
814 			_graphicsMan->_fadingFl = true;
815 			_animMan->playAnim("MP.ANM", "MP.ANM", 10, 16, 200);
816 		} else {
817 			_animMan->playAnim("MP.ANM", "MP.ANM", 10, 16, 200);
818 			_graphicsMan->fadeOutLong();
819 		}
820 	}
821 
822 	_events->mouseOff();
823 
824 	if (!_events->_escKeyFl && _startGameSlot == -1) {
825 		playIntro();
826 		if (shouldQuit())
827 			return false;
828 	}
829 
830 	if (getPlatform() != Common::kPlatformLinux && _startGameSlot == -1) {
831 		_graphicsMan->fadeOutShort();
832 		_graphicsMan->loadImage("H2");
833 		_graphicsMan->fadeInLong();
834 		_events->delay(500);
835 		_graphicsMan->fadeOutLong();
836 	}
837 	_globals->_eventMode = EVENTMODE_DEFAULT;
838 	_globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR");
839 	_globals->_characterType = CHARACTER_HOPKINS;
840 	_objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0;
841 	_globals->_saveData->reset();
842 
843 	_globals->_exitId = 0;
844 
845 
846 	if (_startGameSlot != -1) {
847 		_soundMan->playSound(28);
848 		_saveLoad->loadGame(_startGameSlot);
849 	}
850 
851 	for (;;) {
852 		if (_globals->_exitId == 300)
853 			_globals->_exitId = 0;
854 		if (!_globals->_exitId) {
855 			_globals->_exitId = _menuMan->menu();
856 			if (_globals->_exitId == -1) {
857 				_globals->_characterSpriteBuf = _globals->freeMemory(_globals->_characterSpriteBuf);
858 				restoreSystem();
859 				return false;
860 			}
861 		}
862 
863 		if (shouldQuit())
864 			return false;
865 
866 		_globals->_curRoomNum = _globals->_exitId;
867 
868 		switch (_globals->_exitId) {
869 		case 1:
870 			_linesMan->setMaxLineIdx(40);
871 			_globals->_characterMaxPosY = 435;
872 			_objectsMan->sceneControl2("IM01", "IM01", "ANIM01", "IM01", 1, true);
873 			break;
874 
875 		case 3:
876 			if (!_globals->_saveData->_data[svBankAttackAnimPlayedFl]) {
877 				// Play the bank attack animation
878 				_soundMan->playSound(3);
879 				if (getPlatform() == Common::kPlatformOS2 || getPlatform() == Common::kPlatformBeOS)
880 					_graphicsMan->loadImage("fond");
881 				else {
882 					switch (_globals->_language) {
883 					case LANG_FR:
884 						_graphicsMan->loadImage("fondfr");
885 						break;
886 					case LANG_EN:
887 						_graphicsMan->loadImage("fondan");
888 						break;
889 					case LANG_SP:
890 						_graphicsMan->loadImage("fondes");
891 						break;
892 					}
893 				}
894 				_graphicsMan->fadeInLong();
895 				_events->delay(500);
896 				_graphicsMan->fadeOutLong();
897 				_globals->_eventMode = EVENTMODE_IGNORE;
898 				_soundMan->_specialSoundNum = 2;
899 				_graphicsMan->clearScreen();
900 				_graphicsMan->clearPalette();
901 				if (getPlatform() == Common::kPlatformLinux || getPlatform() == Common::kPlatformWindows) {
902 					if (getPlatform() == Common::kPlatformLinux)
903 						_graphicsMan->_fadingFl = true;
904 
905 					if (!_globals->_censorshipFl)
906 						_animMan->playAnim("BANQUE.ANM", "BANKUK.ANM", 200, 28, 200);
907 					else
908 						_animMan->playAnim("BANKUK.ANM", "BANQUE.ANM", 200, 28, 200);
909 				} else {
910 					_animMan->playAnim("BANQUE.ANM", "BANKUK.ANM", 200, 28, 200);
911 				}
912 
913 				_soundMan->_specialSoundNum = 0;
914 				_soundMan->removeSample(1);
915 				_soundMan->removeSample(2);
916 				_soundMan->removeSample(3);
917 				_soundMan->removeSample(4);
918 
919 				if (getPlatform() != Common::kPlatformLinux) {
920 					// Copy the end of the animation into the secondary buffer and fade out the screen
921 					Common::fill(_graphicsMan->_frontBuffer, _graphicsMan->_frontBuffer +
922 						SCREEN_WIDTH * 2 * SCREEN_HEIGHT, 0);
923 					_graphicsMan->fadeOutLong();
924 				}
925 
926 				_globals->_saveData->_data[svBankAttackAnimPlayedFl] = 1;
927 			}
928 			_linesMan->setMaxLineIdx(5);
929 			_globals->_characterMaxPosY = 450;
930 			_objectsMan->sceneControl2("IM03", "IM03", "ANIM03", "IM03", 2, false);
931 			break;
932 
933 		case 4:
934 			_globals->_disableInventFl = true;
935 			_objectsMan->handleCityMap();
936 			_globals->_disableInventFl = false;
937 			break;
938 
939 		case 5:
940 			_linesMan->setMaxLineIdx(5);
941 			_globals->_characterMaxPosY = 455;
942 			if (_globals->_saveData->_data[svFreedHostageFl] == 1)
943 				_objectsMan->sceneControl2("IM05", "IM05A", "ANIM05B", "IM05", 3, false);
944 			else
945 				_objectsMan->sceneControl2("IM05", "IM05", "ANIM05", "IM05", 3, false);
946 			break;
947 
948 		case 6:
949 			_linesMan->setMaxLineIdx(20);
950 			_globals->_characterMaxPosY = 460;
951 			_objectsMan->sceneControl2("IM06", "IM06", "ANIM06", "IM06", 2, true);
952 			break;
953 
954 		case 7:
955 			if (_globals->_saveData->_data[svBombBoxOpenedFl])
956 				_objectsMan->sceneControl("BOMBEB", "BOMBE", "BOMBE", "BOMBE", 2, true);
957 			else
958 				_objectsMan->sceneControl("BOMBEA", "BOMBE", "BOMBE", "BOMBE", 2, true);
959 			break;
960 
961 		case 8:
962 			_linesMan->setMaxLineIdx(15);
963 			_globals->_characterMaxPosY = 450;
964 			_objectsMan->sceneControl2("IM08", "IM08", "ANIM08", "IM08", 2, true);
965 			break;
966 
967 		case 9:
968 			_linesMan->setMaxLineIdx(20);
969 			_globals->_characterMaxPosY = 440;
970 			if (_globals->_saveData->_data[svBombDisarmedFl])
971 				_objectsMan->sceneControl2("IM09", "IM09", "ANIM09", "IM09", 10, true);
972 			else
973 				bombExplosion();
974 			break;
975 
976 		case 10:
977 			_objectsMan->sceneControl("IM10", "IM10", "ANIM10", "IM10", 9, false);
978 			break;
979 
980 		case 11:
981 			_linesMan->setMaxLineIdx(20);
982 			_globals->_characterMaxPosY = 450;
983 			_objectsMan->sceneControl2("IM11", "IM11", "ANIM11", "IM11", 2, false);
984 			break;
985 
986 		case 12:
987 			_linesMan->setMaxLineIdx(20);
988 			_globals->_characterMaxPosY = 450;
989 			if (_globals->_saveData->_data[svBombDisarmedFl])
990 				_objectsMan->sceneControl2("IM12", "IM12", "ANIM12", "IM12", 1, false);
991 			else
992 				bombExplosion();
993 			break;
994 
995 		case 13:
996 			_linesMan->setMaxLineIdx(40);
997 			_globals->_characterMaxPosY = 440;
998 			_objectsMan->sceneControl2("IM13", "IM13", "ANIM13", "IM13", 1, true);
999 			break;
1000 
1001 		case 14:
1002 			_linesMan->setMaxLineIdx(40);
1003 			_globals->_characterMaxPosY = 440;
1004 			_objectsMan->sceneControl2("IM14", "IM14", "ANIM14", "IM14", 1, true);
1005 			break;
1006 
1007 		case 15:
1008 			if (getPlatform() == Common::kPlatformLinux || getPlatform() == Common::kPlatformWindows)
1009 				_objectsMan->sceneControl("IM15", "IM15", "ANIM15", "IM15", 29, false);
1010 			else
1011 				_objectsMan->sceneControl("IM15", "IM15", "ANIM15", "IM15", 18, false);
1012 			break;
1013 
1014 		case 16:
1015 			_linesMan->setMaxLineIdx(5);
1016 			_globals->_characterMaxPosY = 450;
1017 			if (_globals->_saveData->_data[svForestAvailableFl] == 1)
1018 				_objectsMan->sceneControl2("IM16", "IM16A", "ANIM16", "IM16", 7, true);
1019 			else
1020 				_objectsMan->sceneControl2("IM16", "IM16", "ANIM16", "IM16", 7, true);
1021 			break;
1022 
1023 		case 17:
1024 			_linesMan->setMaxLineIdx(40);
1025 			_globals->_characterMaxPosY = 440;
1026 			if (_globals->_saveData->_data[svHutBurningFl] == 1)
1027 				_objectsMan->sceneControl2("IM17", "IM17A", "ANIM17", "IM17", 11, true);
1028 			else if (!_globals->_saveData->_data[svHutBurningFl])
1029 				_objectsMan->sceneControl2("IM17", "IM17", "ANIM17", "IM17", 11, true);
1030 			if (_globals->_exitId == 18) {
1031 				_globals->_eventMode = EVENTMODE_IGNORE;
1032 				_graphicsMan->clearScreen();
1033 				_graphicsMan->clearPalette();
1034 				_soundMan->stopSound();
1035 				if (getPlatform() == Common::kPlatformLinux) {
1036 					_soundMan->playSound(29);
1037 					_graphicsMan->_fadingFl = true;
1038 					_animMan->playAnim("PURG1A.ANM", "PURG1.ANM", 12, 18, 50);
1039 				} else if (getPlatform() == Common::kPlatformWindows) {
1040 					_soundMan->playSound(29);
1041 					_animMan->playAnim("PURG1A.ANM", "PURG1.ANM", 12, 18, 50);
1042 					_graphicsMan->fadeOutShort();
1043 				} else {
1044 					_soundMan->playSound(6);
1045 					_animMan->playAnim("PURG1A.ANM", "PURG1.ANM", 12, 18, 50);
1046 					_graphicsMan->fadeOutShort();
1047 				}
1048 				_globals->_eventMode = EVENTMODE_DEFAULT;
1049 			}
1050 			break;
1051 
1052 		case 18:
1053 			_linesMan->setMaxLineIdx(5);
1054 			_globals->_characterMaxPosY = 450;
1055 			if (getPlatform() == Common::kPlatformLinux || getPlatform() == Common::kPlatformWindows)
1056 				_objectsMan->sceneControl2("IM18", "IM18", "ANIM18", "IM18", 29, false);
1057 			else
1058 				_objectsMan->sceneControl2("IM18", "IM18", "ANIM18", "IM18", 6, false);
1059 			break;
1060 
1061 		case 19:
1062 			_linesMan->setMaxLineIdx(40);
1063 			_globals->_characterMaxPosY = 440;
1064 			if (_globals->_saveData->_data[svHeavenGuardGoneFl])
1065 				_objectsMan->sceneControl2("IM19", "IM19A", "ANIM19", "IM19", 6, true);
1066 			else
1067 				_objectsMan->sceneControl2("IM19", "IM19", "ANIM19", "IM19", 6, true);
1068 			break;
1069 
1070 		case 20:
1071 			_linesMan->setMaxLineIdx(10);
1072 			_globals->_characterMaxPosY = 440;
1073 			_objectsMan->sceneControl2("IM20", "IM20", "ANIM20", "IM20", 6, true);
1074 			if (_globals->_exitId == 17) {
1075 				_globals->_eventMode = EVENTMODE_IGNORE;
1076 				_soundMan->stopSound();
1077 				_graphicsMan->clearScreen();
1078 				_graphicsMan->clearPalette();
1079 				_soundMan->playSound(6);
1080 				if (getPlatform() == Common::kPlatformLinux)
1081 					_graphicsMan->_fadingFl = true;
1082 				_animMan->playAnim("PURG2A.ANM", "PURG2.ANM", 12, 18, 50);
1083 				if (getPlatform() != Common::kPlatformLinux)
1084 					_graphicsMan->fadeOutShort();
1085 				_globals->_eventMode = EVENTMODE_DEFAULT;
1086 			}
1087 			break;
1088 
1089 		case 22:
1090 			_linesMan->setMaxLineIdx(20);
1091 			_globals->_characterMaxPosY = 445;
1092 			_objectsMan->sceneControl2("IM22", "IM22", "ANIM22", "IM22", 6, true);
1093 			break;
1094 
1095 		case 23:
1096 			_linesMan->setMaxLineIdx(20);
1097 			_globals->_characterMaxPosY = 440;
1098 			_objectsMan->sceneControl2("IM23", "IM23", "ANIM23", "IM23", 6, true);
1099 			break;
1100 
1101 		case 24:
1102 			_linesMan->setMaxLineIdx(5);
1103 			_globals->_characterMaxPosY = 450;
1104 			if (_globals->_saveData->_data[svCinemaDogGoneFl] == 1)
1105 				_objectsMan->sceneControl2("IM24", "IM24A", "ANIM24", "IM24", 1, true);
1106 			else
1107 				_objectsMan->sceneControl2("IM24", "IM24", "ANIM24", "IM24", 1, true);
1108 			break;
1109 
1110 		case 25:
1111 			_linesMan->setMaxLineIdx(20);
1112 			_globals->_characterMaxPosY = 445;
1113 			if (getPlatform() == Common::kPlatformLinux || getPlatform() == Common::kPlatformWindows)
1114 				_objectsMan->sceneControl2("IM25", "IM25", "ANIM25", "IM25", 30, true);
1115 			else
1116 				_objectsMan->sceneControl2("IM25", "IM25", "ANIM25", "IM25", 8, true);
1117 			break;
1118 
1119 		case 26:
1120 			_linesMan->setMaxLineIdx(40);
1121 			_globals->_characterMaxPosY = 435;
1122 			if (getPlatform() == Common::kPlatformLinux || getPlatform() == Common::kPlatformWindows)
1123 				_objectsMan->sceneControl2("IM26", "IM26", "ANIM26", "IM26", 30, true);
1124 			else
1125 				_objectsMan->sceneControl2("IM26", "IM26", "ANIM26", "IM26", 8, true);
1126 			break;
1127 
1128 		case 27:
1129 			_linesMan->setMaxLineIdx(15);
1130 			_globals->_characterMaxPosY = 440;
1131 			if (_globals->_saveData->_data[svPoolDogGoneFl] == 1)
1132 				_objectsMan->sceneControl2("IM27", "IM27A", "ANIM27", "IM27", 27, true);
1133 			else
1134 				_objectsMan->sceneControl2("IM27", "IM27", "ANIM27", "IM27", 27, true);
1135 			break;
1136 
1137 		case 28:
1138 			_linesMan->setMaxLineIdx(5);
1139 			_globals->_characterMaxPosY = 450;
1140 			if (_globals->_saveData->_data[svCinemaCurtainCond1] != 1 || _globals->_saveData->_data[svCinemaCurtainCond2] != 1)
1141 				_objectsMan->sceneControl2("IM28", "IM28", "ANIM28", "IM28", 1, false);
1142 			else
1143 				_objectsMan->sceneControl2("IM28A", "IM28", "ANIM28", "IM28", 1, false);
1144 			break;
1145 
1146 		case 29:
1147 			_linesMan->setMaxLineIdx(50);
1148 			_globals->_characterMaxPosY = 445;
1149 			_objectsMan->sceneControl2("IM29", "IM29", "ANIM29", "IM29", 1, true);
1150 			break;
1151 
1152 		case 30:
1153 			// Shooting
1154 			_linesMan->setMaxLineIdx(15);
1155 			_globals->_characterMaxPosY = 440;
1156 			_objectsMan->sceneControl2("IM30", "IM30", "ANIM30", "IM30", 24, false);
1157 			break;
1158 
1159 		case 31:
1160 			// Shooting target
1161 			_objectsMan->sceneControl("IM31", "IM31", "ANIM31", "IM31", 10, true);
1162 			break;
1163 
1164 		case 32:
1165 			_linesMan->setMaxLineIdx(20);
1166 			_globals->_characterMaxPosY = 445;
1167 			_objectsMan->sceneControl2("IM32", "IM32", "ANIM32", "IM32", 2, true);
1168 			break;
1169 
1170 		case 33:
1171 			_objectsMan->sceneControl("IM33", "IM33", "ANIM33", "IM33", 8, false);
1172 			break;
1173 
1174 		case 34:
1175 			// In the airport, before the flight cut-scene
1176 			_objectsMan->sceneControl("IM34", "IM34", "ANIM34", "IM34", 2, false);
1177 			break;
1178 
1179 		case 35:
1180 		case 36:
1181 		case 37:
1182 		case 38:
1183 		case 39:
1184 		case 40:
1185 		case 41: {
1186 			_linesMan->setMaxLineIdx(40);
1187 			_globals->_characterMaxPosY = 435;
1188 			_globals->_disableInventFl = false;
1189 			_objectsMan->_forestFl = true;
1190 			Common::String im = Common::String::format("IM%d", _globals->_exitId);
1191 			_soundMan->playSound(13);
1192 			if (_objectsMan->_forestSprite == NULL) {
1193 				_objectsMan->_forestSprite = _objectsMan->loadSprite("HOPDEG.SPR");
1194 				_soundMan->loadSample(1, "SOUND41.WAV");
1195 			}
1196 			_objectsMan->sceneControl2(im, im, "BANDIT", im, 13, false);
1197 			if (_globals->_exitId < 35 || _globals->_exitId > 49) {
1198 				_objectsMan->_forestSprite = _globals->freeMemory(_objectsMan->_forestSprite);
1199 				_objectsMan->_forestFl = false;
1200 				_soundMan->removeSample(1);
1201 			}
1202 			break;
1203 			}
1204 
1205 		case 50:
1206 			// Flight cut scene
1207 			playPlaneCutscene();
1208 			_globals->_exitId = 51;
1209 			break;
1210 
1211 		case 51:
1212 			_linesMan->setMaxLineIdx(10);
1213 			_globals->_characterMaxPosY = 440;
1214 			_objectsMan->sceneControl2("IM51", "IM51", "ANIM51", "IM51", 14, true);
1215 			break;
1216 
1217 		case 52:
1218 			_linesMan->setMaxLineIdx(15);
1219 			_globals->_characterMaxPosY = 445;
1220 			_objectsMan->sceneControl2("IM52", "IM52", "ANIM52", "IM52", 14, true);
1221 			break;
1222 
1223 		case 54:
1224 			_linesMan->setMaxLineIdx(30);
1225 			_globals->_characterMaxPosY = 440;
1226 			_objectsMan->sceneControl2("IM54", "IM54", "ANIM54", "IM54", 14, true);
1227 			break;
1228 
1229 		case 55:
1230 			_linesMan->setMaxLineIdx(30);
1231 			_globals->_characterMaxPosY = 460;
1232 			_objectsMan->sceneControl2("IM55", "IM55", "ANIM55", "IM55", 14, false);
1233 			break;
1234 
1235 		case 56:
1236 			_linesMan->setMaxLineIdx(30);
1237 			_globals->_characterMaxPosY = 440;
1238 			_objectsMan->sceneControl2("IM56", "IM56", "ANIM56", "IM56", 14, false);
1239 			break;
1240 
1241 		case 57:
1242 			_linesMan->setMaxLineIdx(30);
1243 			_globals->_characterMaxPosY = 440;
1244 			_objectsMan->sceneControl2("IM57", "IM57", "ANIM57", "IM57", 14, true);
1245 			break;
1246 
1247 		case 58:
1248 			_linesMan->setMaxLineIdx(30);
1249 			_globals->_characterMaxPosY = 440;
1250 			_objectsMan->sceneControl2("IM58", "IM58", "ANIM58", "IM58", 14, false);
1251 			break;
1252 
1253 		case 59:
1254 			_linesMan->setMaxLineIdx(5);
1255 			_globals->_characterMaxPosY = 445;
1256 			_objectsMan->sceneControl2("IM59", "IM59", "ANIM59", "IM59", 21, false);
1257 			break;
1258 
1259 		case 60:
1260 			_linesMan->setMaxLineIdx(30);
1261 			_globals->_characterMaxPosY = 440;
1262 			_objectsMan->sceneControl2("IM60", "IM60", "ANIM60", "IM60", 21, false);
1263 			break;
1264 
1265 		case 61:
1266 			if (_globals->_saveData->_data[svBaseElevatorCond1] == 1 && !_globals->_saveData->_data[svBaseFireFl])
1267 				handleConflagration();
1268 			_objectsMan->sceneControl("IM61", "IM61", "ANIM61", "IM61", 21, false);
1269 			break;
1270 
1271 		case 62:
1272 			_linesMan->setMaxLineIdx(8);
1273 			_globals->_characterMaxPosY = 435;
1274 			_objectsMan->sceneControl2("IM62", "IM62", NULL, "IM62", 21, false);
1275 			break;
1276 
1277 		case 63:
1278 			_linesMan->setMaxLineIdx(30);
1279 			_globals->_characterMaxPosY = 435;
1280 			_objectsMan->sceneControl2("IM63", "IM63", "ANIM63", "IM63", 21, false);
1281 			break;
1282 
1283 		case 64:
1284 			_linesMan->setMaxLineIdx(30);
1285 			_globals->_characterMaxPosY = 435;
1286 			_objectsMan->sceneControl2("IM64", "IM64", "ANIM64", "IM64", 21, true);
1287 			break;
1288 
1289 		case 65:
1290 			_linesMan->setMaxLineIdx(30);
1291 			_globals->_characterMaxPosY = 435;
1292 			_objectsMan->sceneControl2("IM65", "IM65", "ANIM65", "IM65", 21, false);
1293 			break;
1294 
1295 		case 66:
1296 			_linesMan->setMaxLineIdx(5);
1297 			_globals->_characterMaxPosY = 445;
1298 			_objectsMan->sceneControl2("IM66", "IM66", "ANIM66", "IM66", 21, false);
1299 			break;
1300 
1301 		case 67:
1302 			_linesMan->setMaxLineIdx(8);
1303 			_globals->_characterMaxPosY = 435;
1304 			_objectsMan->sceneControl2("IM67", "IM67", NULL, "IM67", 21, false);
1305 			break;
1306 
1307 		case 68:
1308 			_linesMan->setMaxLineIdx(8);
1309 			_globals->_characterMaxPosY = 435;
1310 			_objectsMan->sceneControl2("IM68", "IM68", "ANIM68", "IM68", 21, true);
1311 			break;
1312 
1313 		case 69:
1314 			_linesMan->setMaxLineIdx(5);
1315 			_globals->_characterMaxPosY = 445;
1316 			_objectsMan->sceneControl2("IM69", "IM69", "ANIM69", "IM69", 21, false);
1317 			break;
1318 
1319 		case 70:
1320 			_linesMan->setMaxLineIdx(8);
1321 			_globals->_characterMaxPosY = 435;
1322 			_objectsMan->sceneControl2("IM70", "IM70", NULL, "IM70", 21, false);
1323 			break;
1324 
1325 		case 71:
1326 			_linesMan->setMaxLineIdx(5);
1327 			_globals->_characterMaxPosY = 445;
1328 			_objectsMan->sceneControl2("IM71", "IM71", "ANIM71", "IM71", 21, false);
1329 			break;
1330 
1331 		case 73:
1332 			_linesMan->setMaxLineIdx(15);
1333 			_globals->_characterMaxPosY = 445;
1334 			if (_globals->_saveData->_data[svSecondElevatorAvailableFl] == 1)
1335 				_objectsMan->sceneControl2("IM73", "IM73A", "ANIM73", "IM73", 21, true);
1336 			else
1337 				_objectsMan->sceneControl2("IM73", "IM73", "ANIM73", "IM73", 21, true);
1338 			break;
1339 
1340 		case 75:
1341 			playSubmarineCutscene();
1342 			break;
1343 
1344 		case 77:
1345 			handleOceanMaze(77, "OCEAN01", DIR_RIGHT, 0, 84, 0, 0, 25);
1346 			break;
1347 
1348 		case 78:
1349 			handleOceanMaze(78, "OCEAN02", DIR_UP, 0, 91, 84, 0, 25);
1350 			break;
1351 
1352 		case 79:
1353 			handleOceanMaze(79, "OCEAN03", DIR_LEFT, 87, 0, 0, 83, 25);
1354 			break;
1355 
1356 		case 80:
1357 			handleOceanMaze(80, "OCEAN04", DIR_UP, 86, 88, 0, 81, 25);
1358 			break;
1359 
1360 		case 81:
1361 			handleOceanMaze(81, "OCEAN05", DIR_UP, 91, 82, 80, 85, 25);
1362 			break;
1363 
1364 		case 82:
1365 			handleOceanMaze(82, "OCEAN06", DIR_LEFT, 81, 0, 88, 0, 25);
1366 			break;
1367 
1368 		case 83:
1369 			handleOceanMaze(83, "OCEAN07", DIR_UP, 89, 0, 79, 88, 25);
1370 			break;
1371 
1372 		case 84:
1373 			handleOceanMaze(84, "OCEAN08", DIR_UP, 77, 0, 0, 78, 25);
1374 			break;
1375 
1376 		case 85:
1377 			handleOceanMaze(85, "OCEAN09", DIR_UP, 0, 0, 81, 0, 25);
1378 			break;
1379 
1380 		case 86:
1381 			handleOceanMaze(86, "OCEAN10", DIR_UP, 0, 80, 0, 91, 25);
1382 			break;
1383 
1384 		case 87:
1385 			handleOceanMaze(87, "OCEAN11", DIR_RIGHT, 0, 79, 90, 0, 25);
1386 			break;
1387 
1388 		case 88:
1389 			handleOceanMaze(88, "OCEAN12", DIR_UP, 80, 0, 83, 82, 25);
1390 			break;
1391 
1392 		case 89:
1393 			handleOceanMaze(89, "OCEAN13", DIR_RIGHT, 0, 83, 0, 0, 25);
1394 			break;
1395 
1396 		case 90:
1397 			playUnderwaterBaseCutscene();
1398 			break;
1399 
1400 		case 91:
1401 			handleOceanMaze(91, "OCEAN15", DIR_RIGHT, 78, 81, 86, 0, 25);
1402 			break;
1403 
1404 		case 93:
1405 			_linesMan->setMaxLineIdx(5);
1406 			_globals->_characterMaxPosY = 445;
1407 			if (_globals->_saveData->_data[svEscapeLeftJailFl]) {
1408 				if (getPlatform() == Common::kPlatformLinux || getPlatform() == Common::kPlatformWindows)
1409 					_objectsMan->sceneControl2("IM93", "IM93C", "ANIM93", "IM93", 29, true);
1410 				else
1411 					_objectsMan->sceneControl2("IM93", "IM93C", "ANIM93", "IM93", 26, true);
1412 			} else {
1413 				if (getPlatform() == Common::kPlatformLinux || getPlatform() == Common::kPlatformWindows)
1414 					_objectsMan->sceneControl2("IM93", "IM93", "ANIM93", "IM93", 29, true);
1415 				else
1416 					_objectsMan->sceneControl2("IM93", "IM93", "ANIM93", "IM93", 26, true);
1417 			}
1418 			break;
1419 
1420 		case 94:
1421 			_linesMan->setMaxLineIdx(5);
1422 			_globals->_characterMaxPosY = 440;
1423 			_objectsMan->sceneControl2("IM94", "IM94", "ANIM94", "IM94", 19, true);
1424 			break;
1425 
1426 		case 95:
1427 			_linesMan->setMaxLineIdx(5);
1428 			_globals->_characterMaxPosY = 435;
1429 			_objectsMan->sceneControl2("IM95", "IM95", "ANIM95", "IM95", 19, false);
1430 			break;
1431 
1432 		case 96:
1433 			_linesMan->setMaxLineIdx(5);
1434 			_globals->_characterMaxPosY = 435;
1435 			_objectsMan->sceneControl2("IM96", "IM96", "ANIM96", "IM96", 19, false);
1436 			break;
1437 
1438 		case 97:
1439 			_linesMan->setMaxLineIdx(5);
1440 			_globals->_characterMaxPosY = 435;
1441 			_objectsMan->sceneControl2("IM97", "IM97", "ANIM97", "IM97", 19, false);
1442 			if (_globals->_exitId == 18) {
1443 				_globals->_eventMode = EVENTMODE_IGNORE;
1444 				_soundMan->stopSound();
1445 				_graphicsMan->clearScreen();
1446 				_graphicsMan->clearPalette();
1447 				_soundMan->playSound(6);
1448 				_animMan->playAnim("PURG1A.ANM", "PURG1.ANM", 12, 18, 50);
1449 				_graphicsMan->fadeOutShort();
1450 				_globals->_eventMode = EVENTMODE_DEFAULT;
1451 			}
1452 			break;
1453 
1454 		case 98:
1455 			_linesMan->setMaxLineIdx(5);
1456 			_globals->_characterMaxPosY = 435;
1457 			_objectsMan->sceneControl2("IM98", "IM98", "ANIM98", "IM98", 19, true);
1458 			break;
1459 
1460 		case 99:
1461 			_linesMan->setMaxLineIdx(5);
1462 			_globals->_characterMaxPosY = 435;
1463 			_objectsMan->sceneControl2("IM99", "IM99", "ANIM99", "IM99", 19, true);
1464 			break;
1465 
1466 		case 100:
1467 			playEnding();
1468 			break;
1469 
1470 		case 111:
1471 			_objectsMan->sceneControl("IM111", "IM111", "ANIM111", "IM111", 10, false);
1472 			break;
1473 
1474 		case 112:
1475 			_objectsMan->sceneControl("IM112", "IM112", "ANIM112", "IM112", 10, false);
1476 			break;
1477 
1478 		case 113:
1479 			_globals->_prevScreenId = _globals->_screenId;
1480 			_globals->_screenId = 113;
1481 			_globals->_saveData->_data[svLastPrevScreenId] = _globals->_prevScreenId;
1482 			_globals->_saveData->_data[svLastScreenId] = _globals->_screenId;
1483 			_globals->_exitId = 0;
1484 			_computer->showComputer(COMPUTER_HOPKINS);
1485 			_graphicsMan->clearScreen();
1486 			_graphicsMan->updateScreen();
1487 			memset(_graphicsMan->_frontBuffer, 0, 307200);
1488 			memset(_graphicsMan->_backBuffer, 0, 307200);
1489 			_graphicsMan->clearPalette();
1490 			_graphicsMan->resetDirtyRects();
1491 			break;
1492 
1493 		case 114:
1494 			_globals->_exitId = 0;
1495 			_globals->_prevScreenId = _globals->_screenId;
1496 			_globals->_screenId = 114;
1497 			_globals->_saveData->_data[svLastPrevScreenId] = _globals->_prevScreenId;
1498 			_globals->_saveData->_data[svLastScreenId] = _globals->_screenId;
1499 			_computer->showComputer(COMPUTER_SAMANTHA);
1500 			_graphicsMan->clearScreen();
1501 			break;
1502 
1503 		case 115:
1504 			_globals->_prevScreenId = _globals->_screenId;
1505 			_globals->_screenId = 115;
1506 			_globals->_saveData->_data[svLastPrevScreenId] = _globals->_prevScreenId;
1507 			_globals->_saveData->_data[svLastScreenId] = _globals->_screenId;
1508 			_globals->_exitId = 0;
1509 			_computer->showComputer(COMPUTER_PUBLIC);
1510 			_graphicsMan->clearScreen();
1511 			break;
1512 
1513 		case 150:
1514 			_soundMan->playSound(16);
1515 			_globals->_eventMode = EVENTMODE_IGNORE;
1516 			_graphicsMan->clearScreen();
1517 			_graphicsMan->clearPalette();
1518 			if (getPlatform() == Common::kPlatformLinux)
1519 				_graphicsMan->_fadingFl = true;
1520 			_animMan->playAnim("JOUR1A.ANM", "JOUR1A.ANM", 12, 12, 2000);
1521 			_globals->_eventMode = EVENTMODE_DEFAULT;
1522 			_globals->_exitId = 300;
1523 			break;
1524 
1525 		case 151:
1526 			_soundMan->playSound(16);
1527 			_globals->_eventMode = EVENTMODE_IGNORE;
1528 			_graphicsMan->clearScreen();
1529 			_graphicsMan->clearPalette();
1530 			if (getPlatform() == Common::kPlatformLinux)
1531 				_graphicsMan->_fadingFl = true;
1532 			_animMan->playAnim("JOUR3A.ANM", "JOUR3A.ANM", 12, 12, 2000);
1533 			_globals->_eventMode = EVENTMODE_DEFAULT;
1534 			_globals->_exitId = 300;
1535 			break;
1536 
1537 		case 152:
1538 			_soundMan->playSound(16);
1539 			_globals->_eventMode = EVENTMODE_IGNORE;
1540 			_graphicsMan->clearScreen();
1541 			_graphicsMan->clearPalette();
1542 			if (getPlatform() == Common::kPlatformLinux)
1543 				_graphicsMan->_fadingFl = true;
1544 			_animMan->playAnim("JOUR4A.ANM", "JOUR4A.ANM", 12, 12, 2000);
1545 			_globals->_eventMode = EVENTMODE_DEFAULT;
1546 			_globals->_exitId = 300;
1547 			break;
1548 
1549 		case 194:
1550 		case 195:
1551 		case 196:
1552 		case 197:
1553 		case 198:
1554 		case 199:
1555 			_globals->_characterSpriteBuf = _globals->freeMemory(_globals->_characterSpriteBuf);
1556 			_globals->_eventMode = EVENTMODE_IGNORE;
1557 			_soundMan->stopSound();
1558 			_soundMan->playSound(23);
1559 			_globals->_exitId = handleBaseMap();	// Handles the base map (non-Windows)
1560 			//_globals->_exitId = WBASE();	// Handles the 3D Doom level (Windows)
1561 			_soundMan->stopSound();
1562 			_globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR");
1563 			_globals->_characterType = CHARACTER_HOPKINS;
1564 			_globals->_eventMode = EVENTMODE_DEFAULT;
1565 			_graphicsMan->_lineNbr = SCREEN_WIDTH;
1566 			break;
1567 		}
1568 	}
1569 	_globals->_characterSpriteBuf = _globals->freeMemory(_globals->_characterSpriteBuf);
1570 	restoreSystem();
1571 	return true;
1572 }
1573 
getRandomNumber(int maxNumber)1574 int HopkinsEngine::getRandomNumber(int maxNumber) {
1575 	return _randomSource.getRandomNumber(maxNumber);
1576 }
1577 
initializeSystem()1578 void HopkinsEngine::initializeSystem() {
1579 	// Set graphics mode
1580 	_graphicsMan->setGraphicalMode(SCREEN_WIDTH, SCREEN_HEIGHT);
1581 
1582 	// Synchronize the sound settings from ScummVM
1583 	_soundMan->syncSoundSettings();
1584 
1585 	const Common::FSNode gameDataDir(ConfMan.get("path"));
1586 	SearchMan.addSubDirectoryMatching(gameDataDir, "SYSTEM");
1587 	SearchMan.addSubDirectoryMatching(gameDataDir, "LINK");
1588 	SearchMan.addSubDirectoryMatching(gameDataDir, "BUFFER");
1589 	SearchMan.addSubDirectoryMatching(gameDataDir, "ANIM");
1590 	SearchMan.addSubDirectoryMatching(gameDataDir, "ANM");
1591 	SearchMan.addSubDirectoryMatching(gameDataDir, "BASE");
1592 	SearchMan.addSubDirectoryMatching(gameDataDir, "MUSIC");
1593 	SearchMan.addSubDirectoryMatching(gameDataDir, "SEQ");
1594 	SearchMan.addSubDirectoryMatching(gameDataDir, "SAVE");
1595 	SearchMan.addSubDirectoryMatching(gameDataDir, "SOUND");
1596 	SearchMan.addSubDirectoryMatching(gameDataDir, "SVGA");
1597 	SearchMan.addSubDirectoryMatching(gameDataDir, "VOICE");
1598 	SearchMan.addSubDirectoryMatching(gameDataDir, "TSVGA");
1599 
1600 	_globals->clearAll();
1601 
1602 	_events->initMouseData();
1603 	_fontMan->initData();
1604 
1605 	_dialog->loadIcons();
1606 	_objectsMan->_headSprites = _fileIO->loadFile("TETE.SPR");
1607 
1608 	_events->setMouseOn();
1609 	_events->_mouseFl = false;
1610 
1611 	_globals->loadCharacterData();
1612 
1613 	_events->_mouseOffset.x = 0;
1614 	_events->_mouseOffset.y = 0;
1615 }
1616 
1617 /**
1618  * Play the intro of the game
1619  */
playIntro()1620 void HopkinsEngine::playIntro() {
1621 	// Win95 EN demo doesn't include the intro
1622 	if ((getLanguage() == Common::EN_ANY) && (getPlatform() == Common::kPlatformWindows) && (getIsDemo()))
1623 		return;
1624 
1625 	byte paletteData[PALETTE_EXT_BLOCK_SIZE];
1626 	byte paletteData2[PALETTE_EXT_BLOCK_SIZE];
1627 
1628 	memset(&paletteData, 0, PALETTE_EXT_BLOCK_SIZE);
1629 	_events->refreshScreenAndEvents();
1630 	_events->_mouseFl = false;
1631 	_globals->_eventMode = EVENTMODE_IGNORE;
1632 	_events->refreshScreenAndEvents();
1633 	_soundMan->playSound(16);
1634 	_animMan->setClearAnimFlag();
1635 
1636 	_animMan->playAnim("J1.ANM", "J1.ANM", 12, 12, 50);
1637 	if (shouldQuit() || _events->_escKeyFl)
1638 		return;
1639 	_events->mouseOff();
1640 	_soundMan->mixVoice(1, 3);
1641 	_animMan->playAnim("J2.ANM", "J2.ANM", 12, 12, 50);
1642 
1643 	if (shouldQuit() || _events->_escKeyFl)
1644 		return;
1645 
1646 	_events->mouseOff();
1647 	_soundMan->mixVoice(2, 3);
1648 	_animMan->playAnim("J3.ANM", "J3.ANM", 12, 12, 50);
1649 
1650 	if (shouldQuit() || _events->_escKeyFl)
1651 		return;
1652 
1653 	_events->mouseOff();
1654 	_soundMan->mixVoice(3, 3);
1655 	_graphicsMan->clearScreen();
1656 	_graphicsMan->clearPalette();
1657 	_graphicsMan->updateScreen();
1658 	_soundMan->playSound(11);
1659 	_graphicsMan->loadImage("intro1");
1660 	_graphicsMan->scrollScreen(0);
1661 	_graphicsMan->_scrollOffset = 0;
1662 	_graphicsMan->setColorPercentage(252, 100, 100, 100);
1663 	_graphicsMan->setColorPercentage(253, 100, 100, 100);
1664 	_graphicsMan->setColorPercentage(251, 100, 100, 100);
1665 	_graphicsMan->setColorPercentage(254, 0, 0, 0);
1666 
1667 	_events->delay(500);
1668 
1669 	_globals->_eventMode = EVENTMODE_IGNORE;
1670 	_graphicsMan->fadeInLong();
1671 	if (_graphicsMan->_largeScreenFl) {
1672 		_graphicsMan->_scrollStatus = 2;
1673 		_graphicsMan->_scrollPosX = 0;
1674 
1675 		bool loopCond = false;
1676 		do {
1677 			_graphicsMan->_scrollPosX += 2;
1678 			if (_graphicsMan->_scrollPosX > (SCREEN_WIDTH - 2)) {
1679 				_graphicsMan->_scrollPosX = SCREEN_WIDTH;
1680 				loopCond = true;
1681 			}
1682 
1683 			if (_events->getMouseX() < _graphicsMan->_scrollPosX + 10)
1684 				_events->setMouseXY(_events->_mousePos.x + 4, _events->getMouseY());
1685 			_events->refreshScreenAndEvents();
1686 		} while (!shouldQuit() && !loopCond && _graphicsMan->_scrollPosX != SCREEN_WIDTH);
1687 
1688 		_events->refreshScreenAndEvents();
1689 		_graphicsMan->_scrollStatus = 0;
1690 
1691 		if (shouldQuit())
1692 			return;
1693 	}
1694 
1695 	_soundMan->mixVoice(4, 3);
1696 	_graphicsMan->fadeOutLong();
1697 	_graphicsMan->_scrollStatus = 0;
1698 	_graphicsMan->loadImage("intro2");
1699 	_graphicsMan->scrollScreen(0);
1700 	_animMan->loadAnim("INTRO2");
1701 	_graphicsMan->displayAllBob();
1702 	_soundMan->playSound(23);
1703 	_objectsMan->stopBobAnimation(3);
1704 	_objectsMan->stopBobAnimation(5);
1705 	_graphicsMan->_scrollOffset = 0;
1706 	_graphicsMan->setColorPercentage(252, 100, 100, 100);
1707 	_graphicsMan->setColorPercentage(253, 100, 100, 100);
1708 	_graphicsMan->setColorPercentage(251, 100, 100, 100);
1709 	_graphicsMan->setColorPercentage(254, 0, 0, 0);
1710 
1711 	for (int i = 0; i <= 4; i++)
1712 		_events->refreshScreenAndEvents();
1713 
1714 	_globals->_eventMode = EVENTMODE_IGNORE;
1715 	_graphicsMan->fadeInLong();
1716 	for (uint i = 0; i < 200 / _globals->_speed; ++i)
1717 		_events->refreshScreenAndEvents();
1718 
1719 	_objectsMan->setBobAnimation(3);
1720 	_soundMan->mixVoice(5, 3);
1721 	_objectsMan->stopBobAnimation(3);
1722 	_events->refreshScreenAndEvents();
1723 	memcpy(&paletteData2, _graphicsMan->_palette, 796);
1724 
1725 	_graphicsMan->setPaletteVGA256WithRefresh(paletteData, _graphicsMan->_frontBuffer);
1726 	_graphicsMan->endDisplayBob();
1727 
1728 	if (shouldQuit() || _events->_escKeyFl)
1729 		return;
1730 
1731 	_soundMan->_specialSoundNum = 5;
1732 	_graphicsMan->_fadingFl = true;
1733 	_animMan->playAnim("ELEC.ANM", "ELEC.ANM", 10, 26, 200);
1734 	_soundMan->_specialSoundNum = 0;
1735 
1736 	if (shouldQuit() || _events->_escKeyFl)
1737 		return;
1738 
1739 	_graphicsMan->loadImage("intro2");
1740 	_graphicsMan->scrollScreen(0);
1741 	_animMan->loadAnim("INTRO2");
1742 	_graphicsMan->displayAllBob();
1743 	_soundMan->playSound(23);
1744 	_objectsMan->stopBobAnimation(3);
1745 	_objectsMan->stopBobAnimation(5);
1746 	_objectsMan->stopBobAnimation(1);
1747 	_graphicsMan->_scrollOffset = 0;
1748 	_graphicsMan->setColorPercentage(252, 100, 100, 100);
1749 	_graphicsMan->setColorPercentage(253, 100, 100, 100);
1750 	_graphicsMan->setColorPercentage(251, 100, 100, 100);
1751 	_graphicsMan->setColorPercentage(254, 0, 0, 0);
1752 
1753 	for (int i = 0; i <= 3; i++)
1754 		_events->refreshScreenAndEvents();
1755 
1756 	_globals->_eventMode = EVENTMODE_IGNORE;
1757 	_graphicsMan->setPaletteVGA256WithRefresh(paletteData2, _graphicsMan->_frontBuffer);
1758 
1759 	int introIndex = 0;
1760 	while (!shouldQuit() && !_events->_escKeyFl) {
1761 		if (introIndex == 12) {
1762 			_objectsMan->setBobAnimation(3);
1763 			_events->refreshScreenAndEvents();
1764 			_soundMan->mixVoice(6, 3);
1765 			_events->refreshScreenAndEvents();
1766 			_objectsMan->stopBobAnimation(3);
1767 		}
1768 
1769 		Common::copy(&paletteData2[0], &paletteData2[PALETTE_BLOCK_SIZE], &_graphicsMan->_palette[0]);
1770 
1771 		for (int i = 1, maxPalVal = 4 * introIndex; i <= PALETTE_BLOCK_SIZE; i++) {
1772 			if (_graphicsMan->_palette[i] > maxPalVal)
1773 				_graphicsMan->_palette[i] -= maxPalVal;
1774 		}
1775 
1776 		_graphicsMan->setPaletteVGA256WithRefresh(_graphicsMan->_palette, _graphicsMan->_frontBuffer);
1777 
1778 		for (int i = 1; i < 2 * introIndex; i++)
1779 			_events->refreshScreenAndEvents();
1780 
1781 		_graphicsMan->setPaletteVGA256WithRefresh(paletteData2, _graphicsMan->_frontBuffer);
1782 
1783 		for (int i = 1; i < 20 - introIndex; i++)
1784 			_events->refreshScreenAndEvents();
1785 
1786 		introIndex += 2;
1787 		if (introIndex > 15) {
1788 			_graphicsMan->setPaletteVGA256WithRefresh(paletteData, _graphicsMan->_frontBuffer);
1789 			for (uint j = 1; j < 100 / _globals->_speed; ++j)
1790 				_events->refreshScreenAndEvents();
1791 
1792 			_objectsMan->setBobAnimation(3);
1793 			_soundMan->mixVoice(7, 3);
1794 			_objectsMan->stopBobAnimation(3);
1795 
1796 			for (uint k = 1; k < 60 / _globals->_speed; ++k)
1797 				_events->refreshScreenAndEvents();
1798 			_objectsMan->setBobAnimation(5);
1799 			for (uint l = 0; l < 20 / _globals->_speed; ++l)
1800 				_events->refreshScreenAndEvents();
1801 
1802 			Common::copy(&paletteData2[0], &paletteData2[PALETTE_BLOCK_SIZE], &_graphicsMan->_palette[0]);
1803 			_graphicsMan->setPaletteVGA256WithRefresh(_graphicsMan->_palette, _graphicsMan->_frontBuffer);
1804 
1805 			for (uint m = 0; m < 50 / _globals->_speed; ++m) {
1806 				if (m == 30 / _globals->_speed) {
1807 					_objectsMan->setBobAnimation(3);
1808 					_soundMan->mixVoice(8, 3);
1809 					_objectsMan->stopBobAnimation(3);
1810 				}
1811 
1812 				_events->refreshScreenAndEvents();
1813 			}
1814 
1815 			_graphicsMan->fadeOutLong();
1816 			_graphicsMan->endDisplayBob();
1817 			_soundMan->playSound(3);
1818 			_soundMan->_specialSoundNum = 1;
1819 			_animMan->setClearAnimFlag();
1820 			_animMan->playAnim("INTRO1.ANM", "INTRO1.ANM", 10, 24, 18);
1821 			_soundMan->_specialSoundNum = 0;
1822 			if (shouldQuit() || _events->_escKeyFl)
1823 				return;
1824 
1825 			_animMan->playAnim("INTRO2.ANM", "INTRO2.ANM", 10, 24, 18);
1826 			if (shouldQuit() || _events->_escKeyFl)
1827 				return;
1828 
1829 			_animMan->playAnim("INTRO3.ANM", "INTRO3.ANM", 10, 24, 200);
1830 			if (shouldQuit() || _events->_escKeyFl)
1831 				return;
1832 
1833 			_graphicsMan->_fadingFl = true;
1834 			_animMan->unsetClearAnimFlag();
1835 			_animMan->playAnim("J4.ANM", "J4.ANM", 12, 12, 1000);
1836 			break;
1837 		}
1838 	}
1839 
1840 	_events->_escKeyFl = false;
1841 }
1842 
1843 /**
1844  * If in demo, displays a 'not available' screen and returns to the city map
1845  */
displayNotAvailable()1846 void HopkinsEngine::displayNotAvailable() {
1847 	if (!getIsDemo())
1848 		return;
1849 
1850 	if (_globals->_language == LANG_FR)
1851 		_graphicsMan->loadImage("ndfr");
1852 	else
1853 		_graphicsMan->loadImage("nduk");
1854 
1855 	_graphicsMan->fadeInLong();
1856 	if (_soundMan->_voiceOffFl)
1857 		_events->delay(500);
1858 	else
1859 		_soundMan->mixVoice(628, 4);
1860 
1861 	_graphicsMan->fadeOutLong();
1862 	_globals->_exitId = 4;
1863 }
1864 
handleNotAvailable(int nextScreen)1865 void HopkinsEngine::handleNotAvailable(int nextScreen) {
1866 	// Use the code of the Linux demo instead of the code of the Windows demo.
1867 	// The behavior is somewhat better, and common code is easier to maintain.
1868 	displayNotAvailable();
1869 	_globals->_exitId = nextScreen;
1870 }
1871 
displayEndDemo()1872 void HopkinsEngine::displayEndDemo() {
1873 	_soundMan->playSound(28);
1874 	if (_globals->_language == LANG_FR)
1875 		_graphicsMan->loadImage("endfr");
1876 	else
1877 		_graphicsMan->loadImage("enduk");
1878 
1879 	_graphicsMan->fadeInLong();
1880 	_events->delay(1500);
1881 	_graphicsMan->fadeOutLong();
1882 	_globals->_exitId = 0;
1883 }
1884 
bombExplosion()1885 void HopkinsEngine::bombExplosion() {
1886 	_graphicsMan->_lineNbr = SCREEN_WIDTH;
1887 	_graphicsMan->setScreenWidth(SCREEN_WIDTH);
1888 	_graphicsMan->clearScreen();
1889 	_graphicsMan->clearPalette();
1890 
1891 	_globals->_eventMode = EVENTMODE_IGNORE;
1892 	_soundMan->_specialSoundNum = 199;
1893 	_graphicsMan->_fadingFl = true;
1894 	_animMan->playAnim("BOMBE2A.ANM", "BOMBE2.ANM", 50, 14, 500);
1895 	_soundMan->_specialSoundNum = 0;
1896 	_graphicsMan->loadImage("IM15");
1897 	_animMan->loadAnim("ANIM15");
1898 	_graphicsMan->displayAllBob();
1899 	_objectsMan->stopBobAnimation(7);
1900 
1901 	for (int idx = 0; idx < 5; ++idx) {
1902 		_events->refreshScreenAndEvents();
1903 	}
1904 
1905 	_graphicsMan->fadeInLong();
1906 	_events->mouseOff();
1907 
1908 	for (int idx = 0; idx < 20; ++idx) {
1909 		_events->refreshScreenAndEvents();
1910 	}
1911 
1912 	_globals->_introSpeechOffFl = true;
1913 	_talkMan->startStaticCharacterDialogue("vire.pe2");
1914 	_globals->_introSpeechOffFl = false;
1915 	_objectsMan->setBobAnimation(7);
1916 
1917 	for (int idx = 0; idx < 100; ++idx) {
1918 		_events->refreshScreenAndEvents();
1919 	}
1920 
1921 	_graphicsMan->fadeOutLong();
1922 	_graphicsMan->endDisplayBob();
1923 	_globals->_eventMode = EVENTMODE_DEFAULT;
1924 	_globals->_exitId = 151;
1925 }
1926 
restoreSystem()1927 void HopkinsEngine::restoreSystem() {
1928 	_events->refreshEvents();
1929 }
1930 
endLinuxDemo()1931 void HopkinsEngine::endLinuxDemo() {
1932 	_globals->_linuxEndDemoFl = true;
1933 	_graphicsMan->resetDirtyRects();
1934 	_objectsMan->_forestFl = false;
1935 	_events->_breakoutFl = false;
1936 	_globals->_disableInventFl = true;
1937 	_graphicsMan->loadImage("BOX");
1938 	_soundMan->playSound(28);
1939 	_graphicsMan->fadeInLong();
1940 	_events->mouseOn();
1941 	_events->changeMouseCursor(0);
1942 	_events->_mouseCursorId = 0;
1943 	_events->_mouseSpriteId = 0;
1944 
1945 	bool mouseClicked = false;
1946 
1947 	do {
1948 		_events->refreshScreenAndEvents();
1949 
1950 		if (_events->getMouseButton() == 1)
1951 			mouseClicked = true;
1952 	} while (!mouseClicked && !shouldQuit());
1953 
1954 	// Original tried to open a web browser link here. Since ScummVM doesn't support
1955 	// that, it's being skipped in favor of simply exiting
1956 
1957 	_graphicsMan->fadeOutLong();
1958 }
1959 
handleConflagration()1960 void HopkinsEngine::handleConflagration() {
1961 	_globals->_disableInventFl = true;
1962 	_globals->_eventMode = EVENTMODE_IGNORE;
1963 	_graphicsMan->loadImage("IM71");
1964 	_animMan->loadAnim("ANIM71");
1965 	_graphicsMan->setColorPercentage(252, 100, 100, 100);
1966 	_graphicsMan->setColorPercentage(253, 100, 100, 100);
1967 	_graphicsMan->setColorPercentage(251, 100, 100, 100);
1968 	_graphicsMan->setColorPercentage(254, 0, 0, 0);
1969 	_graphicsMan->displayAllBob();
1970 
1971 	for (int cpt = 0; cpt <= 4; cpt++)
1972 		_events->refreshScreenAndEvents();
1973 
1974 	_graphicsMan->fadeInLong();
1975 	_globals->_eventMode = EVENTMODE_IGNORE;
1976 
1977 	for (int cpt = 0; cpt <= 249; cpt++)
1978 		_events->refreshScreenAndEvents();
1979 
1980 	_globals->_introSpeechOffFl = true;
1981 	_talkMan->startAnimatedCharacterDialogue("SVGARD1.pe2");
1982 	_globals->_introSpeechOffFl = false;
1983 
1984 	for (int cpt = 0; cpt <= 49; cpt++)
1985 		_events->refreshScreenAndEvents();
1986 
1987 	_graphicsMan->fadeOutLong();
1988 	_graphicsMan->endDisplayBob();
1989 	_globals->_saveData->_data[svBaseFireFl] = 1;
1990 	_globals->_disableInventFl = false;
1991 }
1992 
playSubmarineCutscene()1993 void HopkinsEngine::playSubmarineCutscene() {
1994 	_globals->_eventMode = EVENTMODE_IGNORE;
1995 	_graphicsMan->_lineNbr = SCREEN_WIDTH;
1996 	_graphicsMan->clearScreen();
1997 	_graphicsMan->clearPalette();
1998 	_soundMan->playSound(25);
1999 	_animMan->setClearAnimFlag();
2000 	_animMan->playAnim("BASE00A.ANM", "BASE00.ANM", 10, 18, 18);
2001 	if (!_events->_escKeyFl)
2002 		_animMan->playAnim("BASE05A.ANM", "BASE05.ANM", 10, 18, 18);
2003 	if (!_events->_escKeyFl)
2004 		_animMan->playAnim("BASE10A.ANM", "BASE10.ANM", 10, 18, 18);
2005 	if (!_events->_escKeyFl)
2006 		_animMan->playAnim("BASE20A.ANM", "BASE20.ANM", 10, 18, 18);
2007 	// CHECKME: The original code was doing the opposite test, which was a bug.
2008 	if (!_events->_escKeyFl)
2009 		_animMan->playAnim("BASE30A.ANM", "BASE30.ANM", 10, 18, 18);
2010 	if (!_events->_escKeyFl)
2011 		_animMan->playAnim("BASE40A.ANM", "BASE40.ANM", 10, 18, 18);
2012 	if (!_events->_escKeyFl)
2013 		_animMan->playAnim("BASE50A.ANM", "BASE50.ANM", 10, 18, 18);
2014 	if (!_events->_escKeyFl)
2015 		_animMan->playAnim("OC00A.ANM", "OC00.ANM", 10, 18, 18);
2016 	if (!_events->_escKeyFl)
2017 		_animMan->playAnim("OC05A.ANM", "OC05.ANM", 10, 18, 18);
2018 	if (!_events->_escKeyFl)
2019 		_animMan->playAnim("OC10A.ANM", "OC10.ANM", 10, 18, 18);
2020 	if (!_events->_escKeyFl)
2021 		_animMan->playAnim("OC20A.ANM", "OC20.ANM", 10, 18, 18);
2022 	if (!_events->_escKeyFl) {
2023 		_graphicsMan->_fadingFl = true;
2024 		_animMan->playAnim("OC30A.ANM", "OC30.ANM", 10, 18, 18);
2025 	}
2026 
2027 	_events->_escKeyFl = false;
2028 	_animMan->unsetClearAnimFlag();
2029 	_globals->_exitId = 85;
2030 }
2031 
playUnderwaterBaseCutscene()2032 void HopkinsEngine::playUnderwaterBaseCutscene() {
2033 	_graphicsMan->clearScreen();
2034 	_graphicsMan->clearPalette();
2035 	_soundMan->playSound(26);
2036 	_globals->_eventMode = EVENTMODE_IGNORE;
2037 	_globals->_disableInventFl = true;
2038 	_graphicsMan->_fadingFl = true;
2039 	_animMan->playSequence("abase.seq", 50, 15, 50, false, false, true);
2040 	_graphicsMan->loadImage("IM92");
2041 	_animMan->loadAnim("ANIM92");
2042 	_graphicsMan->displayAllBob();
2043 	_objectsMan->loadLinkFile("IM92");
2044 /*
2045 	for (int cpt = 0; cpt <= 4 && !shouldQuit(); cpt++)
2046 		_eventsManager->refreshScreenAndEvents();
2047 */
2048 	_graphicsMan->fadeInLong();
2049 	_objectsMan->enableHidingBehavior();
2050 
2051 	do {
2052 		_events->refreshScreenAndEvents();
2053 	} while (!shouldQuit() && _objectsMan->getBobAnimDataIdx(8) != 22);
2054 
2055 	if (!shouldQuit()) {
2056 		_graphicsMan->fadeOutLong();
2057 		_graphicsMan->endDisplayBob();
2058 		_objectsMan->resetHidingItems();
2059 		_globals->_disableInventFl = false;
2060 		_globals->_exitId = 93;
2061 		_globals->_eventMode = EVENTMODE_DEFAULT;
2062 	}
2063 }
2064 
playEnding()2065 void HopkinsEngine::playEnding() {
2066 	_globals->_characterSpriteBuf = _globals->freeMemory(_globals->_characterSpriteBuf);
2067 	_dialog->disableInvent();
2068 	_globals->_disableInventFl = true;
2069 	_graphicsMan->_scrollOffset = 0;
2070 	_globals->_cityMapEnabledFl = false;
2071 	_globals->_eventMode = EVENTMODE_IGNORE;
2072 	_soundMan->playSound(26);
2073 	_linesMan->_route = NULL;
2074 	_globals->_freezeCharacterFl = true;
2075 	_globals->_exitId = 0;
2076 	_soundMan->loadSample(1, "SOUND90.WAV");
2077 	_graphicsMan->loadImage("IM100");
2078 	_animMan->loadAnim("ANIM100");
2079 	_graphicsMan->displayAllBob();
2080 	_events->mouseOn();
2081 	_objectsMan->stopBobAnimation(7);
2082 	_objectsMan->stopBobAnimation(8);
2083 	_objectsMan->stopBobAnimation(9);
2084 	_graphicsMan->setColorPercentage(252, 100, 100, 100);
2085 	_graphicsMan->setColorPercentage(253, 100, 100, 100);
2086 	_graphicsMan->setColorPercentage(251, 100, 100, 100);
2087 	_graphicsMan->setColorPercentage(254, 0, 0, 0);
2088 	_events->changeMouseCursor(0);
2089 
2090 	for (int cpt = 0; cpt <= 4; cpt++)
2091 		_events->refreshScreenAndEvents();
2092 
2093 	_graphicsMan->fadeInLong();
2094 	_globals->_eventMode = EVENTMODE_IGNORE;
2095 
2096 	do {
2097 		_events->refreshScreenAndEvents();
2098 	} while (_objectsMan->getBobAnimDataIdx(6) != 54);
2099 
2100 	_globals->_introSpeechOffFl = true;
2101 	_talkMan->startAnimatedCharacterDialogue("GM4.PE2");
2102 	_globals->_disableInventFl = true;
2103 	_objectsMan->stopBobAnimation(6);
2104 	_objectsMan->stopBobAnimation(10);
2105 	_objectsMan->setBobAnimation(9);
2106 	_objectsMan->setBobAnimation(7);
2107 
2108 	do {
2109 		_events->refreshScreenAndEvents();
2110 	} while (_objectsMan->getBobAnimDataIdx(7) != 54);
2111 
2112 	_soundMan->playSample(1);
2113 
2114 	do {
2115 		_events->refreshScreenAndEvents();
2116 	} while (_objectsMan->getBobAnimDataIdx(7) != 65);
2117 
2118 	_globals->_introSpeechOffFl = true;
2119 	_talkMan->startAnimatedCharacterDialogue("DUELB4.PE2");
2120 	_events->mouseOff();
2121 	_globals->_disableInventFl = true;
2122 
2123 	do {
2124 		_events->refreshScreenAndEvents();
2125 	} while (_objectsMan->getBobAnimDataIdx(7) != 72);
2126 
2127 	_globals->_introSpeechOffFl = true;
2128 	_talkMan->startAnimatedCharacterDialogue("DUELH1.PE2");
2129 
2130 	do {
2131 		_events->refreshScreenAndEvents();
2132 	} while (_objectsMan->getBobAnimDataIdx(7) != 81);
2133 
2134 	_globals->_introSpeechOffFl = true;
2135 	_talkMan->startAnimatedCharacterDialogue("DUELB5.PE2");
2136 
2137 	do {
2138 		_events->refreshScreenAndEvents();
2139 	} while (_objectsMan->getBobAnimDataIdx(7) != 120);
2140 
2141 	_objectsMan->stopBobAnimation(7);
2142 	if (_globals->_saveData->_data[svGameWonFl] == 1) {
2143 		_soundMan->_specialSoundNum = 200;
2144 		_soundMan->_skipRefreshFl = true;
2145 		_graphicsMan->_fadingFl = true;
2146 		_animMan->playAnim("BERM.ANM", "BERM.ANM", 100, 24, 300);
2147 		_graphicsMan->endDisplayBob();
2148 		_soundMan->removeSample(1);
2149 		_graphicsMan->loadImage("PLAN3");
2150 		_graphicsMan->fadeInLong();
2151 
2152 		_events->_rateCounter = 0;
2153 		if (!_events->_escKeyFl) {
2154 			do {
2155 				_events->refreshEvents();
2156 			} while (_events->_rateCounter < 2000 / _globals->_speed && !_events->_escKeyFl);
2157 		}
2158 		_events->_escKeyFl = false;
2159 		_graphicsMan->fadeOutLong();
2160 		_globals->_eventMode = EVENTMODE_IGNORE;
2161 		_soundMan->_specialSoundNum = 0;
2162 		_graphicsMan->_fadingFl = true;
2163 		_animMan->playAnim("JOUR2A.anm", "JOUR2A.anm", 12, 12, 1000);
2164 		_soundMan->playSound(11);
2165 		_graphicsMan->clearScreen();
2166 		_graphicsMan->clearPalette();
2167 		_animMan->playAnim("FF1a.anm", "FF1.anm", 18, 18, 9);
2168 		_animMan->playAnim("FF1a.anm", "FF1.anm", 9, 18, 9);
2169 		_animMan->playAnim("FF1a.anm", "FF1.anm", 9, 18, 18);
2170 		_animMan->playAnim("FF1a.anm", "FF1.anm", 9, 18, 9);
2171 		_animMan->playAnim("FF2a.anm", "FF2.anm", 24, 24, 100);
2172 		_events->mouseOff();
2173 		displayCredits();
2174 		_globals->_eventMode = EVENTMODE_DEFAULT;
2175 		_globals->_exitId = 300;
2176 		_dialog->enableInvent();
2177 		_globals->_disableInventFl = false;
2178 	} else {
2179 		_soundMan->_specialSoundNum = 200;
2180 		_soundMan->_skipRefreshFl = true;
2181 		_animMan->playAnim2("BERM.ANM", "BERM.ANM", 100, 24, 300);
2182 		_objectsMan->stopBobAnimation(7);
2183 		_objectsMan->setBobAnimation(8);
2184 		_globals->_introSpeechOffFl = true;
2185 		_talkMan->startAnimatedCharacterDialogue("GM5.PE2");
2186 		_globals->_disableInventFl = true;
2187 
2188 		do {
2189 			_events->refreshScreenAndEvents();
2190 		} while (_objectsMan->getBobAnimDataIdx(8) != 5);
2191 
2192 		_soundMan->directPlayWav("SOUND41.WAV");
2193 
2194 		do {
2195 			_events->refreshScreenAndEvents();
2196 		} while (_objectsMan->getBobAnimDataIdx(8) != 21);
2197 
2198 		_graphicsMan->fadeOutLong();
2199 		_graphicsMan->endDisplayBob();
2200 		_soundMan->removeSample(1);
2201 		_soundMan->playSound(16);
2202 		_globals->_eventMode = EVENTMODE_IGNORE;
2203 		_soundMan->_specialSoundNum = 0;
2204 		_dialog->enableInvent();
2205 		_globals->_disableInventFl = false;
2206 		_animMan->playAnim("JOUR4A.ANM", "JOUR4A.ANM", 12, 12, 1000);
2207 		_globals->_eventMode = EVENTMODE_DEFAULT;
2208 		_globals->_exitId = 300;
2209 	}
2210 	_globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR");
2211 	_globals->_characterType = CHARACTER_HOPKINS;
2212 	_globals->_eventMode = EVENTMODE_DEFAULT;
2213 }
2214 
playPlaneCutscene()2215 void HopkinsEngine::playPlaneCutscene() {
2216 	_soundMan->playSound(28);
2217 	_globals->_eventMode = EVENTMODE_IGNORE;
2218 	_graphicsMan->clearScreen();
2219 	_graphicsMan->clearPalette();
2220 
2221 	_animMan->unsetClearAnimFlag();
2222 	_animMan->playAnim("AEROP00A.ANM", "AEROP00.ANM", 10, 18, 18);
2223 	if (!_events->_escKeyFl)
2224 		_animMan->playAnim("SEROP10A.ANM", "SEROP10A.ANM", 10, 18, 18);
2225 	if (!_events->_escKeyFl)
2226 		_animMan->playAnim("AEROP20A.ANM", "AEROP20.ANM", 10, 18, 18);
2227 	if (!_events->_escKeyFl)
2228 		_animMan->playAnim("AEROP30A.ANM", "AEROP30.ANM", 10, 18, 18);
2229 	if (!_events->_escKeyFl)
2230 		_animMan->playAnim("AEROP40A.ANM", "AEROP40.ANM", 10, 18, 18);
2231 	if (!_events->_escKeyFl)
2232 		_animMan->playAnim("AEROP50A.ANM", "AEROP50.ANM", 10, 18, 18);
2233 	if (!_events->_escKeyFl)
2234 		_animMan->playAnim("AEROP60A.ANM", "AEROP60.ANM", 10, 18, 18);
2235 	if (!_events->_escKeyFl)
2236 		_animMan->playAnim("AEROP70A.ANM", "AEROP70.ANM", 10, 18, 18);
2237 	if (!_events->_escKeyFl)
2238 		_animMan->playAnim("TRANS00A.ANM", "TRANS00.ANM", 10, 18, 18);
2239 	if (!_events->_escKeyFl)
2240 		_animMan->playAnim("TRANS10A.ANM", "TRANS10.ANM", 10, 18, 18);
2241 	if (!_events->_escKeyFl)
2242 		_animMan->playAnim("TRANS15A.ANM", "TRANS15.ANM", 10, 18, 18);
2243 	if (!_events->_escKeyFl)
2244 		_animMan->playAnim("TRANS20A.ANM", "TRANS20.ANM", 10, 18, 18);
2245 	if (!_events->_escKeyFl)
2246 		_animMan->playAnim("TRANS30A.ANM", "TRANS30.ANM", 10, 18, 18);
2247 	if (!_events->_escKeyFl)
2248 		_animMan->playAnim("TRANS40A.ANM", "TRANS40.ANM", 10, 18, 18);
2249 	if (!_events->_escKeyFl) {
2250 		_graphicsMan->_fadingFl = true;
2251 		_animMan->playAnim("PARA00A.ANM", "PARA00.ANM", 9, 9, 9);
2252 	} else {
2253 		_graphicsMan->fadeOutShort();
2254 	}
2255 
2256 	_events->_escKeyFl = false;
2257 	_animMan->unsetClearAnimFlag();
2258 }
2259 
loadBaseMap()2260 void HopkinsEngine::loadBaseMap() {
2261 	Common::String filename	= Common::String::format("%s.PCX", "PBASE");
2262 	Common::File f;
2263 
2264 	if (f.exists(filename)) {
2265 		// PBASE file exists, so go ahead and load it
2266 		_graphicsMan->loadImage("PBASE");
2267 	} else {
2268 		// PBASE file doesn't exist, so draw a substitute screen
2269 		drawBaseMap();
2270 	}
2271 }
2272 
drawBaseMap()2273 void HopkinsEngine::drawBaseMap() {
2274 	memset(_graphicsMan->_backBuffer, 0, SCREEN_WIDTH * 2 * SCREEN_HEIGHT);
2275 
2276 	// List of rectangle areas to draw for exit points
2277 	const int rects[] = {
2278 		181, 66, 181 + 16, 66 + 22,
2279 		353, 116, 353 + 22, 116 + 16,
2280 		483, 250, 483 + 20, 250 + 25,
2281 		471, 326, 471 + 27, 326 + 20,
2282 		162, 365, 162 + 21, 365 + 23,
2283 		106, 267, 106 + 20, 267 + 26
2284 	};
2285 
2286 	// Loop through displaying
2287 	const int *rectP = &rects[0];
2288 	for (int rectIndex = 0; rectIndex < 6; ++rectIndex, rectP += 4) {
2289 		Common::Rect r(rectP[0], rectP[1], rectP[2], rectP[3]);
2290 
2291 		for (int yp = r.top; yp <= r.bottom; ++yp) {
2292 			byte *pDest = _graphicsMan->_backBuffer + yp * SCREEN_WIDTH + r.left;
2293 			Common::fill(pDest, pDest + r.width(), 0xff);
2294 		}
2295 	}
2296 
2297 	// Copy the calculated screen
2298 	memcpy(_graphicsMan->_frontBuffer, _graphicsMan->_backBuffer, SCREEN_WIDTH * 2 * SCREEN_HEIGHT);
2299 
2300 	// Write some explanatory text
2301 	_fontMan->displayText(40, 200, "ScummVM base map - select a square for different rooms", 255);
2302 }
2303 
handleBaseMap()2304 int HopkinsEngine::handleBaseMap() {
2305 	_globals->_disableInventFl = true;
2306 
2307 	// Load the map image
2308 	loadBaseMap();
2309 
2310 	// Set needed colors
2311 	_graphicsMan->setColorPercentage(252, 100, 100, 100);
2312 	_graphicsMan->setColorPercentage(253, 100, 100, 100);
2313 	_graphicsMan->setColorPercentage(251, 100, 100, 100);
2314 	_graphicsMan->setColorPercentage(254, 0, 0, 0);
2315 	_events->changeMouseCursor(0);
2316 	_graphicsMan->fadeInLong();
2317 	bool loopCond = false;
2318 	int zone;
2319 	do {
2320 		if (shouldQuit())
2321 			return 0;
2322 
2323 		int mouseButton = _events->getMouseButton();
2324 		int posX = _events->getMouseX();
2325 		int posY = _events->getMouseY();
2326 		zone = 0;
2327 		if ((posX - 181 <= 16) && (posY - 66 <= 22) &&
2328 		    (posX - 181 >= 0) && (posY - 66 >= 0))
2329 			zone = 1;
2330 		if ((posX - 353 <= 22) && (posY - 116 <= 19) &&
2331 		    (posX - 353 >= 0) && (posY - 116 >= 0))
2332 			zone = 2;
2333 		if ((posX - 483 <= 20) && (posY - 250 <= 25) &&
2334 		    (posX - 483 >= 0) && (posY - 250 >= 0))
2335 			zone = 3;
2336 		if ((posX - 471 <= 27) && (posY - 326 <= 20) &&
2337 		    (posX - 471 >= 0) && (posY - 326 >= 0))
2338 			zone = 4;
2339 		if ((posX - 162 <= 21) && (posY - 365 <= 23) &&
2340 		    (posX - 162 >= 0) && (posY - 365 >= 0))
2341 			zone = 5;
2342 		if ((posX - 106 <= 20) && (posY - 267 <= 26) &&
2343 		    (posX - 106 >= 0) && (posY - 267 >= 0))
2344 			zone = 6;
2345 		if (zone) {
2346 			_events->changeMouseCursor(4);
2347 			_globals->_baseMapColor += 25;
2348 			if (_globals->_baseMapColor > 100)
2349 				_globals->_baseMapColor = 0;
2350 			_graphicsMan->setColorPercentage2(251, _globals->_baseMapColor, _globals->_baseMapColor, _globals->_baseMapColor);
2351 		} else {
2352 			_events->changeMouseCursor(0);
2353 			_graphicsMan->setColorPercentage2(251, 100, 100, 100);
2354 		}
2355 		_events->refreshScreenAndEvents();
2356 		if ((mouseButton == 1) && zone)
2357 			loopCond = true;
2358 	} while (!loopCond);
2359 
2360 	_globals->_disableInventFl = false;
2361 	_graphicsMan->fadeOutLong();
2362 
2363 	int result;
2364 	switch (zone) {
2365 	case 1:
2366 		result = 94;
2367 		break;
2368 	case 2:
2369 		result = 95;
2370 		break;
2371 	case 3:
2372 		result = 96;
2373 		break;
2374 	case 4:
2375 		result = 97;
2376 		break;
2377 	case 5:
2378 		result = 98;
2379 		break;
2380 	case 6:
2381 		result = 99;
2382 		break;
2383 	default:
2384 		result = 0;
2385 		break;
2386 	}
2387 	return result;
2388 }
2389 
loadCredits()2390 void HopkinsEngine::loadCredits() {
2391 	_globals->_creditsPosY = 440;
2392 	_globals->_creditsStep = 45;
2393 	byte *bufPtr;
2394 	Common::String filename;
2395 	switch (_globals->_language) {
2396 	case LANG_EN:
2397 		filename = "CREAN.TXT";
2398 		break;
2399 	case LANG_FR:
2400 		filename = "CREFR.TXT";
2401 		break;
2402 	case LANG_SP:
2403 		filename = "CREES.TXT";
2404 		break;
2405 	default:
2406 		error("Unhandled language");
2407 		break;
2408 	}
2409 
2410 	if (!_fileIO->fileExists(filename)) {
2411 		_globals->_creditsLineNumb = 1;
2412 		_globals->_creditsItem[0]._color = '1';
2413 		_globals->_creditsItem[0]._actvFl = true;
2414 		_globals->_creditsItem[0]._linePosY = _globals->_creditsPosY;
2415 		strcpy((char *)_globals->_creditsItem[0]._line, "The End");
2416 		_globals->_creditsItem[0]._lineSize = 7;
2417 		return;
2418 	}
2419 
2420 	bufPtr = _fileIO->loadFile(filename);
2421 
2422 	byte *curPtr = bufPtr;
2423 	int idxLines = 0;
2424 	bool loopCond = false;
2425 	do {
2426 		if (*curPtr == '%') {
2427 			if (curPtr[1] == '%') {
2428 				loopCond = true;
2429 				break;
2430 			}
2431 			_globals->_creditsItem[idxLines]._color = curPtr[1];
2432 			_globals->_creditsItem[idxLines]._actvFl = true;
2433 			_globals->_creditsItem[idxLines]._linePosY = _globals->_creditsPosY + idxLines * _globals->_creditsStep;
2434 
2435 			int idxBuf = 0;
2436 			for(; idxBuf < 49; idxBuf++) {
2437 				byte curChar = curPtr[idxBuf + 3];
2438 				if (curChar == '%' || curChar == 10)
2439 					break;
2440 				_globals->_creditsItem[idxLines]._line[idxBuf] = curChar;
2441 			}
2442 			_globals->_creditsItem[idxLines]._line[idxBuf] = 0;
2443 			_globals->_creditsItem[idxLines]._lineSize = idxBuf - 1;
2444 			curPtr = curPtr + idxBuf + 2;
2445 			++idxLines;
2446 		} else {
2447 			curPtr++;
2448 		}
2449 		_globals->_creditsLineNumb = idxLines;
2450 	} while (!loopCond);
2451 
2452 	_globals->freeMemory(bufPtr);
2453 }
2454 
displayCredits(int startPosY,byte * buffer,char color)2455 void HopkinsEngine::displayCredits(int startPosY, byte *buffer, char color) {
2456 	byte *bufPtr = buffer;
2457 	int strWidth = 0;
2458 	byte curChar;
2459 	for (;;) {
2460 		curChar = *bufPtr++;
2461 		if (!curChar)
2462 			break;
2463 		if (curChar > 31)
2464 			strWidth += _objectsMan->getWidth(_fontMan->_font, curChar - 32);
2465 	}
2466 	int startPosX = 320 - strWidth / 2;
2467 	int endPosX = strWidth + startPosX;
2468 	int endPosY = startPosY + 12;
2469 	if ((_globals->_creditsStartX == -1) && (_globals->_creditsEndX == -1) && (_globals->_creditsStartY == -1) && (_globals->_creditsEndY == -1)) {
2470 		_globals->_creditsStartX = startPosX;
2471 		_globals->_creditsEndX = endPosX;
2472 		_globals->_creditsStartY = startPosY;
2473 		_globals->_creditsEndY = endPosY;
2474 	}
2475 
2476 	_globals->_creditsStartX = MIN(_globals->_creditsStartX, startPosX);
2477 	_globals->_creditsEndX = MAX(_globals->_creditsEndX, endPosX);
2478 	_globals->_creditsStartY = MIN(_globals->_creditsStartY, startPosY);
2479 	_globals->_creditsEndY = MAX(_globals->_creditsEndY, endPosY);
2480 
2481 	Common::String message = Common::String((char *)buffer);
2482 	_fontMan->displayText(startPosX, startPosY, message, color);
2483 }
2484 
displayCredits()2485 void HopkinsEngine::displayCredits() {
2486 	loadCredits();
2487 	_globals->_creditsPosY = 436;
2488 	_graphicsMan->loadImage("GENERIC");
2489 	_graphicsMan->fadeInLong();
2490 	_soundMan->playSound(28);
2491 	_events->_mouseFl = false;
2492 	_globals->_eventMode = EVENTMODE_CREDITS;
2493 	_globals->_creditsStartX = _globals->_creditsEndX = _globals->_creditsStartY = _globals->_creditsEndY = -1;
2494 	int soundId = 28;
2495 
2496 	do {
2497 		for (int i = 0; i < _globals->_creditsLineNumb; ++i) {
2498 			if (_globals->_creditsItem[i]._actvFl) {
2499 				int nextY = _globals->_creditsPosY + i * _globals->_creditsStep;
2500 				_globals->_creditsItem[i]._linePosY = nextY;
2501 
2502 				if ((nextY >= 51) && (nextY <= 460)) {
2503 					int col = 0;
2504 					switch (_globals->_creditsItem[i]._color) {
2505 					case '1':
2506 						col = 163;
2507 						break;
2508 					case '2':
2509 						col = 161;
2510 						break;
2511 					case '3':
2512 						col = 162;
2513 						break;
2514 					default:
2515 						warning("Unknown color, default to col #1");
2516 						col = 163;
2517 						break;
2518 					}
2519 					if (_globals->_creditsItem[i]._lineSize != -1)
2520 						displayCredits(nextY, _globals->_creditsItem[i]._line, col);
2521 				}
2522 			}
2523 		}
2524 		--_globals->_creditsPosY;
2525 		if (_globals->_creditsStartX != -1 || _globals->_creditsEndX != -1 || _globals->_creditsStartY != -1 || _globals->_creditsEndY != -1) {
2526 			_events->refreshScreenAndEvents();
2527 			_graphicsMan->copySurface(_graphicsMan->_backBuffer, 60, 50, 520, 430, _graphicsMan->_frontBuffer, 60, 50);
2528 		} else {
2529 			_events->refreshScreenAndEvents();
2530 		}
2531 		if (_globals->_creditsItem[_globals->_creditsLineNumb - 1]._linePosY <= 39) {
2532 			_globals->_creditsPosY = 440;
2533 			++soundId;
2534 			if (soundId > 31)
2535 				soundId = 28;
2536 			_soundMan->playSound(soundId);
2537 		}
2538 		_globals->_creditsStartX = -1;
2539 		_globals->_creditsEndX = -1;
2540 		_globals->_creditsStartY = -1;
2541 		_globals->_creditsEndY = -1;
2542 	} while ((_events->getMouseButton() != 1) && (!shouldQuit()));
2543 	_graphicsMan->fadeOutLong();
2544 	_globals->_eventMode = EVENTMODE_IGNORE;
2545 	_events->_mouseFl = true;
2546 }
2547 
handleOceanMouseEvents()2548 void HopkinsEngine::handleOceanMouseEvents() {
2549 	_fontMan->hideText(9);
2550 	if (_events->_mouseCursorId != 16)
2551 		return;
2552 
2553 	_events->getMouseX();
2554 	if (_objectsMan->_zoneNum <= 0)
2555 		return;
2556 
2557 	int oldPosX = _events->getMouseX();
2558 	int oldPosY = _events->getMouseY();
2559 	bool displAnim = false;
2560 	int oldX;
2561 	switch (_objectsMan->_zoneNum) {
2562 	case 1:
2563 		switch (_globals->_oceanDirection) {
2564 		case DIR_UP:
2565 			_objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "27,26,25,24,23,22,21,20,19,18,-1,", 6, false);
2566 			break;
2567 		case DIR_RIGHT:
2568 			_objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,-1,", 6, false);
2569 			break;
2570 		case DIR_DOWN:
2571 			_objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "9,10,11,12,13,14,15,16,17,18,-1,", 6, false);
2572 			break;
2573 		default:
2574 			break;
2575 		}
2576 
2577 		_globals->_oceanDirection = DIR_LEFT;
2578 		_globals->_exitId = 1;
2579 		oldX = _objectsMan->getSpriteX(0);
2580 		for (;;) {
2581 			if (_globals->_speed == 1)
2582 				oldX -= 2;
2583 			else if (_globals->_speed == 2)
2584 				oldX -= 4;
2585 			else if (_globals->_speed == 3)
2586 				oldX -= 6;
2587 			_objectsMan->setSpriteX(0, oldX);
2588 			setSubmarineSprites();
2589 			_events->refreshScreenAndEvents();
2590 			if (_events->getMouseButton() == 1 && oldPosX == _events->getMouseX() && _events->getMouseY() == oldPosY) {
2591 				displAnim = true;
2592 				break;
2593 			}
2594 
2595 			if (oldX <= -100)
2596 				break;
2597 		}
2598 		break;
2599 	case 2:
2600 		switch (_globals->_oceanDirection) {
2601 		case DIR_UP:
2602 			_objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "27,28,29,30,31,32,33,34,35,36,-1,", 6, false);
2603 			break;
2604 		case DIR_DOWN:
2605 			_objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "9,8,7,6,5,4,3,2,1,0,-1,", 6, false);
2606 			break;
2607 		case DIR_LEFT:
2608 			_objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,-1,", 6, false);
2609 			break;
2610 		default:
2611 			break;
2612 		}
2613 		_globals->_oceanDirection = DIR_RIGHT;
2614 		_globals->_exitId = 2;
2615 		oldX = _objectsMan->getSpriteX(0);
2616 		for (;;) {
2617 			if (_globals->_speed == 1)
2618 				oldX += 2;
2619 			else if (_globals->_speed == 2)
2620 				oldX += 4;
2621 			else if (_globals->_speed == 3)
2622 				oldX += 6;
2623 			_objectsMan->setSpriteX(0, oldX);
2624 			setSubmarineSprites();
2625 			_events->refreshScreenAndEvents();
2626 			if (_events->getMouseButton() == 1 && oldPosX == _events->getMouseX() && _events->getMouseY() == oldPosY) {
2627 				displAnim = true;
2628 				break;
2629 			}
2630 			if (oldX > 499)
2631 				break;
2632 		}
2633 		break;
2634 	case 3:
2635 		switch (_globals->_oceanDirection) {
2636 		case DIR_RIGHT:
2637 			oldX = _objectsMan->getSpriteX(0);
2638 			do {
2639 				if (_globals->_speed == 1)
2640 					oldX += 2;
2641 				else if (_globals->_speed == 2)
2642 					oldX += 4;
2643 				else if (_globals->_speed == 3)
2644 					oldX += 6;
2645 				_objectsMan->setSpriteX(0, oldX);
2646 				setSubmarineSprites();
2647 				_events->refreshScreenAndEvents();
2648 				if (_events->getMouseButton() == 1 && oldPosX == _events->getMouseX() && _events->getMouseY() == oldPosY) {
2649 					displAnim = true;
2650 					break;
2651 				}
2652 			} while (oldX <= 235);
2653 			if (!displAnim)
2654 				_objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "36,35,34,33,32,31,30,29,28,27,-1,", 6, false);
2655 			break;
2656 		case DIR_DOWN:
2657 			_objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,-1,", 6, false);
2658 			break;
2659 		case DIR_LEFT:
2660 			oldX = _objectsMan->getSpriteX(0);
2661 			do {
2662 				if (_globals->_speed == 1)
2663 					oldX -= 2;
2664 				else if (_globals->_speed == 2)
2665 					oldX -= 4;
2666 				else if (_globals->_speed == 3)
2667 					oldX -= 6;
2668 				_objectsMan->setSpriteX(0, oldX);
2669 				setSubmarineSprites();
2670 				_events->refreshScreenAndEvents();
2671 				if (_events->getMouseButton() == 1 && oldPosX == _events->getMouseX() && _events->getMouseY() == oldPosY) {
2672 					displAnim = true;
2673 					break;
2674 				}
2675 			} while (oldX > 236);
2676 			if (!displAnim)
2677 				_objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "18,19,20,21,22,23,24,25,26,27,-1,", 6, false);
2678 			break;
2679 		default:
2680 			break;
2681 		}
2682 		_globals->_oceanDirection = DIR_UP;
2683 		_globals->_exitId = 3;
2684 		break;
2685 	case 4:
2686 		switch (_globals->_oceanDirection) {
2687 		case DIR_UP:
2688 			_objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,-1,", 6, false);
2689 			break;
2690 		case DIR_RIGHT:
2691 			oldX = _objectsMan->getSpriteX(0);
2692 			do {
2693 				if (_globals->_speed == 1)
2694 					oldX += 2;
2695 				else if (_globals->_speed == 2)
2696 					oldX += 4;
2697 				else if (_globals->_speed == 3)
2698 					oldX += 6;
2699 				_objectsMan->setSpriteX(0, oldX);
2700 				setSubmarineSprites();
2701 				_events->refreshScreenAndEvents();
2702 				if (_events->getMouseButton() == 1 && oldPosX == _events->getMouseX() && _events->getMouseY() == oldPosY) {
2703 					displAnim = true;
2704 					break;
2705 				}
2706 			} while (oldX <= 235);
2707 			if (!displAnim)
2708 				_objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "0,1,2,3,4,5,6,7,8,9,-1,", 6, false);
2709 			break;
2710 		case DIR_LEFT:
2711 			oldX = _objectsMan->getSpriteX(0);
2712 			for (;;) {
2713 				if (_globals->_speed == 1)
2714 					oldX -= 2;
2715 				else if (_globals->_speed == 2)
2716 					oldX -= 4;
2717 				else if (_globals->_speed == 3)
2718 					oldX -= 6;
2719 				_objectsMan->setSpriteX(0, oldX);
2720 				setSubmarineSprites();
2721 				_events->refreshScreenAndEvents();
2722 				if (_events->getMouseButton() == 1 && oldPosX == _events->getMouseX() && _events->getMouseY() == oldPosY)
2723 					break;
2724 
2725 				if (oldX <= 236) {
2726 					if (!displAnim)
2727 						_objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "18,17,16,15,14,13,12,11,10,9,-1,", 6, false);
2728 					break;
2729 				}
2730 			}
2731 			break;
2732 		default:
2733 			break;
2734 		}
2735 		_globals->_oceanDirection = DIR_DOWN;
2736 		_globals->_exitId = 4;
2737 		break;
2738 	}
2739 }
2740 
setSubmarineSprites()2741 void HopkinsEngine::setSubmarineSprites() {
2742 	switch (_globals->_oceanDirection) {
2743 	case DIR_UP:
2744 		_objectsMan->setSpriteIndex(0, 27);
2745 		break;
2746 	case DIR_RIGHT:
2747 		_objectsMan->setSpriteIndex(0, 0);
2748 		break;
2749 	case DIR_DOWN:
2750 		_objectsMan->setSpriteIndex(0, 9);
2751 		break;
2752 	case DIR_LEFT:
2753 		_objectsMan->setSpriteIndex(0, 18);
2754 		break;
2755 	default:
2756 		break;
2757 	}
2758 }
2759 
handleOceanMaze(int16 curExitId,Common::String backgroundFilename,Directions defaultDirection,int16 exit1,int16 exit2,int16 exit3,int16 exit4,int16 soundId)2760 void HopkinsEngine::handleOceanMaze(int16 curExitId, Common::String backgroundFilename, Directions defaultDirection, int16 exit1, int16 exit2, int16 exit3, int16 exit4, int16 soundId) {
2761 	_globals->_cityMapEnabledFl = false;
2762 	_graphicsMan->_noFadingFl = false;
2763 	_globals->_freezeCharacterFl = false;
2764 	_globals->_exitId = 0;
2765 	_globals->_disableInventFl = true;
2766 	_soundMan->playSound(soundId);
2767 	_globals->_characterSpriteBuf = _fileIO->loadFile("VAISSEAU.SPR");
2768 	if (backgroundFilename.size())
2769 		_graphicsMan->loadImage(backgroundFilename);
2770 
2771 	if (curExitId == 77)
2772 		_objectsMan->loadLinkFile("IM77");
2773 	else if (curExitId == 84)
2774 		_objectsMan->loadLinkFile("IM84");
2775 	else if (curExitId == 91)
2776 		_objectsMan->loadLinkFile("IM91");
2777 	else
2778 		_objectsMan->loadLinkFile("ocean");
2779 
2780 	if (!exit1)
2781 		_linesMan->disableZone(1);
2782 	if (!exit2)
2783 		_linesMan->disableZone(2);
2784 	if (!exit3)
2785 		_linesMan->disableZone(3);
2786 	if (!exit4)
2787 		_linesMan->disableZone(4);
2788 
2789 	if (_globals->_oceanDirection == DIR_NONE)
2790 		_globals->_oceanDirection = defaultDirection;
2791 
2792 	switch (_globals->_oceanDirection) {
2793 	case DIR_UP:
2794 		_objectsMan->_characterPos.x = 236;
2795 		_objectsMan->_startSpriteIndex = 27;
2796 		break;
2797 	case DIR_RIGHT:
2798 		_objectsMan->_characterPos.x = -20;
2799 		_objectsMan->_startSpriteIndex = 0;
2800 		break;
2801 	case DIR_DOWN:
2802 		_objectsMan->_characterPos.x = 236;
2803 		_objectsMan->_startSpriteIndex = 9;
2804 		break;
2805 	case DIR_LEFT:
2806 		_objectsMan->_characterPos.x = 415;
2807 		_objectsMan->_startSpriteIndex = 18;
2808 		break;
2809 	default:
2810 		break;
2811 	}
2812 
2813 	_objectsMan->addStaticSprite(_globals->_characterSpriteBuf, Common::Point(_objectsMan->_characterPos.x, 110), 0, _objectsMan->_startSpriteIndex, 0, false, 0, 0);
2814 	_graphicsMan->setColorPercentage(252, 100, 100, 100);
2815 	_graphicsMan->setColorPercentage(253, 100, 100, 100);
2816 	_graphicsMan->setColorPercentage(251, 100, 100, 100);
2817 	_graphicsMan->setColorPercentage(254, 0, 0, 0);
2818 	_objectsMan->animateSprite(0);
2819 	_linesMan->_route = NULL;
2820 	_events->mouseOn();
2821 	_events->changeMouseCursor(4);
2822 
2823 	for (int cpt = 0; cpt <= 4; cpt++)
2824 		_events->refreshScreenAndEvents();
2825 
2826 	if (!_graphicsMan->_noFadingFl)
2827 		_graphicsMan->fadeInLong();
2828 	_graphicsMan->_noFadingFl = false;
2829 	_globals->_eventMode = EVENTMODE_IGNORE;
2830 
2831 	for (;;) {
2832 		int mouseButton = _events->getMouseButton();
2833 		if (mouseButton && mouseButton == 1)
2834 			handleOceanMouseEvents();
2835 		_linesMan->checkZone();
2836 		setSubmarineSprites();
2837 
2838 		_events->refreshScreenAndEvents();
2839 		if (_globals->_exitId || shouldQuit())
2840 			break;
2841 	}
2842 
2843 	if (_globals->_exitId == 1)
2844 		_globals->_exitId = exit1;
2845 	else if (_globals->_exitId == 2)
2846 		_globals->_exitId = exit2;
2847 	else if (_globals->_exitId == 3)
2848 		_globals->_exitId = exit3;
2849 	else if (_globals->_exitId == 4)
2850 		_globals->_exitId = exit4;
2851 	_graphicsMan->fadeOutLong();
2852 	_objectsMan->removeSprite(0);
2853 	_objectsMan->clearScreen();
2854 	_globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR");
2855 	_globals->_characterType = CHARACTER_HOPKINS;
2856 }
2857 
syncSoundSettings()2858 void HopkinsEngine::syncSoundSettings() {
2859 	Engine::syncSoundSettings();
2860 
2861 	_soundMan->syncSoundSettings();
2862 }
2863 
displayAdultDisclaimer()2864 bool HopkinsEngine::displayAdultDisclaimer() {
2865 	int buttonIndex;
2866 
2867 	_graphicsMan->_minX = 0;
2868 	_graphicsMan->_minY = 0;
2869 	_graphicsMan->_maxX = SCREEN_WIDTH;
2870 	_graphicsMan->_maxY = SCREEN_HEIGHT - 1;
2871 	_events->_breakoutFl = false;
2872 	_objectsMan->_forestFl = false;
2873 	_globals->_disableInventFl = true;
2874 	_globals->_exitId = 0;
2875 
2876 	_graphicsMan->loadImage("ADULT");
2877 	_graphicsMan->fadeInLong();
2878 	_events->mouseOn();
2879 	_events->changeMouseCursor(0);
2880 	_events->_mouseCursorId = 0;
2881 	_events->_mouseSpriteId = 0;
2882 
2883 	do {
2884 		int xp = _events->getMouseX();
2885 		int yp = _events->getMouseY();
2886 
2887 		buttonIndex = 0;
2888 		if (xp >= 37 && xp <= 169 && yp >= 406 && yp <= 445)
2889 			buttonIndex = 2;
2890 		else if (xp >= 424 && xp <= 602 && yp >= 406 && yp <= 445)
2891 			buttonIndex = 1;
2892 
2893 		_events->refreshScreenAndEvents();
2894 	} while (!shouldQuit() && (buttonIndex == 0 || _events->getMouseButton() != 1));
2895 
2896 	_globals->_disableInventFl = false;
2897 	_graphicsMan->fadeOutLong();
2898 
2899 	if (buttonIndex != 2) {
2900 		// Quit game
2901 		return false;
2902 	} else {
2903 		// Continue
2904 		_graphicsMan->_minX = 0;
2905 		_graphicsMan->_maxY = 20;
2906 		_graphicsMan->_maxX = SCREEN_WIDTH;
2907 		_graphicsMan->_maxY = SCREEN_HEIGHT - 20;
2908 		return true;
2909 	}
2910 }
2911 
isUnderwaterSubScene()2912 bool HopkinsEngine::isUnderwaterSubScene() {
2913 	return (_globals->_curRoomNum >= 77) && (_globals->_curRoomNum <= 89);
2914 }
2915 
2916 } // End of namespace Hopkins
2917