diff options
Diffstat (limited to 'engines/hopkins/hopkins.cpp')
-rw-r--r-- | engines/hopkins/hopkins.cpp | 2861 |
1 files changed, 2861 insertions, 0 deletions
diff --git a/engines/hopkins/hopkins.cpp b/engines/hopkins/hopkins.cpp new file mode 100644 index 0000000000..bf9509c0d4 --- /dev/null +++ b/engines/hopkins/hopkins.cpp @@ -0,0 +1,2861 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "hopkins/hopkins.h" +#include "hopkins/graphics.h" +#include "hopkins/files.h" +#include "hopkins/saveload.h" +#include "hopkins/sound.h" +#include "hopkins/talk.h" + +#include "common/scummsys.h" +#include "common/config-manager.h" +#include "common/debug-channels.h" +#include "common/events.h" +#include "common/file.h" + +namespace Hopkins { + +HopkinsEngine *g_vm; + +HopkinsEngine::HopkinsEngine(OSystem *syst, const HopkinsGameDescription *gameDesc) : Engine(syst), + _gameDescription(gameDesc), _randomSource("Hopkins") { + g_vm = this; + _animMan = new AnimationManager(this); + _computer = new ComputerManager(this); + _dialog = new DialogsManager(this); + _debug = new Debugger(this); + _events = new EventsManager(this); + _fileIO = new FileManager(this); + _fontMan = new FontManager(this); + _globals = new Globals(this); + _graphicsMan = new GraphicsManager(this); + _linesMan = new LinesManager(this); + _menuMan = new MenuManager(this); + _objectsMan = new ObjectsManager(this); + _saveLoad = new SaveLoadManager(this); + _script = new ScriptManager(this); + _soundMan = new SoundManager(this); + _talkMan = new TalkManager(this); + + _startGameSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1; +} + +HopkinsEngine::~HopkinsEngine() { + delete _talkMan; + delete _soundMan; + delete _script; + delete _saveLoad; + delete _objectsMan; + delete _menuMan; + delete _linesMan; + delete _graphicsMan; + delete _globals; + delete _fontMan; + delete _fileIO; + delete _events; + delete _debug; + delete _dialog; + delete _computer; + delete _animMan; +} + +Common::String HopkinsEngine::generateSaveName(int slot) { + return Common::String::format("%s.%03d", _targetName.c_str(), slot); +} + +/** + * Returns true if it is currently okay to restore a game + */ +bool HopkinsEngine::canLoadGameStateCurrently() { + return !_globals->_exitId && !_globals->_cityMapEnabledFl && _events->_mouseFl; +} + +/** + * Returns true if it is currently okay to save the game + */ +bool HopkinsEngine::canSaveGameStateCurrently() { + return !_globals->_exitId && !_globals->_cityMapEnabledFl && _events->_mouseFl; +} + +/** + * Load the savegame at the specified slot index + */ +Common::Error HopkinsEngine::loadGameState(int slot) { + return _saveLoad->loadGame(slot); +} + +/** + * Save the game to the given slot index, and with the given name + */ +Common::Error HopkinsEngine::saveGameState(int slot, const Common::String &desc) { + return _saveLoad->saveGame(slot, desc); +} + +Common::Error HopkinsEngine::run() { + _saveLoad->initSaves(); + + _globals->setConfig(); + _fileIO->initCensorship(); + initializeSystem(); + + if (!getIsDemo()) + runFull(); + else if (getPlatform() == Common::kPlatformLinux) + runLinuxDemo(); + else if (getPlatform() == Common::kPlatformWindows) + runWin95Demo(); + else { + warning("Unhandled version, switching to Linux demo. Please report this version to ScummVM developers"); + runLinuxDemo(); + } + + return Common::kNoError; +} + +bool HopkinsEngine::runWin95Demo() { + _objectsMan->loadObjects(); + _objectsMan->changeObject(14); + _objectsMan->addObject(14); + _objectsMan->_helicopterFl = false; + + _globals->_eventMode = EVENTMODE_IGNORE; + + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + + if (_startGameSlot == -1) { + _graphicsMan->loadImage("H2"); + _graphicsMan->fadeInLong(); + + if (!_events->_escKeyFl) + playIntro(); + } + + _events->_rateCounter = 0; + _globals->_eventMode = EVENTMODE_IGNORE; + _globals->_speed = 1; + + for (int i = 1; i < 50; i++) { + _graphicsMan->copySurface(_graphicsMan->_backBuffer, 0, 0, 640, 440, _graphicsMan->_frontBuffer, 0, 0); + _events->refreshScreenAndEvents(); + } + + _globals->_eventMode = EVENTMODE_DEFAULT; + if (_events->_rateCounter > 475) + _globals->_speed = 2; + if (_events->_rateCounter > 700) + _globals->_speed = 3; + + if (_startGameSlot == -1) { + _graphicsMan->fadeOutLong(); + _globals->_eventMode = EVENTMODE_IGNORE; + _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR"); + } + + _globals->_characterType = 0; + _objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0; + memset(_globals->_saveData, 0, 2000); + _globals->_exitId = 0; + + if (_startGameSlot != -1) + _saveLoad->loadGame(_startGameSlot); + + if (getLanguage() != Common::PL_POL) + if (!displayAdultDisclaimer()) + return Common::kNoError; + + for (;;) { + if (_globals->_exitId == 300) + _globals->_exitId = 0; + + if (!_globals->_exitId) { + _globals->_exitId = _menuMan->menu(); + if (_globals->_exitId == -1) { + _globals->_characterSpriteBuf = _globals->freeMemory(_globals->_characterSpriteBuf); + restoreSystem(); + return false; + } + } + + if (shouldQuit()) + return false; + + _globals->_curRoomNum = _globals->_exitId; + + switch (_globals->_exitId) { + case 1: + _linesMan->setMaxLineIdx(40); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM01", "IM01", "ANIM01", "IM01", 2, true); + break; + + case 3: + if (!_globals->_saveData->_data[svBankAttackAnimPlayedFl]) { + _soundMan->playSound(3); + if (getPlatform() == Common::kPlatformOS2 || getPlatform() == Common::kPlatformBeOS) + _graphicsMan->loadImage("fond"); + else { + if (_globals->_language == LANG_FR) + _graphicsMan->loadImage("fondfr"); + else if (_globals->_language == LANG_EN) + _graphicsMan->loadImage("fondan"); + else if (_globals->_language == LANG_SP) + _graphicsMan->loadImage("fondes"); + } + _graphicsMan->fadeInLong(); + _events->delay(500); + _graphicsMan->fadeOutLong(); + _globals->_eventMode = EVENTMODE_IGNORE; + _soundMan->_specialSoundNum = 2; + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + if (!_globals->_censorshipFl) + _animMan->playAnim("BANQUE.ANM", 200, 28, 200); + else + _animMan->playAnim("BANKUK.ANM", 200, 28, 200); + _soundMan->_specialSoundNum = 0; + _soundMan->removeSample(1); + _soundMan->removeSample(2); + _soundMan->removeSample(3); + _soundMan->removeSample(4); + _graphicsMan->fadeOutLong(); + _globals->_saveData->_data[svBankAttackAnimPlayedFl] = 1; + } + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 450; + _objectsMan->sceneControl2("IM03", "IM03", "ANIM03", "IM03", 2, false); + break; + + case 4: + _globals->_disableInventFl = true; + _objectsMan->handleCityMap(); + _globals->_disableInventFl = false; + break; + + case 5: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 455; + + if (_globals->_saveData->_data[svFreedHostageFl]) { + if (_globals->_saveData->_data[svFreedHostageFl] == 1) + _objectsMan->sceneControl2("IM05", "IM05A", "ANIM05B", "IM05", 3, false); + } else { + _objectsMan->sceneControl2("IM05", "IM05", "ANIM05", "IM05", 3, false); + } + break; + + case 6: + _linesMan->setMaxLineIdx(20); + _globals->_characterMaxPosY = 460; + _objectsMan->sceneControl2("IM06", "IM06", "ANIM06", "IM06", 2, true); + break; + + case 7: + if (_globals->_saveData->_data[svBombBoxOpenedFl]) + _objectsMan->sceneControl("BOMBEB", "BOMBE", "BOMBE", "BOMBE", 2, true); + else + _objectsMan->sceneControl("BOMBEA", "BOMBE", "BOMBE", "BOMBE", 2, true); + break; + + case 8: + _linesMan->setMaxLineIdx(15); + _globals->_characterMaxPosY = 450; + _objectsMan->sceneControl2("IM08", "IM08", "ANIM08", "IM08", 2, true); + break; + + case 9: + _globals->_characterMaxPosY = 440; + _linesMan->setMaxLineIdx(20); + if (_globals->_saveData->_data[svBombDisarmedFl]) + _objectsMan->sceneControl2("IM09", "IM09", "ANIM09", "IM09", 10, true); + else + bombExplosion(); + break; + + case 10: + _objectsMan->sceneControl("IM10", "IM10", "ANIM10", "IM10", 9, false); + break; + + case 11: + _linesMan->setMaxLineIdx(20); + _globals->_characterMaxPosY = 450; + _objectsMan->sceneControl2("IM11", "IM11", "ANIM11", "IM11", 2, false); + break; + + case 12: + _globals->_characterMaxPosY = 450; + _linesMan->setMaxLineIdx(20); + if (_globals->_saveData->_data[svBombDisarmedFl]) { + if (_globals->_language == LANG_FR) + _graphicsMan->loadImage("ENDFR"); + else + _graphicsMan->loadImage("ENDUK"); + _graphicsMan->fadeInLong(); + _events->mouseOn(); + do + _events->refreshScreenAndEvents(); + while (_events->getMouseButton() != 1); + _graphicsMan->fadeOutLong(); + restoreSystem(); + } else + bombExplosion(); + break; + + case 13: + case 14: + case 15: + handleNotAvailable(11); + break; + + case 16: + case 24: + case 25: + case 26: + case 27: + case 28: + case 29: + case 30: + case 31: + case 33: + case 32: + case 34: + handleNotAvailable(4); + break; + + case 17: + handleNotAvailable(1); + break; + + case 111: + _objectsMan->sceneControl("IM111", "IM111", "ANIM111", "IM111", 10, false); + break; + + case 112: + _objectsMan->sceneControl("IM112", "IM112", "ANIM112", "IM112", 10, false); + break; + + case 113: + _globals->_exitId = 0; + _globals->_prevScreenId = _globals->_screenId; + _globals->_saveData->_data[svLastPrevScreenId] = _globals->_screenId; + _globals->_screenId = 113; + _globals->_saveData->_data[svLastScreenId] = _globals->_screenId; + _computer->showComputer(COMPUTER_HOPKINS); + _graphicsMan->clearScreen(); + _graphicsMan->updateScreen(); + memset(_graphicsMan->_frontBuffer, 0, 307200); + memset(_graphicsMan->_backBuffer, 0, 307200); + _graphicsMan->clearPalette(); + _graphicsMan->resetDirtyRects(); + break; + + case 114: + _globals->_prevScreenId = _globals->_screenId; + _globals->_saveData->_data[svLastPrevScreenId] = _globals->_screenId; + _globals->_screenId = 114; + _globals->_saveData->_data[svLastScreenId] = _globals->_screenId; + _globals->_exitId = 0; + _computer->showComputer(COMPUTER_SAMANTHA); + _graphicsMan->clearScreen(); + break; + + case 115: + _globals->_exitId = 0; + _globals->_prevScreenId = _globals->_screenId; + _globals->_saveData->_data[svLastPrevScreenId] = _globals->_screenId; + _globals->_screenId = 115; + _globals->_saveData->_data[svLastScreenId] = _globals->_screenId; + _computer->showComputer(COMPUTER_PUBLIC); + _graphicsMan->clearScreen(); + break; + + case 150: + _soundMan->playSound(28); + _globals->_eventMode = EVENTMODE_ALT; // CHECKME! + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + _animMan->playAnim("JOUR1A.anm", 12, 12, 2000); + _globals->_eventMode = EVENTMODE_DEFAULT; + _globals->_exitId = 300; + break; + + case 151: + _soundMan->playSound(28); + _globals->_eventMode = EVENTMODE_ALT; // CHECKME! + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + _graphicsMan->loadImage("njour3a"); + _graphicsMan->fadeInLong(); + _events->delay(5000); + _graphicsMan->fadeOutLong(); + _globals->_exitId = 300; + _globals->_eventMode = EVENTMODE_DEFAULT; + break; + + case 152: + _soundMan->playSound(28); + _globals->_eventMode = EVENTMODE_ALT; // CHECKME! + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + _animMan->playAnim("JOUR4A.anm", 12, 12, 2000); + _globals->_eventMode = EVENTMODE_DEFAULT; + _globals->_exitId = 300; + break; + } + } + return true; +} + +bool HopkinsEngine::runLinuxDemo() { + _objectsMan->loadObjects(); + _objectsMan->changeObject(14); + _objectsMan->addObject(14); + _objectsMan->_helicopterFl = false; + + _events->mouseOff(); + + _graphicsMan->clearScreen(); + + if (_startGameSlot == -1) { + _graphicsMan->loadImage("LINUX"); + _graphicsMan->fadeInLong(); + _events->delay(1500); + _graphicsMan->fadeOutLong(); + + _graphicsMan->loadImage("H2"); + _graphicsMan->fadeInLong(); + _events->delay(500); + _graphicsMan->fadeOutLong(); + + if (!_events->_escKeyFl) + playIntro(); + } + + _globals->_eventMode = EVENTMODE_DEFAULT; + _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR"); + _globals->_characterType = 0; + _objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0; + memset(_globals->_saveData, 0, 2000); + _globals->_exitId = 0; + + if (_startGameSlot != -1) + _saveLoad->loadGame(_startGameSlot); + + for (;;) { + if (_globals->_exitId == 300) + _globals->_exitId = 0; + + if (!_globals->_exitId) { + _globals->_exitId = _menuMan->menu(); + if (_globals->_exitId == -1) { + if (!shouldQuit()) + endLinuxDemo(); + _globals->_characterSpriteBuf = _globals->freeMemory(_globals->_characterSpriteBuf); + restoreSystem(); + } + } + + if (shouldQuit()) + return false; + + _globals->_curRoomNum = _globals->_exitId; + + switch (_globals->_exitId) { + case 17: + case 18: + case 19: + case 20: + case 22: + case 23: + case 24: + case 27: + case 28: + case 29: + case 30: + case 31: + case 32: + case 34: + case 38: + displayNotAvailable(); + break; + + case 1: + _linesMan->setMaxLineIdx(40); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM01", "IM01", "ANIM01", "IM01", 1, true); + break; + + case 3: + if (!_globals->_saveData->_data[svBankAttackAnimPlayedFl]) { + _soundMan->playSound(3); + if (getPlatform() == Common::kPlatformOS2 || getPlatform() == Common::kPlatformBeOS) + _graphicsMan->loadImage("fond"); + else { + if (_globals->_language == LANG_FR) + _graphicsMan->loadImage("fondfr"); + else if (_globals->_language == LANG_EN) + _graphicsMan->loadImage("fondan"); + else if (_globals->_language == LANG_SP) + _graphicsMan->loadImage("fondes"); + } + _graphicsMan->fadeInLong(); + _events->delay(500); + _graphicsMan->fadeOutLong(); + _globals->_eventMode = EVENTMODE_IGNORE; + _soundMan->_specialSoundNum = 2; + + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + _graphicsMan->_fadingFl = true; + + if (!_globals->_censorshipFl) + _animMan->playAnim("BANQUE.ANM", 200, 28, 200); + else + _animMan->playAnim("BANKUK.ANM", 200, 28, 200); + _soundMan->_specialSoundNum = 0; + _soundMan->removeSample(1); + _soundMan->removeSample(2); + _soundMan->removeSample(3); + _soundMan->removeSample(4); + _globals->_saveData->_data[svBankAttackAnimPlayedFl] = 1; + } + + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 450; + _objectsMan->sceneControl2("IM03", "IM03", "ANIM03", "IM03", 2, false); + break; + + case 4: + _globals->_disableInventFl = true; + _objectsMan->handleCityMap(); + _globals->_disableInventFl = false; + break; + + case 5: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 455; + if (_globals->_saveData->_data[svFreedHostageFl] == 1) + _objectsMan->sceneControl2("IM05", "IM05A", "ANIM05B", "IM05", 3, false); + else + _objectsMan->sceneControl2("IM05", "IM05", "ANIM05", "IM05", 3, false); + break; + + case 6: + _linesMan->setMaxLineIdx(20); + _globals->_characterMaxPosY = 460; + _objectsMan->sceneControl2("IM06", "IM06", "ANIM06", "IM06", 2, true); + break; + + case 7: + if (_globals->_saveData->_data[svBombBoxOpenedFl]) + _objectsMan->sceneControl("BOMBEB", "BOMBE", "BOMBE", "BOMBE", 2, true); + else + _objectsMan->sceneControl("BOMBEA", "BOMBE", "BOMBE", "BOMBE", 2, true); + break; + + case 8: + _linesMan->setMaxLineIdx(15); + _globals->_characterMaxPosY = 450; + _objectsMan->sceneControl2("IM08", "IM08", "ANIM08", "IM08", 2, true); + break; + + case 9: + _linesMan->setMaxLineIdx(20); + _globals->_characterMaxPosY = 440; + + if (!_globals->_saveData->_data[svBombDisarmedFl]) + bombExplosion(); + else + _objectsMan->sceneControl2("IM09", "IM09", "ANIM09", "IM09", 10, true); + break; + + case 10: + _objectsMan->sceneControl("IM10", "IM10", "ANIM10", "IM10", 9, false); + break; + + case 11: + _linesMan->setMaxLineIdx(20); + _globals->_characterMaxPosY = 450; + _objectsMan->sceneControl2("IM11", "IM11", "ANIM11", "IM11", 2, false); + break; + + case 12: + _linesMan->setMaxLineIdx(20); + _globals->_characterMaxPosY = 450; + if (_globals->_saveData->_data[svBombDisarmedFl]) + _objectsMan->sceneControl2("IM12", "IM12", "ANIM12", "IM12", 1, false); + else + bombExplosion(); + break; + + case 13: + _linesMan->setMaxLineIdx(40); + _globals->_characterMaxPosY = 440; + _objectsMan->sceneControl2("IM13", "IM13", "ANIM13", "IM13", 1, true); + break; + + case 14: + _linesMan->setMaxLineIdx(40); + _globals->_characterMaxPosY = 440; + _objectsMan->sceneControl2("IM14", "IM14", "ANIM14", "IM14", 1, true); + break; + + case 15: + _objectsMan->sceneControl("IM15", "IM15", "ANIM15", "IM15", 29, false); + break; + + case 16: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 450; + + if (_globals->_saveData->_data[svForestAvailableFl] == 1) { + _objectsMan->sceneControl2("IM16", "IM16A", "ANIM16", "IM16", 7, true); + } else if (!_globals->_saveData->_data[svForestAvailableFl]) { + _objectsMan->sceneControl2("IM16", "IM16", "ANIM16", "IM16", 7, true); + } + break; + + case 25: + _linesMan->setMaxLineIdx(20); + _globals->_characterMaxPosY = 445; + _objectsMan->sceneControl2("IM25", "IM25", "ANIM25", "IM25", 30, true); + break; + + case 26: + _linesMan->setMaxLineIdx(40); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM26", "IM26", "ANIM26", "IM26", 30, true); + + case 33: + _objectsMan->sceneControl("IM33", "IM33", "ANIM33", "IM33", 8, false); + break; + + case 35: + displayEndDemo(); + break; + + case 111: + _objectsMan->sceneControl("IM111", "IM111", "ANIM111", "IM111", 10, false); + break; + + case 112: + _objectsMan->sceneControl("IM112", "IM112", "ANIM112", "IM112", 10, false); + break; + + case 113: + _globals->_exitId = 0; + _globals->_prevScreenId = _globals->_screenId; + _globals->_saveData->_data[svLastPrevScreenId] = _globals->_screenId; + _globals->_screenId = 113; + _globals->_saveData->_data[svLastScreenId] = 113; + _computer->showComputer(COMPUTER_HOPKINS); + + _graphicsMan->clearScreen(); + _graphicsMan->updateScreen(); + memset(_graphicsMan->_frontBuffer, 0, 307200); + memset(_graphicsMan->_backBuffer, 0, 307200); + _graphicsMan->clearPalette(); + _graphicsMan->resetDirtyRects(); + break; + + case 114: + _globals->_exitId = 0; + _globals->_prevScreenId = _globals->_screenId; + _globals->_saveData->_data[svLastPrevScreenId] = _globals->_screenId; + _globals->_screenId = 114; + _globals->_saveData->_data[svLastScreenId] = 114; + _computer->showComputer(COMPUTER_SAMANTHA); + _graphicsMan->clearScreen(); + break; + + case 115: + _globals->_exitId = 0; + _globals->_prevScreenId = _globals->_screenId; + _globals->_saveData->_data[svLastPrevScreenId] = _globals->_screenId; + _globals->_screenId = 115; + _globals->_saveData->_data[svLastScreenId] = 115; + _computer->showComputer(COMPUTER_PUBLIC); + _graphicsMan->clearScreen(); + break; + + case 150: + _soundMan->playSound(16); + _globals->_eventMode = EVENTMODE_IGNORE; + + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + _graphicsMan->_fadingFl = true; + _animMan->playAnim("JOUR1A.anm", 12, 12, 2000); + _globals->_eventMode = EVENTMODE_DEFAULT; + _globals->_exitId = 300; + break; + + case 151: + _soundMan->playSound(16); + _globals->_eventMode = EVENTMODE_IGNORE; + + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + _graphicsMan->_fadingFl = true; + _animMan->playAnim("JOUR3A.anm", 12, 12, 2000); + _globals->_eventMode = EVENTMODE_DEFAULT; + _globals->_exitId = 300; + break; + + case 152: + _soundMan->playSound(16); + _globals->_eventMode = EVENTMODE_IGNORE; + + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + _graphicsMan->_fadingFl = true; + _animMan->playAnim("JOUR4A.anm", 12, 12, 2000); + _globals->_eventMode = EVENTMODE_DEFAULT; + _globals->_exitId = 300; + break; + } + } + return true; +} + +bool HopkinsEngine::runFull() { + if (_startGameSlot == -1 && getPlatform() == Common::kPlatformLinux) + _soundMan->playSound(16); + + _objectsMan->loadObjects(); + _objectsMan->changeObject(14); + _objectsMan->addObject(14); + + if (getPlatform() == Common::kPlatformLinux) { + _objectsMan->_helicopterFl = false; + _events->mouseOff(); + // No code has been added to display the version as it's wrong + // in my copy: it mentions a Win95 version v4 using DirectDraw (Strangerke) + } else if (getPlatform() == Common::kPlatformWindows) { + _objectsMan->_helicopterFl = false; + _globals->_eventMode = EVENTMODE_IGNORE; + // This code displays the game version. + // It wasn't present in the original and could be put in the debugger + // It has been added there for debug purposes + if (_startGameSlot == -1) { + _graphicsMan->loadImage("VERSW"); + _graphicsMan->fadeInLong(); + _events->delay(500); + _graphicsMan->fadeOutLong(); + } + _graphicsMan->clearVesaScreen(); + } else { + // This piece of code, though named "display_version" in the original, + // displays a "loading please wait" screen. + if (_startGameSlot == -1) { + _graphicsMan->loadImage("VERSW"); + _graphicsMan->fadeInLong(); + _events->delay(500); + _graphicsMan->fadeOutLong(); + } + _graphicsMan->clearVesaScreen(); + + _globals->_eventMode = EVENTMODE_IGNORE; + } + + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + + if (_startGameSlot == -1) { + if (getPlatform() == Common::kPlatformLinux) { + _graphicsMan->loadImage("H2"); + _graphicsMan->fadeInLong(); + _events->delay(500); + _graphicsMan->fadeOutLong(); + _globals->_speed = 2; + _globals->_eventMode = EVENTMODE_IGNORE; + _graphicsMan->_fadingFl = true; + _animMan->playAnim("MP.ANM", 10, 16, 200); + } else { + _animMan->playAnim("MP.ANM", 10, 16, 200); + _graphicsMan->fadeOutLong(); + } + } + + if (!_events->_escKeyFl && _startGameSlot == -1) { + playIntro(); + if (shouldQuit()) + return false; + } + if (getPlatform() != Common::kPlatformLinux && _startGameSlot == -1) { + _graphicsMan->fadeOutShort(); + _graphicsMan->loadImage("H2"); + _graphicsMan->fadeInLong(); + _events->delay(500); + _graphicsMan->fadeOutLong(); + } + _globals->_eventMode = EVENTMODE_DEFAULT; + _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR"); + _globals->_characterType = 0; + _objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0; + memset(_globals->_saveData, 0, 2000); + + _globals->_exitId = 0; + + if (_startGameSlot != -1) + _saveLoad->loadGame(_startGameSlot); + + for (;;) { + if (_globals->_exitId == 300) + _globals->_exitId = 0; + if (!_globals->_exitId) { + _globals->_exitId = _menuMan->menu(); + if (_globals->_exitId == -1) { + _globals->_characterSpriteBuf = _globals->freeMemory(_globals->_characterSpriteBuf); + restoreSystem(); + return false; + } + } + + if (shouldQuit()) + return false; + + _globals->_curRoomNum = _globals->_exitId; + + switch (_globals->_exitId) { + case 1: + _linesMan->setMaxLineIdx(40); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM01", "IM01", "ANIM01", "IM01", 1, true); + break; + + case 3: + if (!_globals->_saveData->_data[svBankAttackAnimPlayedFl]) { + // Play the bank attack animation + _soundMan->playSound(3); + if (getPlatform() == Common::kPlatformOS2 || getPlatform() == Common::kPlatformBeOS) + _graphicsMan->loadImage("fond"); + else { + if (_globals->_language == LANG_FR) + _graphicsMan->loadImage("fondfr"); + else if (_globals->_language == LANG_EN) + _graphicsMan->loadImage("fondan"); + else if (_globals->_language == LANG_SP) + _graphicsMan->loadImage("fondes"); + } + _graphicsMan->fadeInLong(); + _events->delay(500); + _graphicsMan->fadeOutLong(); + _globals->_eventMode = EVENTMODE_IGNORE; + _soundMan->_specialSoundNum = 2; + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + if (getPlatform() == Common::kPlatformLinux || getPlatform() == Common::kPlatformWindows) { + if (getPlatform() == Common::kPlatformLinux) + _graphicsMan->_fadingFl = true; + + if (!_globals->_censorshipFl) + _animMan->playAnim("BANQUE.ANM", 200, 28, 200); + else + _animMan->playAnim("BANKUK.ANM", 200, 28, 200); + } else { + _animMan->playAnim("BANQUE.ANM", 200, 28, 200); + } + + _soundMan->_specialSoundNum = 0; + _soundMan->removeSample(1); + _soundMan->removeSample(2); + _soundMan->removeSample(3); + _soundMan->removeSample(4); + + if (getPlatform() != Common::kPlatformLinux) { + // Copy the end of the animation into the secondary buffer and fade out the screen + Common::fill(_graphicsMan->_frontBuffer, _graphicsMan->_frontBuffer + + SCREEN_WIDTH * 2 * SCREEN_HEIGHT, 0); + _graphicsMan->fadeOutLong(); + } + + _globals->_saveData->_data[svBankAttackAnimPlayedFl] = 1; + } + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 450; + _objectsMan->sceneControl2("IM03", "IM03", "ANIM03", "IM03", 2, false); + break; + + case 4: + _globals->_disableInventFl = true; + _objectsMan->handleCityMap(); + _globals->_disableInventFl = false; + break; + + case 5: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 455; + if (_globals->_saveData->_data[svFreedHostageFl] == 1) + _objectsMan->sceneControl2("IM05", "IM05A", "ANIM05B", "IM05", 3, false); + else + _objectsMan->sceneControl2("IM05", "IM05", "ANIM05", "IM05", 3, false); + break; + + case 6: + _linesMan->setMaxLineIdx(20); + _globals->_characterMaxPosY = 460; + _objectsMan->sceneControl2("IM06", "IM06", "ANIM06", "IM06", 2, true); + break; + + case 7: + if (_globals->_saveData->_data[svBombBoxOpenedFl]) + _objectsMan->sceneControl("BOMBEB", "BOMBE", "BOMBE", "BOMBE", 2, true); + else + _objectsMan->sceneControl("BOMBEA", "BOMBE", "BOMBE", "BOMBE", 2, true); + break; + + case 8: + _linesMan->setMaxLineIdx(15); + _globals->_characterMaxPosY = 450; + _objectsMan->sceneControl2("IM08", "IM08", "ANIM08", "IM08", 2, true); + break; + + case 9: + _linesMan->setMaxLineIdx(20); + _globals->_characterMaxPosY = 440; + if (_globals->_saveData->_data[svBombDisarmedFl]) + _objectsMan->sceneControl2("IM09", "IM09", "ANIM09", "IM09", 10, true); + else + bombExplosion(); + break; + + case 10: + _objectsMan->sceneControl("IM10", "IM10", "ANIM10", "IM10", 9, false); + break; + + case 11: + _linesMan->setMaxLineIdx(20); + _globals->_characterMaxPosY = 450; + _objectsMan->sceneControl2("IM11", "IM11", "ANIM11", "IM11", 2, false); + break; + + case 12: + _linesMan->setMaxLineIdx(20); + _globals->_characterMaxPosY = 450; + if (_globals->_saveData->_data[svBombDisarmedFl]) + _objectsMan->sceneControl2("IM12", "IM12", "ANIM12", "IM12", 1, false); + else + bombExplosion(); + break; + + case 13: + _linesMan->setMaxLineIdx(40); + _globals->_characterMaxPosY = 440; + _objectsMan->sceneControl2("IM13", "IM13", "ANIM13", "IM13", 1, true); + break; + + case 14: + _linesMan->setMaxLineIdx(40); + _globals->_characterMaxPosY = 440; + _objectsMan->sceneControl2("IM14", "IM14", "ANIM14", "IM14", 1, true); + break; + + case 15: + if (getPlatform() == Common::kPlatformLinux || getPlatform() == Common::kPlatformWindows) + _objectsMan->sceneControl("IM15", "IM15", "ANIM15", "IM15", 29, false); + else + _objectsMan->sceneControl("IM15", "IM15", "ANIM15", "IM15", 18, false); + break; + + case 16: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 450; + if (_globals->_saveData->_data[svForestAvailableFl] == 1) + _objectsMan->sceneControl2("IM16", "IM16A", "ANIM16", "IM16", 7, true); + else + _objectsMan->sceneControl2("IM16", "IM16", "ANIM16", "IM16", 7, true); + break; + + case 17: + _linesMan->setMaxLineIdx(40); + _globals->_characterMaxPosY = 440; + if (_globals->_saveData->_data[svHutBurningFl] == 1) + _objectsMan->sceneControl2("IM17", "IM17A", "ANIM17", "IM17", 11, true); + else if (!_globals->_saveData->_data[svHutBurningFl]) + _objectsMan->sceneControl2("IM17", "IM17", "ANIM17", "IM17", 11, true); + if (_globals->_exitId == 18) { + _globals->_eventMode = EVENTMODE_IGNORE; + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + _soundMan->stopSound(); + if (getPlatform() == Common::kPlatformLinux) { + _soundMan->playSound(29); + _graphicsMan->_fadingFl = true; + _animMan->playAnim("PURG1A.ANM", 12, 18, 50); + } else if (getPlatform() == Common::kPlatformWindows) { + _soundMan->playSound(29); + _animMan->playAnim("PURG1A.ANM", 12, 18, 50); + _graphicsMan->fadeOutShort(); + } else { + _soundMan->playSound(6); + _animMan->playAnim("PURG1A.ANM", 12, 18, 50); + _graphicsMan->fadeOutShort(); + } + _globals->_eventMode = EVENTMODE_DEFAULT; + } + break; + + case 18: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 450; + if (getPlatform() == Common::kPlatformLinux || getPlatform() == Common::kPlatformWindows) + _objectsMan->sceneControl2("IM18", "IM18", "ANIM18", "IM18", 29, false); + else + _objectsMan->sceneControl2("IM18", "IM18", "ANIM18", "IM18", 6, false); + break; + + case 19: + _linesMan->setMaxLineIdx(40); + _globals->_characterMaxPosY = 440; + if (_globals->_saveData->_data[svHeavenGuardGoneFl]) + _objectsMan->sceneControl2("IM19", "IM19A", "ANIM19", "IM19", 6, true); + else + _objectsMan->sceneControl2("IM19", "IM19", "ANIM19", "IM19", 6, true); + break; + + case 20: + _linesMan->setMaxLineIdx(10); + _globals->_characterMaxPosY = 440; + _objectsMan->sceneControl2("IM20", "IM20", "ANIM20", "IM20", 6, true); + if (_globals->_exitId == 17) { + _globals->_eventMode = EVENTMODE_IGNORE; + _soundMan->stopSound(); + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + _soundMan->playSound(6); + if (getPlatform() == Common::kPlatformLinux) + _graphicsMan->_fadingFl = true; + _animMan->playAnim("PURG2A.ANM", 12, 18, 50); + if (getPlatform() != Common::kPlatformLinux) + _graphicsMan->fadeOutShort(); + _globals->_eventMode = EVENTMODE_DEFAULT; + } + break; + + case 22: + _linesMan->setMaxLineIdx(20); + _globals->_characterMaxPosY = 445; + _objectsMan->sceneControl2("IM22", "IM22", "ANIM22", "IM22", 6, true); + break; + + case 23: + _linesMan->setMaxLineIdx(20); + _globals->_characterMaxPosY = 440; + _objectsMan->sceneControl2("IM23", "IM23", "ANIM23", "IM23", 6, true); + break; + + case 24: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 450; + if (_globals->_saveData->_data[svCinemaDogGoneFl] == 1) + _objectsMan->sceneControl2("IM24", "IM24A", "ANIM24", "IM24", 1, true); + else + _objectsMan->sceneControl2("IM24", "IM24", "ANIM24", "IM24", 1, true); + break; + + case 25: + _linesMan->setMaxLineIdx(20); + _globals->_characterMaxPosY = 445; + if (getPlatform() == Common::kPlatformLinux || getPlatform() == Common::kPlatformWindows) + _objectsMan->sceneControl2("IM25", "IM25", "ANIM25", "IM25", 30, true); + else + _objectsMan->sceneControl2("IM25", "IM25", "ANIM25", "IM25", 8, true); + break; + + case 26: + _linesMan->setMaxLineIdx(40); + _globals->_characterMaxPosY = 435; + if (getPlatform() == Common::kPlatformLinux || getPlatform() == Common::kPlatformWindows) + _objectsMan->sceneControl2("IM26", "IM26", "ANIM26", "IM26", 30, true); + else + _objectsMan->sceneControl2("IM26", "IM26", "ANIM26", "IM26", 8, true); + break; + + case 27: + _linesMan->setMaxLineIdx(15); + _globals->_characterMaxPosY = 440; + if (_globals->_saveData->_data[svPoolDogGoneFl] == 1) + _objectsMan->sceneControl2("IM27", "IM27A", "ANIM27", "IM27", 27, true); + else + _objectsMan->sceneControl2("IM27", "IM27", "ANIM27", "IM27", 27, true); + break; + + case 28: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 450; + if (_globals->_saveData->_data[svCinemaCurtainCond1] != 1 || _globals->_saveData->_data[svCinemaCurtainCond2] != 1) + _objectsMan->sceneControl2("IM28", "IM28", "ANIM28", "IM28", 1, false); + else + _objectsMan->sceneControl2("IM28A", "IM28", "ANIM28", "IM28", 1, false); + break; + + case 29: + _linesMan->setMaxLineIdx(50); + _globals->_characterMaxPosY = 445; + _objectsMan->sceneControl2("IM29", "IM29", "ANIM29", "IM29", 1, true); + break; + + case 30: + _linesMan->setMaxLineIdx(15); + _globals->_characterMaxPosY = 440; + _objectsMan->sceneControl2("IM30", "IM30", "ANIM30", "IM30", 24, false); + break; + + case 31: + _objectsMan->sceneControl("IM31", "IM31", "ANIM31", "IM31", 10, true); + break; + + case 32: + _linesMan->setMaxLineIdx(20); + _globals->_characterMaxPosY = 445; + _objectsMan->sceneControl2("IM32", "IM32", "ANIM32", "IM32", 2, true); + break; + + case 33: + _objectsMan->sceneControl("IM33", "IM33", "ANIM33", "IM33", 8, false); + break; + + case 34: + _objectsMan->sceneControl("IM34", "IM34", "ANIM34", "IM34", 2, false); + break; + + case 35: + case 36: + case 37: + case 38: + case 39: + case 40: + case 41: { + _linesMan->setMaxLineIdx(40); + _globals->_characterMaxPosY = 435; + _globals->_disableInventFl = false; + _objectsMan->_forestFl = true; + Common::String im = Common::String::format("IM%d", _globals->_exitId); + _soundMan->playSound(13); + if (_objectsMan->_forestSprite == NULL) { + _objectsMan->_forestSprite = _objectsMan->loadSprite("HOPDEG.SPR"); + _soundMan->loadSample(1, "SOUND41.WAV"); + } + _objectsMan->sceneControl2(im, im, "BANDIT", im, 13, false); + if (_globals->_exitId < 35 || _globals->_exitId > 49) { + _objectsMan->_forestSprite = _globals->freeMemory(_objectsMan->_forestSprite); + _objectsMan->_forestFl = false; + _soundMan->removeSample(1); + } + break; + } + + case 50: + playPlaneCutscene(); + _globals->_exitId = 51; + break; + + case 51: + _linesMan->setMaxLineIdx(10); + _globals->_characterMaxPosY = 440; + _objectsMan->sceneControl2("IM51", "IM51", "ANIM51", "IM51", 14, true); + break; + + case 52: + _linesMan->setMaxLineIdx(15); + _globals->_characterMaxPosY = 445; + _objectsMan->sceneControl2("IM52", "IM52", "ANIM52", "IM52", 14, true); + break; + + case 54: + _linesMan->setMaxLineIdx(30); + _globals->_characterMaxPosY = 440; + _objectsMan->sceneControl2("IM54", "IM54", "ANIM54", "IM54", 14, true); + break; + + case 55: + _linesMan->setMaxLineIdx(30); + _globals->_characterMaxPosY = 460; + _objectsMan->sceneControl2("IM55", "IM55", "ANIM55", "IM55", 14, false); + break; + + case 56: + _linesMan->setMaxLineIdx(30); + _globals->_characterMaxPosY = 440; + _objectsMan->sceneControl2("IM56", "IM56", "ANIM56", "IM56", 14, false); + break; + + case 57: + _linesMan->setMaxLineIdx(30); + _globals->_characterMaxPosY = 440; + _objectsMan->sceneControl2("IM57", "IM57", "ANIM57", "IM57", 14, true); + break; + + case 58: + _linesMan->setMaxLineIdx(30); + _globals->_characterMaxPosY = 440; + _objectsMan->sceneControl2("IM58", "IM58", "ANIM58", "IM58", 14, false); + break; + + case 59: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 445; + _objectsMan->sceneControl2("IM59", "IM59", "ANIM59", "IM59", 21, false); + break; + + case 60: + _linesMan->setMaxLineIdx(30); + _globals->_characterMaxPosY = 440; + _objectsMan->sceneControl2("IM60", "IM60", "ANIM60", "IM60", 21, false); + break; + + case 61: + if (_globals->_saveData->_data[svBaseElevatorCond1] == 1 && !_globals->_saveData->_data[svBaseFireFl]) + handleConflagration(); + _objectsMan->sceneControl("IM61", "IM61", "ANIM61", "IM61", 21, false); + break; + + case 62: + _linesMan->setMaxLineIdx(8); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM62", "IM62", NULL, "IM62", 21, false); + break; + + case 63: + _linesMan->setMaxLineIdx(30); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM63", "IM63", "ANIM63", "IM63", 21, false); + break; + + case 64: + _linesMan->setMaxLineIdx(30); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM64", "IM64", "ANIM64", "IM64", 21, true); + break; + + case 65: + _linesMan->setMaxLineIdx(30); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM65", "IM65", "ANIM65", "IM65", 21, false); + break; + + case 66: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 445; + _objectsMan->sceneControl2("IM66", "IM66", "ANIM66", "IM66", 21, false); + break; + + case 67: + _linesMan->setMaxLineIdx(8); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM67", "IM67", NULL, "IM67", 21, false); + break; + + case 68: + _linesMan->setMaxLineIdx(8); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM68", "IM68", "ANIM68", "IM68", 21, true); + break; + + case 69: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 445; + _objectsMan->sceneControl2("IM69", "IM69", "ANIM69", "IM69", 21, false); + break; + + case 70: + _linesMan->setMaxLineIdx(8); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM70", "IM70", NULL, "IM70", 21, false); + break; + + case 71: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 445; + _objectsMan->sceneControl2("IM71", "IM71", "ANIM71", "IM71", 21, false); + break; + + case 73: + _linesMan->setMaxLineIdx(15); + _globals->_characterMaxPosY = 445; + if (_globals->_saveData->_data[svSecondElevatorAvailableFl] == 1) + _objectsMan->sceneControl2("IM73", "IM73A", "ANIM73", "IM73", 21, true); + else + _objectsMan->sceneControl2("IM73", "IM73", "ANIM73", "IM73", 21, true); + break; + + case 75: + playSubmarineCutscene(); + break; + + case 77: + handleOceanMaze(77, "OCEAN01", DIR_RIGHT, 0, 84, 0, 0, 25); + break; + + case 78: + handleOceanMaze(78, "OCEAN02", DIR_UP, 0, 91, 84, 0, 25); + break; + + case 79: + handleOceanMaze(79, "OCEAN03", DIR_LEFT, 87, 0, 0, 83, 25); + break; + + case 80: + handleOceanMaze(80, "OCEAN04", DIR_UP, 86, 88, 0, 81, 25); + break; + + case 81: + handleOceanMaze(81, "OCEAN05", DIR_UP, 91, 82, 80, 85, 25); + break; + + case 82: + handleOceanMaze(82, "OCEAN06", DIR_LEFT, 81, 0, 88, 0, 25); + break; + + case 83: + handleOceanMaze(83, "OCEAN07", DIR_UP, 89, 0, 79, 88, 25); + break; + + case 84: + handleOceanMaze(84, "OCEAN08", DIR_UP, 77, 0, 0, 78, 25); + break; + + case 85: + handleOceanMaze(85, "OCEAN09", DIR_UP, 0, 0, 81, 0, 25); + break; + + case 86: + handleOceanMaze(86, "OCEAN10", DIR_UP, 0, 80, 0, 91, 25); + break; + + case 87: + handleOceanMaze(87, "OCEAN11", DIR_RIGHT, 0, 79, 90, 0, 25); + break; + + case 88: + handleOceanMaze(88, "OCEAN12", DIR_UP, 80, 0, 83, 82, 25); + break; + + case 89: + handleOceanMaze(89, "OCEAN13", DIR_RIGHT, 0, 83, 0, 0, 25); + break; + + case 90: + playUnderwaterBaseCutscene(); + break; + + case 91: + handleOceanMaze(91, "OCEAN15", DIR_RIGHT, 78, 81, 86, 0, 25); + break; + + case 93: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 445; + if (_globals->_saveData->_data[svEscapeLeftJailFl]) { + if (getPlatform() == Common::kPlatformLinux || getPlatform() == Common::kPlatformWindows) + _objectsMan->sceneControl2("IM93", "IM93C", "ANIM93", "IM93", 29, true); + else + _objectsMan->sceneControl2("IM93", "IM93C", "ANIM93", "IM93", 26, true); + } else { + if (getPlatform() == Common::kPlatformLinux || getPlatform() == Common::kPlatformWindows) + _objectsMan->sceneControl2("IM93", "IM93", "ANIM93", "IM93", 29, true); + else + _objectsMan->sceneControl2("IM93", "IM93", "ANIM93", "IM93", 26, true); + } + break; + + case 94: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 440; + _objectsMan->sceneControl2("IM94", "IM94", "ANIM94", "IM94", 19, true); + break; + + case 95: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM95", "IM95", "ANIM95", "IM95", 19, false); + break; + + case 96: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM96", "IM96", "ANIM96", "IM96", 19, false); + break; + + case 97: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM97", "IM97", "ANIM97", "IM97", 19, false); + if (_globals->_exitId == 18) { + _globals->_eventMode = EVENTMODE_IGNORE; + _soundMan->stopSound(); + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + _soundMan->playSound(6); + _animMan->playAnim("PURG1A.ANM", 12, 18, 50); + _graphicsMan->fadeOutShort(); + _globals->_eventMode = EVENTMODE_DEFAULT; + } + break; + + case 98: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM98", "IM98", "ANIM98", "IM98", 19, true); + break; + + case 99: + _linesMan->setMaxLineIdx(5); + _globals->_characterMaxPosY = 435; + _objectsMan->sceneControl2("IM99", "IM99", "ANIM99", "IM99", 19, true); + break; + + case 100: + playEnding(); + break; + + case 111: + _objectsMan->sceneControl("IM111", "IM111", "ANIM111", "IM111", 10, false); + break; + + case 112: + _objectsMan->sceneControl("IM112", "IM112", "ANIM112", "IM112", 10, false); + break; + + case 113: + _globals->_prevScreenId = _globals->_screenId; + _globals->_screenId = 113; + _globals->_saveData->_data[svLastPrevScreenId] = _globals->_prevScreenId; + _globals->_saveData->_data[svLastScreenId] = _globals->_screenId; + _globals->_exitId = 0; + _computer->showComputer(COMPUTER_HOPKINS); + _graphicsMan->clearScreen(); + _graphicsMan->updateScreen(); + memset(_graphicsMan->_frontBuffer, 0, 307200); + memset(_graphicsMan->_backBuffer, 0, 307200); + _graphicsMan->clearPalette(); + _graphicsMan->resetDirtyRects(); + break; + + case 114: + _globals->_exitId = 0; + _globals->_prevScreenId = _globals->_screenId; + _globals->_screenId = 114; + _globals->_saveData->_data[svLastPrevScreenId] = _globals->_prevScreenId; + _globals->_saveData->_data[svLastScreenId] = _globals->_screenId; + _computer->showComputer(COMPUTER_SAMANTHA); + _graphicsMan->clearScreen(); + break; + + case 115: + _globals->_prevScreenId = _globals->_screenId; + _globals->_screenId = 115; + _globals->_saveData->_data[svLastPrevScreenId] = _globals->_prevScreenId; + _globals->_saveData->_data[svLastScreenId] = _globals->_screenId; + _globals->_exitId = 0; + _computer->showComputer(COMPUTER_PUBLIC); + _graphicsMan->clearScreen(); + break; + + case 150: + _soundMan->playSound(16); + _globals->_eventMode = EVENTMODE_IGNORE; + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + if (getPlatform() == Common::kPlatformLinux) + _graphicsMan->_fadingFl = true; + _animMan->playAnim("JOUR1A.ANM", 12, 12, 2000); + _globals->_eventMode = EVENTMODE_DEFAULT; + _globals->_exitId = 300; + break; + + case 151: + _soundMan->playSound(16); + _globals->_eventMode = EVENTMODE_IGNORE; + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + if (getPlatform() == Common::kPlatformLinux) + _graphicsMan->_fadingFl = true; + _animMan->playAnim("JOUR3A.ANM", 12, 12, 2000); + _globals->_eventMode = EVENTMODE_DEFAULT; + _globals->_exitId = 300; + break; + + case 152: + _soundMan->playSound(16); + _globals->_eventMode = EVENTMODE_IGNORE; + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + if (getPlatform() == Common::kPlatformLinux) + _graphicsMan->_fadingFl = true; + _animMan->playAnim("JOUR4A.ANM", 12, 12, 2000); + _globals->_eventMode = EVENTMODE_DEFAULT; + _globals->_exitId = 300; + break; + + case 194: + case 195: + case 196: + case 197: + case 198: + case 199: + _globals->_characterSpriteBuf = _globals->freeMemory(_globals->_characterSpriteBuf); + _globals->_eventMode = EVENTMODE_IGNORE; + _soundMan->stopSound(); + _soundMan->playSound(23); + _globals->_exitId = handleBaseMap(); // Handles the base map (non-Windows) + //_globals->_exitId = WBASE(); // Handles the 3D Doom level (Windows) + _soundMan->stopSound(); + _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR"); + _globals->_characterType = 0; + _globals->_eventMode = EVENTMODE_DEFAULT; + _graphicsMan->_lineNbr = SCREEN_WIDTH; + break; + } + } + _globals->_characterSpriteBuf = _globals->freeMemory(_globals->_characterSpriteBuf); + restoreSystem(); + return true; +} + +bool HopkinsEngine::shouldQuit() const { + return g_system->getEventManager()->shouldQuit(); +} + +int HopkinsEngine::getRandomNumber(int maxNumber) { + return _randomSource.getRandomNumber(maxNumber); +} + +void HopkinsEngine::initializeSystem() { + // Set graphics mode + _graphicsMan->setGraphicalMode(SCREEN_WIDTH, SCREEN_HEIGHT); + + // Synchronize the sound settings from ScummVM + _soundMan->syncSoundSettings(); + + const Common::FSNode gameDataDir(ConfMan.get("path")); + SearchMan.addSubDirectoryMatching(gameDataDir, "SYSTEM"); + SearchMan.addSubDirectoryMatching(gameDataDir, "LINK"); + SearchMan.addSubDirectoryMatching(gameDataDir, "BUFFER"); + SearchMan.addSubDirectoryMatching(gameDataDir, "ANIM"); + SearchMan.addSubDirectoryMatching(gameDataDir, "ANM"); + SearchMan.addSubDirectoryMatching(gameDataDir, "BASE"); + SearchMan.addSubDirectoryMatching(gameDataDir, "MUSIC"); + SearchMan.addSubDirectoryMatching(gameDataDir, "SEQ"); + SearchMan.addSubDirectoryMatching(gameDataDir, "SAVE"); + SearchMan.addSubDirectoryMatching(gameDataDir, "SOUND"); + SearchMan.addSubDirectoryMatching(gameDataDir, "SVGA"); + SearchMan.addSubDirectoryMatching(gameDataDir, "VOICE"); + SearchMan.addSubDirectoryMatching(gameDataDir, "TSVGA"); + + _globals->clearAll(); + + _events->initMouseData(); + _fontMan->initData(); + + _dialog->loadIcons(); + _objectsMan->_headSprites = _fileIO->loadFile("TETE.SPR"); + + _events->setMouseOn(); + _events->_mouseFl = false; + + _globals->loadCharacterData(); + + _events->_mouseOffset.x = 0; + _events->_mouseOffset.y = 0; +} + +/** + * Play the intro of the game + */ +void HopkinsEngine::playIntro() { + // Win95 EN demo doesn't include the intro + if ((getLanguage() == Common::EN_ANY) && (getPlatform() == Common::kPlatformWindows) && (getIsDemo())) + return; + + byte paletteData[PALETTE_EXT_BLOCK_SIZE]; + byte paletteData2[PALETTE_EXT_BLOCK_SIZE]; + + memset(&paletteData, 0, PALETTE_EXT_BLOCK_SIZE); + _events->refreshScreenAndEvents(); + _events->_mouseFl = false; + _globals->_eventMode = EVENTMODE_IGNORE; + _events->refreshScreenAndEvents(); + _soundMan->playSound(16); + _animMan->setClearAnimFlag(); + _animMan->playAnim("J1.anm", 12, 12, 50); + if (shouldQuit() || _events->_escKeyFl) + return; + + _soundMan->mixVoice(1, 3); + _animMan->playAnim("J2.anm", 12, 12, 50); + + if (shouldQuit() || _events->_escKeyFl) + return; + + _soundMan->mixVoice(2, 3); + _animMan->playAnim("J3.anm", 12, 12, 50); + + if (shouldQuit() || _events->_escKeyFl) + return; + + _soundMan->mixVoice(3, 3); + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + _graphicsMan->updateScreen(); + _soundMan->playSound(11); + _graphicsMan->loadImage("intro1"); + _graphicsMan->scrollScreen(0); + _graphicsMan->_scrollOffset = 0; + _graphicsMan->setColorPercentage(252, 100, 100, 100); + _graphicsMan->setColorPercentage(253, 100, 100, 100); + _graphicsMan->setColorPercentage(251, 100, 100, 100); + _graphicsMan->setColorPercentage(254, 0, 0, 0); + for (int i = 0; i <= 4; i++) + _events->refreshScreenAndEvents(); + + _globals->_eventMode = EVENTMODE_IGNORE; + _graphicsMan->fadeInLong(); + if (_graphicsMan->_largeScreenFl) { + _graphicsMan->_scrollStatus = 2; + _graphicsMan->_scrollPosX = 0; + + bool loopCond = false; + do { + _graphicsMan->_scrollPosX += 2; + if (_graphicsMan->_scrollPosX > (SCREEN_WIDTH - 2)) { + _graphicsMan->_scrollPosX = SCREEN_WIDTH; + loopCond = true; + } + + if (_events->getMouseX() < _graphicsMan->_scrollPosX + 10) + _events->setMouseXY(_events->_mousePos.x + 4, _events->getMouseY()); + _events->refreshScreenAndEvents(); + } while (!shouldQuit() && !loopCond && _graphicsMan->_scrollPosX != SCREEN_WIDTH); + + _events->refreshScreenAndEvents(); + _graphicsMan->_scrollStatus = 0; + + if (shouldQuit()) + return; + } + + _soundMan->mixVoice(4, 3); + _graphicsMan->fadeOutLong(); + _graphicsMan->_scrollStatus = 0; + _graphicsMan->loadImage("intro2"); + _graphicsMan->scrollScreen(0); + _animMan->loadAnim("INTRO2"); + _graphicsMan->displayAllBob(); + _soundMan->playSound(23); + _objectsMan->stopBobAnimation(3); + _objectsMan->stopBobAnimation(5); + _graphicsMan->_scrollOffset = 0; + _graphicsMan->setColorPercentage(252, 100, 100, 100); + _graphicsMan->setColorPercentage(253, 100, 100, 100); + _graphicsMan->setColorPercentage(251, 100, 100, 100); + _graphicsMan->setColorPercentage(254, 0, 0, 0); + + for (int i = 0; i <= 4; i++) + _events->refreshScreenAndEvents(); + + _globals->_eventMode = EVENTMODE_IGNORE; + _graphicsMan->fadeInLong(); + for (uint i = 0; i < 200 / _globals->_speed; ++i) + _events->refreshScreenAndEvents(); + + _objectsMan->setBobAnimation(3); + _soundMan->mixVoice(5, 3); + _objectsMan->stopBobAnimation(3); + _events->refreshScreenAndEvents(); + memcpy(&paletteData2, _graphicsMan->_palette, 796); + + _graphicsMan->setPaletteVGA256WithRefresh(paletteData, _graphicsMan->_frontBuffer); + _graphicsMan->endDisplayBob(); + + if (shouldQuit() || _events->_escKeyFl) + return; + + _soundMan->_specialSoundNum = 5; + _graphicsMan->_fadingFl = true; + _animMan->playAnim("ELEC.ANM", 10, 26, 200); + _soundMan->_specialSoundNum = 0; + + if (shouldQuit() || _events->_escKeyFl) + return; + + _graphicsMan->loadImage("intro2"); + _graphicsMan->scrollScreen(0); + _animMan->loadAnim("INTRO2"); + _graphicsMan->displayAllBob(); + _soundMan->playSound(23); + _objectsMan->stopBobAnimation(3); + _objectsMan->stopBobAnimation(5); + _objectsMan->stopBobAnimation(1); + _graphicsMan->_scrollOffset = 0; + _graphicsMan->setColorPercentage(252, 100, 100, 100); + _graphicsMan->setColorPercentage(253, 100, 100, 100); + _graphicsMan->setColorPercentage(251, 100, 100, 100); + _graphicsMan->setColorPercentage(254, 0, 0, 0); + + for (int i = 0; i <= 3; i++) + _events->refreshScreenAndEvents(); + + _globals->_eventMode = EVENTMODE_IGNORE; + _graphicsMan->setPaletteVGA256WithRefresh(paletteData2, _graphicsMan->_frontBuffer); + + int introIndex = 0; + while (!shouldQuit() && !_events->_escKeyFl) { + if (introIndex == 12) { + _objectsMan->setBobAnimation(3); + _events->refreshScreenAndEvents(); + _soundMan->mixVoice(6, 3); + _events->refreshScreenAndEvents(); + _objectsMan->stopBobAnimation(3); + } + + Common::copy(&paletteData2[0], &paletteData2[PALETTE_BLOCK_SIZE], &_graphicsMan->_palette[0]); + + for (int i = 1, maxPalVal = 4 * introIndex; i <= PALETTE_BLOCK_SIZE; i++) { + if (_graphicsMan->_palette[i] > maxPalVal) + _graphicsMan->_palette[i] -= maxPalVal; + } + + _graphicsMan->setPaletteVGA256WithRefresh(_graphicsMan->_palette, _graphicsMan->_frontBuffer); + + for (int i = 1; i < 2 * introIndex; i++) + _events->refreshScreenAndEvents(); + + _graphicsMan->setPaletteVGA256WithRefresh(paletteData2, _graphicsMan->_frontBuffer); + + for (int i = 1; i < 20 - introIndex; i++) + _events->refreshScreenAndEvents(); + + introIndex += 2; + if (introIndex > 15) { + _graphicsMan->setPaletteVGA256WithRefresh(paletteData, _graphicsMan->_frontBuffer); + for (uint j = 1; j < 100 / _globals->_speed; ++j) + _events->refreshScreenAndEvents(); + + _objectsMan->setBobAnimation(3); + _soundMan->mixVoice(7, 3); + _objectsMan->stopBobAnimation(3); + + for (uint k = 1; k < 60 / _globals->_speed; ++k) + _events->refreshScreenAndEvents(); + _objectsMan->setBobAnimation(5); + for (uint l = 0; l < 20 / _globals->_speed; ++l) + _events->refreshScreenAndEvents(); + + Common::copy(&paletteData2[0], &paletteData2[PALETTE_BLOCK_SIZE], &_graphicsMan->_palette[0]); + _graphicsMan->setPaletteVGA256WithRefresh(_graphicsMan->_palette, _graphicsMan->_frontBuffer); + + for (uint m = 0; m < 50 / _globals->_speed; ++m) { + if (m == 30 / _globals->_speed) { + _objectsMan->setBobAnimation(3); + _soundMan->mixVoice(8, 3); + _objectsMan->stopBobAnimation(3); + } + + _events->refreshScreenAndEvents(); + } + + _graphicsMan->fadeOutLong(); + _graphicsMan->endDisplayBob(); + _soundMan->playSound(3); + _soundMan->_specialSoundNum = 1; + _animMan->setClearAnimFlag(); + _animMan->playAnim("INTRO1.anm", 10, 24, 18); + _soundMan->_specialSoundNum = 0; + if (shouldQuit() || _events->_escKeyFl) + return; + + _animMan->playAnim("INTRO2.anm", 10, 24, 18); + if (shouldQuit() || _events->_escKeyFl) + return; + + _animMan->playAnim("INTRO3.anm", 10, 24, 200); + if (shouldQuit() || _events->_escKeyFl) + return; + + _graphicsMan->_fadingFl = true; + _animMan->unsetClearAnimFlag(); + _animMan->playAnim("J4.anm", 12, 12, 1000); + break; + } + } + + _events->_escKeyFl = false; +} + +/** + * If in demo, displays a 'not available' screen and returns to the city map + */ +void HopkinsEngine::displayNotAvailable() { + if (!getIsDemo()) + return; + + if (_globals->_language == LANG_FR) + _graphicsMan->loadImage("ndfr"); + else + _graphicsMan->loadImage("nduk"); + + _graphicsMan->fadeInLong(); + if (_soundMan->_voiceOffFl) + _events->delay(500); + else + _soundMan->mixVoice(628, 4); + + _graphicsMan->fadeOutLong(); + _globals->_exitId = 4; +} + +void HopkinsEngine::handleNotAvailable(int nextScreen) { + // Use the code of the Linux demo instead of the code of the Windows demo. + // The behavior is somewhat better, and common code is easier to maintain. + displayNotAvailable(); + _globals->_exitId = nextScreen; +} + +void HopkinsEngine::displayEndDemo() { + _soundMan->playSound(28); + if (_globals->_language == LANG_FR) + _graphicsMan->loadImage("endfr"); + else + _graphicsMan->loadImage("enduk"); + + _graphicsMan->fadeInLong(); + _events->delay(1500); + _graphicsMan->fadeOutLong(); + _globals->_exitId = 0; +} + +void HopkinsEngine::bombExplosion() { + _graphicsMan->_lineNbr = SCREEN_WIDTH; + _graphicsMan->setScreenWidth(SCREEN_WIDTH); + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + + _globals->_eventMode = EVENTMODE_IGNORE; + _soundMan->_specialSoundNum = 199; + _graphicsMan->_fadingFl = true; + _animMan->playAnim("BOMBE2A.ANM", 50, 14, 500); + _soundMan->_specialSoundNum = 0; + _graphicsMan->loadImage("IM15"); + _animMan->loadAnim("ANIM15"); + _graphicsMan->displayAllBob(); + _objectsMan->stopBobAnimation(7); + + for (int idx = 0; idx < 5; ++idx) { + _events->refreshScreenAndEvents(); + } + + _graphicsMan->fadeInLong(); + _events->mouseOff(); + + for (int idx = 0; idx < 20; ++idx) { + _events->refreshScreenAndEvents(); + } + + _globals->_introSpeechOffFl = true; + _talkMan->startStaticCharacterDialogue("vire.pe2"); + _globals->_introSpeechOffFl = false; + _objectsMan->setBobAnimation(7); + + for (int idx = 0; idx < 100; ++idx) { + _events->refreshScreenAndEvents(); + } + + _graphicsMan->fadeOutLong(); + _graphicsMan->endDisplayBob(); + _globals->_eventMode = EVENTMODE_DEFAULT; + _globals->_exitId = 151; +} + +void HopkinsEngine::restoreSystem() { + quitGame(); + _events->refreshEvents(); +} + +void HopkinsEngine::endLinuxDemo() { + _globals->_linuxEndDemoFl = true; + _graphicsMan->resetDirtyRects(); + _objectsMan->_forestFl = false; + _events->_breakoutFl = false; + _globals->_disableInventFl = true; + _graphicsMan->loadImage("BOX"); + _soundMan->playSound(28); + _graphicsMan->fadeInLong(); + _events->mouseOn(); + _events->changeMouseCursor(0); + _events->_mouseCursorId = 0; + _events->_mouseSpriteId = 0; + + bool mouseClicked = false; + + do { + _events->refreshScreenAndEvents(); + + if (_events->getMouseButton() == 1) + mouseClicked = true; + } while (!mouseClicked && !shouldQuit()); + + // Original tried to open a web browser link here. Since ScummVM doesn't support + // that, it's being skipped in favor of simply exiting + + _graphicsMan->fadeOutLong(); +} + +void HopkinsEngine::handleConflagration() { + _globals->_disableInventFl = true; + _globals->_eventMode = EVENTMODE_IGNORE; + _graphicsMan->loadImage("IM71"); + _animMan->loadAnim("ANIM71"); + _graphicsMan->setColorPercentage(252, 100, 100, 100); + _graphicsMan->setColorPercentage(253, 100, 100, 100); + _graphicsMan->setColorPercentage(251, 100, 100, 100); + _graphicsMan->setColorPercentage(254, 0, 0, 0); + _graphicsMan->displayAllBob(); + + for (int cpt = 0; cpt <= 4; cpt++) + _events->refreshScreenAndEvents(); + + _graphicsMan->fadeInLong(); + _globals->_eventMode = EVENTMODE_IGNORE; + + for (int cpt = 0; cpt <= 249; cpt++) + _events->refreshScreenAndEvents(); + + _globals->_introSpeechOffFl = true; + _talkMan->startAnimatedCharacterDialogue("SVGARD1.pe2"); + _globals->_introSpeechOffFl = false; + + for (int cpt = 0; cpt <= 49; cpt++) + _events->refreshScreenAndEvents(); + + _graphicsMan->fadeOutLong(); + _graphicsMan->endDisplayBob(); + _globals->_saveData->_data[svBaseFireFl] = 1; + _globals->_disableInventFl = false; +} + +void HopkinsEngine::playSubmarineCutscene() { + _globals->_eventMode = EVENTMODE_IGNORE; + _graphicsMan->_lineNbr = SCREEN_WIDTH; + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + _soundMan->playSound(25); + _animMan->setClearAnimFlag(); + _animMan->playAnim("base00a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("base05a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("base10a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("base20a.anm", 10, 18, 18); + // CHECKME: The original code was doing the opposite test, which was a bug. + if (!_events->_escKeyFl) + _animMan->playAnim("base30a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("base40a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("base50a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("OC00a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("OC05a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("OC10a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("OC20a.anm", 10, 18, 18); + if (!_events->_escKeyFl) { + _graphicsMan->_fadingFl = true; + _animMan->playAnim("OC30a.anm", 10, 18, 18); + } + + _events->_escKeyFl = false; + _animMan->unsetClearAnimFlag(); + _globals->_exitId = 85; +} + +void HopkinsEngine::playUnderwaterBaseCutscene() { + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + _soundMan->playSound(26); + _globals->_eventMode = EVENTMODE_IGNORE; + _globals->_disableInventFl = true; + _graphicsMan->_fadingFl = true; + _animMan->playSequence("abase.seq", 50, 15, 50, false, false, true); + _graphicsMan->loadImage("IM92"); + _animMan->loadAnim("ANIM92"); + _graphicsMan->displayAllBob(); + _objectsMan->loadLinkFile("IM92"); +/* + for (int cpt = 0; cpt <= 4 && !shouldQuit(); cpt++) + _eventsManager->refreshScreenAndEvents(); +*/ + _graphicsMan->fadeInLong(); + _objectsMan->enableHidingBehavior(); + + do + _events->refreshScreenAndEvents(); + while (!shouldQuit() && _objectsMan->getBobAnimDataIdx(8) != 22); + + if (!shouldQuit()) { + _graphicsMan->fadeOutLong(); + _graphicsMan->endDisplayBob(); + _objectsMan->resetHidingItems(); + _globals->_disableInventFl = false; + _globals->_exitId = 93; + _globals->_eventMode = EVENTMODE_DEFAULT; + } +} + +void HopkinsEngine::playEnding() { + _globals->_characterSpriteBuf = _globals->freeMemory(_globals->_characterSpriteBuf); + _dialog->disableInvent(); + _globals->_disableInventFl = true; + _graphicsMan->_scrollOffset = 0; + _globals->_cityMapEnabledFl = false; + _globals->_eventMode = EVENTMODE_IGNORE; + _soundMan->playSound(26); + _linesMan->_route = NULL; + _globals->_freezeCharacterFl = true; + _globals->_exitId = 0; + _soundMan->loadSample(1, "SOUND90.WAV"); + _graphicsMan->loadImage("IM100"); + _animMan->loadAnim("ANIM100"); + _graphicsMan->displayAllBob(); + _events->mouseOn(); + _objectsMan->stopBobAnimation(7); + _objectsMan->stopBobAnimation(8); + _objectsMan->stopBobAnimation(9); + _graphicsMan->setColorPercentage(252, 100, 100, 100); + _graphicsMan->setColorPercentage(253, 100, 100, 100); + _graphicsMan->setColorPercentage(251, 100, 100, 100); + _graphicsMan->setColorPercentage(254, 0, 0, 0); + _events->changeMouseCursor(0); + + for (int cpt = 0; cpt <= 4; cpt++) + _events->refreshScreenAndEvents(); + + _graphicsMan->fadeInLong(); + _globals->_eventMode = EVENTMODE_IGNORE; + + do + _events->refreshScreenAndEvents(); + while (_objectsMan->getBobAnimDataIdx(6) != 54); + + _globals->_introSpeechOffFl = true; + _talkMan->startAnimatedCharacterDialogue("GM4.PE2"); + _globals->_disableInventFl = true; + _objectsMan->stopBobAnimation(6); + _objectsMan->stopBobAnimation(10); + _objectsMan->setBobAnimation(9); + _objectsMan->setBobAnimation(7); + + do + _events->refreshScreenAndEvents(); + while (_objectsMan->getBobAnimDataIdx(7) != 54); + + _soundMan->playSample(1); + + do + _events->refreshScreenAndEvents(); + while (_objectsMan->getBobAnimDataIdx(7) != 65); + + _globals->_introSpeechOffFl = true; + _talkMan->startAnimatedCharacterDialogue("DUELB4.PE2"); + _events->mouseOff(); + _globals->_disableInventFl = true; + + do + _events->refreshScreenAndEvents(); + while (_objectsMan->getBobAnimDataIdx(7) != 72); + + _globals->_introSpeechOffFl = true; + _talkMan->startAnimatedCharacterDialogue("DUELH1.PE2"); + + do + _events->refreshScreenAndEvents(); + while (_objectsMan->getBobAnimDataIdx(7) != 81); + + _globals->_introSpeechOffFl = true; + _talkMan->startAnimatedCharacterDialogue("DUELB5.PE2"); + + do + _events->refreshScreenAndEvents(); + while (_objectsMan->getBobAnimDataIdx(7) != 120); + + _objectsMan->stopBobAnimation(7); + if (_globals->_saveData->_data[svGameWonFl] == 1) { + _soundMan->_specialSoundNum = 200; + _soundMan->_skipRefreshFl = true; + _graphicsMan->_fadingFl = true; + _animMan->playAnim("BERM.ANM", 100, 24, 300); + _graphicsMan->endDisplayBob(); + _soundMan->removeSample(1); + _graphicsMan->loadImage("PLAN3"); + _graphicsMan->fadeInLong(); + + _events->_rateCounter = 0; + if (!_events->_escKeyFl) { + do + _events->refreshEvents(); + while (_events->_rateCounter < 2000 / _globals->_speed && !_events->_escKeyFl); + } + _events->_escKeyFl = false; + _graphicsMan->fadeOutLong(); + _globals->_eventMode = EVENTMODE_IGNORE; + _soundMan->_specialSoundNum = 0; + _graphicsMan->_fadingFl = true; + _animMan->playAnim("JOUR2A.anm", 12, 12, 1000); + _soundMan->playSound(11); + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + _animMan->playAnim("FF1a.anm", 18, 18, 9); + _animMan->playAnim("FF1a.anm", 9, 18, 9); + _animMan->playAnim("FF1a.anm", 9, 18, 18); + _animMan->playAnim("FF1a.anm", 9, 18, 9); + _animMan->playAnim("FF2a.anm", 24, 24, 100); + displayCredits(); + _globals->_eventMode = EVENTMODE_DEFAULT; + _globals->_exitId = 300; + _dialog->enableInvent(); + _globals->_disableInventFl = false; + } else { + _soundMan->_specialSoundNum = 200; + _soundMan->_skipRefreshFl = true; + _animMan->playAnim2("BERM.ANM", 100, 24, 300); + _objectsMan->stopBobAnimation(7); + _objectsMan->setBobAnimation(8); + _globals->_introSpeechOffFl = true; + _talkMan->startAnimatedCharacterDialogue("GM5.PE2"); + _globals->_disableInventFl = true; + + do + _events->refreshScreenAndEvents(); + while (_objectsMan->getBobAnimDataIdx(8) != 5); + + _soundMan->directPlayWav("SOUND41.WAV"); + + do + _events->refreshScreenAndEvents(); + while (_objectsMan->getBobAnimDataIdx(8) != 21); + + _graphicsMan->fadeOutLong(); + _graphicsMan->endDisplayBob(); + _soundMan->removeSample(1); + _soundMan->playSound(16); + _globals->_eventMode = EVENTMODE_IGNORE; + _soundMan->_specialSoundNum = 0; + _dialog->enableInvent(); + _globals->_disableInventFl = false; + _animMan->playAnim("JOUR4A.anm", 12, 12, 1000); + _globals->_eventMode = EVENTMODE_DEFAULT; + _globals->_exitId = 300; + } + _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR"); + _globals->_characterType = 0; + _globals->_eventMode = EVENTMODE_DEFAULT; +} + +void HopkinsEngine::playPlaneCutscene() { + _soundMan->playSound(28); + _globals->_eventMode = EVENTMODE_IGNORE; + _graphicsMan->clearScreen(); + _graphicsMan->clearPalette(); + + _animMan->unsetClearAnimFlag(); + _animMan->playAnim("aerop00a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("serop10a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("aerop20a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("aerop30a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("aerop40a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("aerop50a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("aerop60a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("aerop70a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("trans00a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("trans10a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("trans15a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("trans20a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("trans30a.anm", 10, 18, 18); + if (!_events->_escKeyFl) + _animMan->playAnim("trans40a.anm", 10, 18, 18); + if (!_events->_escKeyFl) { + _graphicsMan->_fadingFl = true; + _animMan->playAnim("PARA00a.anm", 9, 9, 9); + } + + _events->_escKeyFl = false; + _animMan->unsetClearAnimFlag(); +} + +void HopkinsEngine::loadBaseMap() { + Common::String filename = Common::String::format("%s.PCX", "PBASE"); + Common::File f; + + if (f.exists(filename)) { + // PBASE file exists, so go ahead and load it + _graphicsMan->loadImage("PBASE"); + } else { + // PBASE file doesn't exist, so draw a substitute screen + drawBaseMap(); + } +} + +void HopkinsEngine::drawBaseMap() { + memset(_graphicsMan->_backBuffer, 0, SCREEN_WIDTH * 2 * SCREEN_HEIGHT); + + // List of rectangle areas to draw for exit points + const int rects[] = { + 181, 66, 181 + 16, 66 + 22, + 353, 116, 353 + 22, 116 + 16, + 483, 250, 483 + 20, 250 + 25, + 471, 326, 471 + 27, 326 + 20, + 162, 365, 162 + 21, 365 + 23, + 106, 267, 106 + 20, 267 + 26 + }; + + // Loop through displaying + const int *rectP = &rects[0]; + for (int rectIndex = 0; rectIndex < 6; ++rectIndex, rectP += 4) { + Common::Rect r(rectP[0], rectP[1], rectP[2], rectP[3]); + + for (int yp = r.top; yp <= r.bottom; ++yp) { + byte *pDest = _graphicsMan->_backBuffer + yp * SCREEN_WIDTH + r.left; + Common::fill(pDest, pDest + r.width(), 0xff); + } + } + + // Copy the calculated screen + memcpy(_graphicsMan->_frontBuffer, _graphicsMan->_backBuffer, SCREEN_WIDTH * 2 * SCREEN_HEIGHT); + + // Write some explanatory text + _fontMan->displayText(40, 200, "ScummVM base map - select a square for different rooms", 255); +} + +int HopkinsEngine::handleBaseMap() { + _globals->_disableInventFl = true; + + // Load the map image + loadBaseMap(); + + // Set needed colors + _graphicsMan->setColorPercentage(252, 100, 100, 100); + _graphicsMan->setColorPercentage(253, 100, 100, 100); + _graphicsMan->setColorPercentage(251, 100, 100, 100); + _graphicsMan->setColorPercentage(254, 0, 0, 0); + _events->changeMouseCursor(0); + _graphicsMan->fadeInLong(); + bool loopCond = false; + int zone; + do { + if (shouldQuit()) + return 0; + + int mouseButton = _events->getMouseButton(); + int posX = _events->getMouseX(); + int posY = _events->getMouseY(); + zone = 0; + if ((posX - 181 <= 16) && (posY - 66 <= 22) && + (posX - 181 >= 0) && (posY - 66 >= 0)) + zone = 1; + if ((posX - 353 <= 22) && (posY - 116 <= 19) && + (posX - 353 >= 0) && (posY - 116 >= 0)) + zone = 2; + if ((posX - 483 <= 20) && (posY - 250 <= 25) && + (posX - 483 >= 0) && (posY - 250 >= 0)) + zone = 3; + if ((posX - 471 <= 27) && (posY - 326 <= 20) && + (posX - 471 >= 0) && (posY - 326 >= 0)) + zone = 4; + if ((posX - 162 <= 21) && (posY - 365 <= 23) && + (posX - 162 >= 0) && (posY - 365 >= 0)) + zone = 5; + if ((posX - 106 <= 20) && (posY - 267 <= 26) && + (posX - 106 >= 0) && (posY - 267 >= 0)) + zone = 6; + if (zone) { + _events->changeMouseCursor(4); + _globals->_baseMapColor += 25; + if (_globals->_baseMapColor > 100) + _globals->_baseMapColor = 0; + _graphicsMan->setColorPercentage2(251, _globals->_baseMapColor, _globals->_baseMapColor, _globals->_baseMapColor); + } else { + _events->changeMouseCursor(0); + _graphicsMan->setColorPercentage2(251, 100, 100, 100); + } + _events->refreshScreenAndEvents(); + if ((mouseButton == 1) && zone) + loopCond = true; + } while (!loopCond); + + _globals->_disableInventFl = false; + _graphicsMan->fadeOutLong(); + + int result; + switch (zone) { + case 1: + result = 94; + break; + case 2: + result = 95; + break; + case 3: + result = 96; + break; + case 4: + result = 97; + break; + case 5: + result = 98; + break; + case 6: + result = 99; + break; + default: + result = 0; + break; + } + return result; +} + +void HopkinsEngine::loadCredits() { + _globals->_creditsPosY = 440; + _globals->_creditsStep = 45; + byte *bufPtr; + switch (_globals->_language) { + case LANG_EN: + bufPtr = _fileIO->loadFile("CREAN.TXT"); + break; + case LANG_FR: + bufPtr = _fileIO->loadFile("CREFR.TXT"); + break; + case LANG_SP: + bufPtr = _fileIO->loadFile("CREES.TXT"); + break; + default: + error("Unhandled language"); + break; + } + + byte *curPtr = bufPtr; + int idxLines = 0; + bool loopCond = false; + do { + if (*curPtr == '%') { + if (curPtr[1] == '%') { + loopCond = true; + break; + } + _globals->_creditsItem[idxLines]._color = curPtr[1]; + _globals->_creditsItem[idxLines]._actvFl = true; + _globals->_creditsItem[idxLines]._linePosY = _globals->_creditsPosY + idxLines * _globals->_creditsStep; + + int idxBuf = 0; + for(; idxBuf < 49; idxBuf++) { + byte curChar = curPtr[idxBuf + 3]; + if (curChar == '%' || curChar == 10) + break; + _globals->_creditsItem[idxLines]._line[idxBuf] = curChar; + } + _globals->_creditsItem[idxLines]._line[idxBuf] = 0; + _globals->_creditsItem[idxLines]._lineSize = idxBuf - 1; + curPtr = curPtr + idxBuf + 2; + ++idxLines; + } else { + curPtr++; + } + _globals->_creditsLineNumb = idxLines; + } while (!loopCond); + + _globals->freeMemory(bufPtr); +} + +void HopkinsEngine::displayCredits(int startPosY, byte *buffer, char color) { + byte *bufPtr = buffer; + int strWidth = 0; + byte curChar; + for (;;) { + curChar = *bufPtr++; + if (!curChar) + break; + if (curChar > 31) + strWidth += _objectsMan->getWidth(_fontMan->_font, curChar - 32); + } + int startPosX = 320 - strWidth / 2; + int endPosX = strWidth + startPosX; + int endPosY = startPosY + 12; + if ((_globals->_creditsStartX == -1) && (_globals->_creditsEndX == -1) && (_globals->_creditsStartY == -1) && (_globals->_creditsEndY == -1)) { + _globals->_creditsStartX = startPosX; + _globals->_creditsEndX = endPosX; + _globals->_creditsStartY = startPosY; + _globals->_creditsEndY = endPosY; + } + + _globals->_creditsStartX = MIN(_globals->_creditsStartX, startPosX); + _globals->_creditsEndX = MAX(_globals->_creditsEndX, endPosX); + _globals->_creditsStartY = MIN(_globals->_creditsStartY, startPosY); + _globals->_creditsEndY = MAX(_globals->_creditsEndY, endPosY); + + Common::String message = Common::String((char *)buffer); + _fontMan->displayText(startPosX, startPosY, message, color); +} + +void HopkinsEngine::displayCredits() { + loadCredits(); + _globals->_creditsPosY = 436; + _graphicsMan->loadImage("GENERIC"); + _graphicsMan->fadeInLong(); + _soundMan->playSound(28); + _events->_mouseFl = false; + _globals->_eventMode = EVENTMODE_CREDITS; + _globals->_creditsStartX = _globals->_creditsEndX = _globals->_creditsStartY = _globals->_creditsEndY = -1; + int soundId = 28; + do { + for (int i = 0; i < _globals->_creditsLineNumb; ++i) { + if (_globals->_creditsItem[i]._actvFl) { + int nextY = _globals->_creditsPosY + i * _globals->_creditsStep; + _globals->_creditsItem[i]._linePosY = nextY; + + if ((nextY - 21 >= 0) && (nextY - 21 <= 418)) { + int col = 0; + switch (_globals->_creditsItem[i]._color) { + case '1': + col = 163; + break; + case '2': + col = 161; + break; + case '3': + col = 162; + break; + default: + warning("Unknown color, default to col #1"); + col = 163; + break; + } + if (_globals->_creditsItem[i]._lineSize != -1) + displayCredits(nextY, _globals->_creditsItem[i]._line, col); + } + } + } + --_globals->_creditsPosY; + if (_globals->_creditsStartX != -1 || _globals->_creditsEndX != -1 || _globals->_creditsStartY != -1 || _globals->_creditsEndY != -1) { + _events->refreshScreenAndEvents(); + _graphicsMan->copySurface(_graphicsMan->_backBuffer, 60, 50, 520, 380, _graphicsMan->_frontBuffer, 60, 50); + } else { + _events->refreshScreenAndEvents(); + } + if (_globals->_creditsItem[_globals->_creditsLineNumb - 1]._linePosY <= 39) { + _globals->_creditsPosY = 440; + ++soundId; + if (soundId > 31) + soundId = 28; + _soundMan->playSound(soundId); + } + _globals->_creditsStartX = -1; + _globals->_creditsEndX = -1; + _globals->_creditsStartY = -1; + _globals->_creditsEndY = -1; + } while ((_events->getMouseButton() != 1) && (!shouldQuit())); + _graphicsMan->fadeOutLong(); + _globals->_eventMode = EVENTMODE_IGNORE; + _events->_mouseFl = true; +} + +void HopkinsEngine::handleOceanMouseEvents() { + _fontMan->hideText(9); + if (_events->_mouseCursorId != 16) + return; + + _events->getMouseX(); + if (_objectsMan->_zoneNum <= 0) + return; + + int oldPosX = _events->getMouseX(); + int oldPosY = _events->getMouseY(); + bool displAnim = false; + int oldX; + switch (_objectsMan->_zoneNum) { + case 1: + switch (_globals->_oceanDirection) { + case DIR_UP: + _objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "27,26,25,24,23,22,21,20,19,18,-1,", 6, false); + break; + case DIR_RIGHT: + _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); + break; + case DIR_DOWN: + _objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "9,10,11,12,13,14,15,16,17,18,-1,", 6, false); + break; + default: + break; + } + + _globals->_oceanDirection = DIR_LEFT; + _globals->_exitId = 1; + oldX = _objectsMan->getSpriteX(0); + for (;;) { + if (_globals->_speed == 1) + oldX -= 2; + else if (_globals->_speed == 2) + oldX -= 4; + else if (_globals->_speed == 3) + oldX -= 6; + _objectsMan->setSpriteX(0, oldX); + setSubmarineSprites(); + _events->refreshScreenAndEvents(); + if (_events->getMouseButton() == 1 && oldPosX == _events->getMouseX() && _events->getMouseY() == oldPosY) { + displAnim = true; + break; + } + + if (oldX <= -100) + break; + } + break; + case 2: + switch (_globals->_oceanDirection) { + case DIR_UP: + _objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "27,28,29,30,31,32,33,34,35,36,-1,", 6, false); + break; + case DIR_DOWN: + _objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "9,8,7,6,5,4,3,2,1,0,-1,", 6, false); + break; + case DIR_LEFT: + _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); + break; + default: + break; + } + _globals->_oceanDirection = DIR_RIGHT; + _globals->_exitId = 2; + oldX = _objectsMan->getSpriteX(0); + for (;;) { + if (_globals->_speed == 1) + oldX += 2; + else if (_globals->_speed == 2) + oldX += 4; + else if (_globals->_speed == 3) + oldX += 6; + _objectsMan->setSpriteX(0, oldX); + setSubmarineSprites(); + _events->refreshScreenAndEvents(); + if (_events->getMouseButton() == 1 && oldPosX == _events->getMouseX() && _events->getMouseY() == oldPosY) { + displAnim = true; + break; + } + if (oldX > 499) + break; + } + break; + case 3: + switch (_globals->_oceanDirection) { + case DIR_RIGHT: + oldX = _objectsMan->getSpriteX(0); + do { + if (_globals->_speed == 1) + oldX += 2; + else if (_globals->_speed == 2) + oldX += 4; + else if (_globals->_speed == 3) + oldX += 6; + _objectsMan->setSpriteX(0, oldX); + setSubmarineSprites(); + _events->refreshScreenAndEvents(); + if (_events->getMouseButton() == 1 && oldPosX == _events->getMouseX() && _events->getMouseY() == oldPosY) { + displAnim = true; + break; + } + } while (oldX <= 235); + if (!displAnim) + _objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "36,35,34,33,32,31,30,29,28,27,-1,", 6, false); + break; + case DIR_DOWN: + _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); + break; + case DIR_LEFT: + oldX = _objectsMan->getSpriteX(0); + do { + if (_globals->_speed == 1) + oldX -= 2; + else if (_globals->_speed == 2) + oldX -= 4; + else if (_globals->_speed == 3) + oldX -= 6; + _objectsMan->setSpriteX(0, oldX); + setSubmarineSprites(); + _events->refreshScreenAndEvents(); + if (_events->getMouseButton() == 1 && oldPosX == _events->getMouseX() && _events->getMouseY() == oldPosY) { + displAnim = true; + break; + } + } while (oldX > 236); + if (!displAnim) + _objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "18,19,20,21,22,23,24,25,26,27,-1,", 6, false); + break; + default: + break; + } + _globals->_oceanDirection = DIR_UP; + _globals->_exitId = 3; + break; + case 4: + switch (_globals->_oceanDirection) { + case DIR_UP: + _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); + break; + case DIR_RIGHT: + oldX = _objectsMan->getSpriteX(0); + do { + if (_globals->_speed == 1) + oldX += 2; + else if (_globals->_speed == 2) + oldX += 4; + else if (_globals->_speed == 3) + oldX += 6; + _objectsMan->setSpriteX(0, oldX); + setSubmarineSprites(); + _events->refreshScreenAndEvents(); + if (_events->getMouseButton() == 1 && oldPosX == _events->getMouseX() && _events->getMouseY() == oldPosY) { + displAnim = true; + break; + } + } while (oldX <= 235); + if (!displAnim) + _objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "0,1,2,3,4,5,6,7,8,9,-1,", 6, false); + break; + case DIR_LEFT: + oldX = _objectsMan->getSpriteX(0); + for (;;) { + if (_globals->_speed == 1) + oldX -= 2; + else if (_globals->_speed == 2) + oldX -= 4; + else if (_globals->_speed == 3) + oldX -= 6; + _objectsMan->setSpriteX(0, oldX); + setSubmarineSprites(); + _events->refreshScreenAndEvents(); + if (_events->getMouseButton() == 1 && oldPosX == _events->getMouseX() && _events->getMouseY() == oldPosY) + break; + + if (oldX <= 236) { + if (!displAnim) + _objectsMan->showSpecialActionAnimationWithFlip(_globals->_characterSpriteBuf, "18,17,16,15,14,13,12,11,10,9,-1,", 6, false); + break; + } + } + break; + default: + break; + } + _globals->_oceanDirection = DIR_DOWN; + _globals->_exitId = 4; + break; + } +} + +void HopkinsEngine::setSubmarineSprites() { + switch (_globals->_oceanDirection) { + case DIR_UP: + _objectsMan->setSpriteIndex(0, 27); + break; + case DIR_RIGHT: + _objectsMan->setSpriteIndex(0, 0); + break; + case DIR_DOWN: + _objectsMan->setSpriteIndex(0, 9); + break; + case DIR_LEFT: + _objectsMan->setSpriteIndex(0, 18); + break; + default: + break; + } +} + +void HopkinsEngine::handleOceanMaze(int16 curExitId, Common::String backgroundFilename, Directions defaultDirection, int16 exit1, int16 exit2, int16 exit3, int16 exit4, int16 soundId) { + _globals->_cityMapEnabledFl = false; + _graphicsMan->_noFadingFl = false; + _globals->_freezeCharacterFl = false; + _globals->_exitId = 0; + _globals->_disableInventFl = true; + _soundMan->playSound(soundId); + _globals->_characterSpriteBuf = _fileIO->loadFile("VAISSEAU.SPR"); + if (backgroundFilename.size()) + _graphicsMan->loadImage(backgroundFilename); + + if (curExitId == 77) + _objectsMan->loadLinkFile("IM77"); + else if (curExitId == 84) + _objectsMan->loadLinkFile("IM84"); + else if (curExitId == 91) + _objectsMan->loadLinkFile("IM91"); + else + _objectsMan->loadLinkFile("ocean"); + + if (!exit1) + _linesMan->disableZone(1); + if (!exit2) + _linesMan->disableZone(2); + if (!exit3) + _linesMan->disableZone(3); + if (!exit4) + _linesMan->disableZone(4); + + if (_globals->_oceanDirection == DIR_NONE) + _globals->_oceanDirection = defaultDirection; + + switch (_globals->_oceanDirection) { + case DIR_UP: + _objectsMan->_characterPos.x = 236; + _objectsMan->_startSpriteIndex = 27; + break; + case DIR_RIGHT: + _objectsMan->_characterPos.x = -20; + _objectsMan->_startSpriteIndex = 0; + break; + case DIR_DOWN: + _objectsMan->_characterPos.x = 236; + _objectsMan->_startSpriteIndex = 9; + break; + case DIR_LEFT: + _objectsMan->_characterPos.x = 415; + _objectsMan->_startSpriteIndex = 18; + break; + default: + break; + } + + _objectsMan->addStaticSprite(_globals->_characterSpriteBuf, Common::Point(_objectsMan->_characterPos.x, 110), 0, _objectsMan->_startSpriteIndex, 0, false, 0, 0); + _graphicsMan->setColorPercentage(252, 100, 100, 100); + _graphicsMan->setColorPercentage(253, 100, 100, 100); + _graphicsMan->setColorPercentage(251, 100, 100, 100); + _graphicsMan->setColorPercentage(254, 0, 0, 0); + _objectsMan->animateSprite(0); + _linesMan->_route = NULL; + _events->mouseOn(); + _events->changeMouseCursor(4); + + for (int cpt = 0; cpt <= 4; cpt++) + _events->refreshScreenAndEvents(); + + if (!_graphicsMan->_noFadingFl) + _graphicsMan->fadeInLong(); + _graphicsMan->_noFadingFl = false; + _globals->_eventMode = EVENTMODE_IGNORE; + + for (;;) { + int mouseButton = _events->getMouseButton(); + if (mouseButton && mouseButton == 1) + handleOceanMouseEvents(); + _linesMan->checkZone(); + setSubmarineSprites(); + + _events->refreshScreenAndEvents(); + if (_globals->_exitId || shouldQuit()) + break; + } + + if (_globals->_exitId == 1) + _globals->_exitId = exit1; + else if (_globals->_exitId == 2) + _globals->_exitId = exit2; + else if (_globals->_exitId == 3) + _globals->_exitId = exit3; + else if (_globals->_exitId == 4) + _globals->_exitId = exit4; + _graphicsMan->fadeOutLong(); + _objectsMan->removeSprite(0); + _objectsMan->clearScreen(); + _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR"); + _globals->_characterType = 0; +} + +void HopkinsEngine::syncSoundSettings() { + Engine::syncSoundSettings(); + + _soundMan->syncSoundSettings(); +} + +bool HopkinsEngine::displayAdultDisclaimer() { + int xp, yp; + int buttonIndex; + + _graphicsMan->_minX = 0; + _graphicsMan->_minY = 0; + _graphicsMan->_maxX = SCREEN_WIDTH; + _graphicsMan->_maxY = SCREEN_HEIGHT - 1; + _events->_breakoutFl = false; + _objectsMan->_forestFl = false; + _globals->_disableInventFl = true; + _globals->_exitId = 0; + + _graphicsMan->loadImage("ADULT"); + _graphicsMan->fadeInLong(); + _events->mouseOn(); + _events->changeMouseCursor(0); + _events->_mouseCursorId = 0; + _events->_mouseSpriteId = 0; + + do { + xp = _events->getMouseX(); + yp = _events->getMouseY(); + + buttonIndex = 0; + if (xp >= 37 && xp <= 169 && yp >= 406 && yp <= 445) + buttonIndex = 2; + else if (xp >= 424 && xp <= 602 && yp >= 406 && yp <= 445) + buttonIndex = 1; + + _events->refreshScreenAndEvents(); + } while (!shouldQuit() && (buttonIndex == 0 || _events->getMouseButton() != 1)); + + _globals->_disableInventFl = false; + _graphicsMan->fadeOutLong(); + + if (buttonIndex != 2) { + // Quit game + return false; + } else { + // Continue + _graphicsMan->_minX = 0; + _graphicsMan->_maxY = 20; + _graphicsMan->_maxX = SCREEN_WIDTH; + _graphicsMan->_maxY = SCREEN_HEIGHT - 20; + return true; + } +} + +} // End of namespace Hopkins |