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 "sherlock/sherlock.h"
24 #include "sherlock/surface.h"
25 #include "common/scummsys.h"
26 #include "common/config-manager.h"
27 #include "common/debug-channels.h"
28 
29 namespace Sherlock {
30 
SherlockEngine(OSystem * syst,const SherlockGameDescription * gameDesc)31 SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc) :
32 		Engine(syst), _gameDescription(gameDesc), _randomSource("Sherlock") {
33 	_animation = nullptr;
34 	_debugger = nullptr;
35 	_events = nullptr;
36 	_fixedText = nullptr;
37 	_inventory = nullptr;
38 	_journal = nullptr;
39 	_map = nullptr;
40 	_music = nullptr;
41 	_people = nullptr;
42 	_res = nullptr;
43 	_saves = nullptr;
44 	_scene = nullptr;
45 	_screen = nullptr;
46 	_sound = nullptr;
47 	_talk = nullptr;
48 	_ui = nullptr;
49 	_useEpilogue2 = false;
50 	_loadGameSlot = -1;
51 	_canLoadSave = false;
52 	_showOriginalSavesDialog = false;
53 	_interactiveFl = true;
54 	_isScreenDoubled = false;
55 }
56 
~SherlockEngine()57 SherlockEngine::~SherlockEngine() {
58 	delete _animation;
59 	//_debugger is deleted by Engine
60 	delete _events;
61 	delete _fixedText;
62 	delete _journal;
63 	delete _map;
64 	delete _people;
65 	delete _saves;
66 	delete _scene;
67 	delete _screen;
68 	delete _music;
69 	delete _sound;
70 	delete _talk;
71 	delete _ui;
72 	delete _inventory;
73 	delete _res;
74 }
75 
initialize()76 void SherlockEngine::initialize() {
77 	Fonts::setVm(this);
78 	ImageFile::setVm(this);
79 	ImageFile3DO::setVm(this);
80 	BaseObject::setVm(this);
81 
82 	if (isDemo()) {
83 		Common::File f;
84 		// The interactive demo doesn't have an intro thus doesn't include TITLE.SND
85 		// At the opposite, the non-interactive demo is only the intro.
86 		if (f.exists("TITLE.SND"))
87 			_interactiveFl = false;
88 	}
89 
90 	_res = new Resources(this);
91 	_animation = new Animation(this);
92 	_debugger = Debugger::init(this);
93 	setDebugger(_debugger);
94 	_events = new Events(this);
95 	_fixedText = FixedText::init(this);
96 	_inventory = Inventory::init(this);
97 	_map = Map::init(this);
98 	_music = new Music(this, _mixer);
99 	_journal = Journal::init(this);
100 	_people = People::init(this);
101 	_saves = SaveManager::init(this, _targetName);
102 	_scene = Scene::init(this);
103 	_screen = Screen::init(this);
104 	_sound = new Sound(this, _mixer);
105 	_talk = Talk::init(this);
106 	_ui = UserInterface::init(this);
107 
108 	// Load game settings
109 	loadConfig();
110 
111 	if (getPlatform() == Common::kPlatform3DO) {
112 		// Disable portraits on 3DO
113 		// 3DO does not include portrait data
114 		_people->_portraitsOn = false;
115 	}
116 }
117 
run()118 Common::Error SherlockEngine::run() {
119 	// Initialize the engine
120 	initialize();
121 
122 	// Flag for whether to show original saves dialog rather than the ScummVM GMM
123 	_showOriginalSavesDialog = ConfMan.getBool("originalsaveload");
124 
125 	// If requested, load a savegame instead of showing the intro
126 	if (ConfMan.hasKey("save_slot")) {
127 		int saveSlot = ConfMan.getInt("save_slot");
128 		if (saveSlot >= 0 && saveSlot <= MAX_SAVEGAME_SLOTS)
129 			_loadGameSlot = saveSlot;
130 	}
131 
132 	if (_loadGameSlot != -1) {
133 		_saves->loadGame(_loadGameSlot);
134 		_loadGameSlot = -1;
135 	} else {
136 		do {
137 			showOpening();
138 		} while (!shouldQuit() && !_interactiveFl);
139 	}
140 
141 	while (!shouldQuit()) {
142 		// Prepare for scene, and handle any game-specific scenes. This allows
143 		// for game specific cutscenes or mini-games that aren't standard scenes
144 		startScene();
145 		if (shouldQuit())
146 			break;
147 
148 		// Clear the screen
149 		_screen->clear();
150 
151 		// Reset UI flags
152 		_ui->reset();
153 
154 		// Reset the data for the player character (Sherlock)
155 		_people->reset();
156 
157 		// Initialize and load the scene.
158 		_scene->selectScene();
159 
160 		// Scene handling loop
161 		sceneLoop();
162 	}
163 
164 	return Common::kNoError;
165 }
166 
sceneLoop()167 void SherlockEngine::sceneLoop() {
168 	while (!shouldQuit() && _scene->_goToScene == -1) {
169 		// See if a script needs to be completed from either a goto room code,
170 		// or a script that was interrupted by another script
171 		if (_talk->_scriptMoreFlag == 1 || _talk->_scriptMoreFlag == 3)
172 			_talk->talkTo(_talk->_scriptName);
173 		else
174 			_talk->_scriptMoreFlag = 0;
175 
176 		// Handle any input from the keyboard or mouse
177 		handleInput();
178 
179 		if (_people->_savedPos.x == -1) {
180 			_canLoadSave = true;
181 			_scene->doBgAnim();
182 			_canLoadSave = false;
183 		}
184 	}
185 
186 	_scene->freeScene();
187 	_people->freeWalk();
188 }
189 
handleInput()190 void SherlockEngine::handleInput() {
191 	_canLoadSave = _ui->_menuMode == STD_MODE || _ui->_menuMode == LAB_MODE;
192 	_events->pollEventsAndWait();
193 	_canLoadSave = false;
194 
195 	// See if a key or mouse button is pressed
196 	_events->setButtonState();
197 
198 	_ui->handleInput();
199 }
200 
readFlags(int flagNum)201 bool SherlockEngine::readFlags(int flagNum) {
202 	bool value = _flags[ABS(flagNum)];
203 	if (flagNum < 0)
204 		value = !value;
205 
206 	return value;
207 }
208 
setFlags(int flagNum)209 void SherlockEngine::setFlags(int flagNum) {
210 	_flags[ABS(flagNum)] = flagNum >= 0;
211 
212 	_scene->checkSceneFlags(true);
213 }
214 
setFlagsDirect(int flagNum)215 void SherlockEngine::setFlagsDirect(int flagNum) {
216 	_flags[ABS(flagNum)] = flagNum >= 0;
217 }
218 
loadConfig()219 void SherlockEngine::loadConfig() {
220 	// Load sound settings
221 	syncSoundSettings();
222 
223 	ConfMan.registerDefault("font", getGameID() == GType_SerratedScalpel ? 1 : 4);
224 
225 	_screen->setFont(ConfMan.getInt("font"));
226 	if (getGameID() == GType_SerratedScalpel)
227 		_screen->_fadeStyle = ConfMan.getBool("fade_style");
228 
229 	_ui->_helpStyle = ConfMan.getBool("help_style");
230 	_ui->_slideWindows = ConfMan.getBool("window_style");
231 	_people->_portraitsOn = ConfMan.getBool("portraits_on");
232 }
233 
saveConfig()234 void SherlockEngine::saveConfig() {
235 	ConfMan.setBool("mute", !_sound->_digitized);
236 	ConfMan.setBool("music_mute", !_music->_musicOn);
237 	ConfMan.setBool("speech_mute", !_sound->_speechOn);
238 	ConfMan.setInt("music_volume", _music->_musicVolume);
239 	ConfMan.setInt("sfx_volume", _sound->_soundVolume);
240 	ConfMan.setInt("speech_volume", _sound->_soundVolume);
241 
242 	ConfMan.setInt("font", _screen->fontNumber());
243 	ConfMan.setBool("fade_style", _screen->_fadeStyle);
244 	ConfMan.setBool("help_style", _ui->_helpStyle);
245 	ConfMan.setBool("window_style", _ui->_slideWindows);
246 	ConfMan.setBool("portraits_on", _people->_portraitsOn);
247 
248 	ConfMan.flushToDisk();
249 }
250 
syncSoundSettings()251 void SherlockEngine::syncSoundSettings() {
252 	Engine::syncSoundSettings();
253 
254 	// Load sound-related settings
255 	_sound->syncSoundSettings();
256 	_music->syncMusicSettings();
257 }
258 
synchronize(Serializer & s)259 void SherlockEngine::synchronize(Serializer &s) {
260 	for (uint idx = 0; idx < _flags.size(); ++idx)
261 		s.syncAsByte(_flags[idx]);
262 }
263 
canLoadGameStateCurrently()264 bool SherlockEngine::canLoadGameStateCurrently() {
265 	return _canLoadSave;
266 }
267 
canSaveGameStateCurrently()268 bool SherlockEngine::canSaveGameStateCurrently() {
269 	return _canLoadSave;
270 }
271 
loadGameState(int slot)272 Common::Error SherlockEngine::loadGameState(int slot) {
273 	_saves->loadGame(slot);
274 	return Common::kNoError;
275 }
276 
saveGameState(int slot,const Common::String & desc,bool isAutosave)277 Common::Error SherlockEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
278 	_saves->saveGame(slot, desc);
279 	return Common::kNoError;
280 }
281 
282 } // End of namespace Sherlock
283