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