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/saveload.h"
25 #include "sherlock/scalpel/scalpel.h"
26 #include "sherlock/tattoo/tattoo.h"
27 #include "common/system.h"
28 #include "common/translation.h"
29 #include "engines/advancedDetector.h"
30 
31 namespace Sherlock {
32 
33 struct SherlockGameDescription {
34 	ADGameDescription desc;
35 
36 	GameType gameID;
37 };
38 
getGameID() const39 GameType SherlockEngine::getGameID() const {
40 	return _gameDescription->gameID;
41 }
42 
getPlatform() const43 Common::Platform SherlockEngine::getPlatform() const {
44 	return _gameDescription->desc.platform;
45 }
46 
getLanguage() const47 Common::Language SherlockEngine::getLanguage() const {
48 	return _gameDescription->desc.language;
49 }
50 
51 } // End of namespace Sherlock
52 
53 static const PlainGameDescriptor sherlockGames[] = {
54 	{ "scalpel", "The Case of the Serrated Scalpel" },
55 	{ "rosetattoo", "The Case of the Rose Tattoo" },
56 	{0, 0}
57 };
58 
59 
60 #define GAMEOPTION_ORIGINAL_SAVES	GUIO_GAMEOPTIONS1
61 #define GAMEOPTION_FADE_STYLE		GUIO_GAMEOPTIONS2
62 #define GAMEOPTION_HELP_STYLE		GUIO_GAMEOPTIONS3
63 #define GAMEOPTION_PORTRAITS_ON		GUIO_GAMEOPTIONS4
64 #define GAMEOPTION_WINDOW_STYLE		GUIO_GAMEOPTIONS5
65 #define GAMEOPTION_TRANSPARENT_WINDOWS		GUIO_GAMEOPTIONS6
66 
67 static const ADExtraGuiOptionsMap optionsList[] = {
68 	{
69 		GAMEOPTION_ORIGINAL_SAVES,
70 		{
71 			_s("Use original save/load screens"),
72 			_s("Use the original save/load screens instead of the ScummVM ones"),
73 			"originalsaveload",
74 			false
75 		}
76 	},
77 
78 	{
79 		GAMEOPTION_FADE_STYLE,
80 		{
81 			_s("Pixellated scene transitions"),
82 			_s("When changing scenes, a randomized pixel transition is done"),
83 			"fade_style",
84 			true
85 		}
86 	},
87 
88 	{
89 		GAMEOPTION_HELP_STYLE,
90 		{
91 			_s("Don't show hotspots when moving mouse"),
92 			_s("Only show hotspot names after you actually click on a hotspot or action button"),
93 			"help_style",
94 			false
95 		}
96 	},
97 
98 	{
99 		GAMEOPTION_PORTRAITS_ON,
100 		{
101 			_s("Show character portraits"),
102 			_s("Show portraits for the characters when conversing"),
103 			"portraits_on",
104 			true
105 		}
106 	},
107 
108 	{
109 		GAMEOPTION_WINDOW_STYLE,
110 		{
111 			_s("Slide dialogs into view"),
112 			_s("Slide UI dialogs into view, rather than simply showing them immediately"),
113 			"window_style",
114 			true
115 		}
116 	},
117 
118 	{
119 		GAMEOPTION_TRANSPARENT_WINDOWS,
120 		{
121 			_s("Transparent windows"),
122 			_s("Show windows with a partially transparent background"),
123 			"transparent_windows",
124 			true
125 		}
126 	},
127 
128 	AD_EXTRA_GUI_OPTIONS_TERMINATOR
129 };
130 
131 
132 #include "sherlock/detection_tables.h"
133 
134 class SherlockMetaEngine : public AdvancedMetaEngine {
135 public:
SherlockMetaEngine()136 	SherlockMetaEngine() : AdvancedMetaEngine(Sherlock::gameDescriptions, sizeof(Sherlock::SherlockGameDescription),
137 		sherlockGames, optionsList) {}
138 
getName() const139 	virtual const char *getName() const {
140 		return "Sherlock";
141 	}
142 
getOriginalCopyright() const143 	virtual const char *getOriginalCopyright() const {
144 		return "Sherlock (C) 1992-1996 Mythos Software, (C) 1992-1996 Electronic Arts";
145 	}
146 
147 	/**
148 	 * Creates an instance of the game engine
149 	 */
150 	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
151 
152 	/**
153 	 * Returns a list of features the game's MetaEngine support
154 	 */
155 	virtual bool hasFeature(MetaEngineFeature f) const;
156 
157 	/**
158 	 * Return a list of savegames
159 	 */
160 	virtual SaveStateList listSaves(const char *target) const;
161 
162 	/**
163 	 * Returns the maximum number of allowed save slots
164 	 */
165 	virtual int getMaximumSaveSlot() const;
166 
167 	/**
168 	 * Deletes a savegame in the specified slot
169 	 */
170 	virtual void removeSaveState(const char *target, int slot) const;
171 
172 	/**
173 	 * Given a specified savegame slot, returns extended information for the save
174 	 */
175 	SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
176 };
177 
createInstance(OSystem * syst,Engine ** engine,const ADGameDescription * desc) const178 bool SherlockMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
179 	const Sherlock::SherlockGameDescription *gd = (const Sherlock::SherlockGameDescription *)desc;
180 	if (gd) {
181 		switch (gd->gameID) {
182 		case Sherlock::GType_SerratedScalpel:
183 			*engine = new Sherlock::Scalpel::ScalpelEngine(syst, gd);
184 			break;
185 		case Sherlock::GType_RoseTattoo:
186 			*engine = new Sherlock::Tattoo::TattooEngine(syst, gd);
187 			break;
188 		default:
189 			error("Unknown game");
190 			break;
191 		}
192 	}
193 	return gd != 0;
194 }
195 
hasFeature(MetaEngineFeature f) const196 bool SherlockMetaEngine::hasFeature(MetaEngineFeature f) const {
197 	return
198 		(f == kSupportsListSaves) ||
199 		(f == kSupportsLoadingDuringStartup) ||
200 		(f == kSupportsDeleteSave) ||
201 		(f == kSavesSupportMetaInfo) ||
202 		(f == kSavesSupportThumbnail) ||
203 		(f == kSavesSupportCreationDate) ||
204 		(f == kSavesSupportPlayTime) ||
205 		(f == kSimpleSavesNames);
206 }
207 
hasFeature(EngineFeature f) const208 bool Sherlock::SherlockEngine::hasFeature(EngineFeature f) const {
209 	return
210 		(f == kSupportsRTL) ||
211 		(f == kSupportsLoadingDuringRuntime) ||
212 		(f == kSupportsSavingDuringRuntime);
213 }
214 
isDemo() const215 bool Sherlock::SherlockEngine::isDemo() const {
216 	return _gameDescription->desc.flags & ADGF_DEMO;
217 }
218 
listSaves(const char * target) const219 SaveStateList SherlockMetaEngine::listSaves(const char *target) const {
220 	return Sherlock::SaveManager::getSavegameList(target);
221 }
222 
getMaximumSaveSlot() const223 int SherlockMetaEngine::getMaximumSaveSlot() const {
224 	return MAX_SAVEGAME_SLOTS;
225 }
226 
removeSaveState(const char * target,int slot) const227 void SherlockMetaEngine::removeSaveState(const char *target, int slot) const {
228 	Common::String filename = Sherlock::SaveManager(nullptr, target).generateSaveName(slot);
229 	g_system->getSavefileManager()->removeSavefile(filename);
230 }
231 
querySaveMetaInfos(const char * target,int slot) const232 SaveStateDescriptor SherlockMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
233 	Common::String filename = Sherlock::SaveManager(nullptr, target).generateSaveName(slot);
234 	Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename);
235 
236 	if (f) {
237 		Sherlock::SherlockSavegameHeader header;
238 		if (!Sherlock::SaveManager::readSavegameHeader(f, header, false)) {
239 			delete f;
240 			return SaveStateDescriptor();
241 		}
242 		delete f;
243 
244 		// Create the return descriptor
245 		SaveStateDescriptor desc(slot, header._saveName);
246 		desc.setThumbnail(header._thumbnail);
247 		desc.setSaveDate(header._year, header._month, header._day);
248 		desc.setSaveTime(header._hour, header._minute);
249 		desc.setPlayTime(header._totalFrames * GAME_FRAME_TIME);
250 
251 		return desc;
252 	}
253 
254 	return SaveStateDescriptor();
255 }
256 
257 
258 #if PLUGIN_ENABLED_DYNAMIC(SHERLOCK)
259 	REGISTER_PLUGIN_DYNAMIC(SHERLOCK, PLUGIN_TYPE_ENGINE, SherlockMetaEngine);
260 #else
261 	REGISTER_PLUGIN_STATIC(SHERLOCK, PLUGIN_TYPE_ENGINE, SherlockMetaEngine);
262 #endif
263