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 "base/plugins.h"
24 #include "common/md5.h"
25 #include "common/memstream.h"
26 #include "common/str-array.h"
27 #include "common/file.h"
28 #include "common/translation.h"
29 #include "common/config-manager.h"
30 
31 #include "glk/detection.h"
32 #include "glk/game_description.h"
33 #include "glk/glk.h"
34 
35 #include "glk/adrift/detection.h"
36 #include "glk/advsys/detection.h"
37 #include "glk/agt/detection.h"
38 #include "glk/alan2/detection.h"
39 #include "glk/alan3/detection.h"
40 #include "glk/archetype/detection.h"
41 #include "glk/comprehend/detection.h"
42 #include "glk/glulx/detection.h"
43 #include "glk/hugo/detection.h"
44 #include "glk/jacl/detection.h"
45 #include "glk/level9/detection.h"
46 #include "glk/magnetic/detection.h"
47 #include "glk/quest/detection.h"
48 #include "glk/scott/detection.h"
49 #include "glk/zcode/detection.h"
50 
51 #ifndef RELEASE_BUILD
52 #include "glk/tads/detection.h"
53 #endif
54 
55 #include "base/plugins.h"
56 #include "common/md5.h"
57 #include "common/memstream.h"
58 #include "common/savefile.h"
59 #include "common/str-array.h"
60 #include "common/system.h"
61 #include "graphics/surface.h"
62 #include "common/config-manager.h"
63 #include "common/file.h"
64 #include "common/translation.h"
65 
66 static const DebugChannelDef debugFlagList[] = {
67 	{Glk::kDebugCore, "core", "Core engine debug level"},
68 	{Glk::kDebugScripts, "scripts", "Game scripts"},
69 	{Glk::kDebugGraphics, "graphics", "Graphics handling"},
70 	{Glk::kDebugSound, "sound", "Sound and Music handling"},
71 	{Glk::kDebugSpeech, "speech", "Text to Speech handling"},
72 	DEBUG_CHANNEL_END
73 };
74 
75 namespace Glk {
76 
getGlkGUIOptions()77 Common::String GlkDetectedGame::getGlkGUIOptions() {
78 #if defined (USE_TTS)
79 	return GUIO2(GUIO_NOMUSIC, GUIO_NOSUBTITLES);
80 #else
81 	return GUIO3(GUIO_NOSPEECH, GUIO_NOMUSIC, GUIO_NOSUBTITLES);
82 #endif
83 }
84 
GlkDetectedGame(const char * id,const char * desc,const Common::String & filename,GameSupportLevel supportLevel)85 GlkDetectedGame::GlkDetectedGame(const char *id, const char *desc, const Common::String &filename,
86 		GameSupportLevel supportLevel) :
87 		DetectedGame("glk", id, desc, Common::EN_ANY, Common::kPlatformUnknown) {
88 	setGUIOptions(getGlkGUIOptions());
89 	gameSupportLevel = supportLevel;
90 	addExtraEntry("filename", filename);
91 }
92 
GlkDetectedGame(const char * id,const char * desc,const Common::String & filename,Common::Language lang,GameSupportLevel supportLevel)93 GlkDetectedGame::GlkDetectedGame(const char *id, const char *desc, const Common::String &filename,
94 		Common::Language lang, GameSupportLevel supportLevel) : DetectedGame("glk", id, desc, lang, Common::kPlatformUnknown) {
95 	setGUIOptions(getGlkGUIOptions());
96 	gameSupportLevel = supportLevel;
97 	addExtraEntry("filename", filename);
98 }
99 
GlkDetectedGame(const char * id,const char * desc,const char * xtra,const Common::String & filename,Common::Language lang,GameSupportLevel supportLevel)100 GlkDetectedGame::GlkDetectedGame(const char *id, const char *desc, const char *xtra,
101 		const Common::String &filename, Common::Language lang,
102 		GameSupportLevel supportLevel) :
103 		DetectedGame("glk", id, desc, lang, Common::kPlatformUnknown, xtra) {
104 	setGUIOptions(getGlkGUIOptions());
105 	gameSupportLevel = supportLevel;
106 	addExtraEntry("filename", filename);
107 }
108 
GlkDetectedGame(const char * id,const char * desc,const Common::String & filename,const Common::String & md5,size_t filesize,GameSupportLevel supportLevel)109 GlkDetectedGame::GlkDetectedGame(const char *id, const char *desc, const Common::String &filename,
110 		const Common::String &md5, size_t filesize, GameSupportLevel supportLevel) :
111 		DetectedGame("glk", id, desc, Common::UNK_LANG, Common::kPlatformUnknown) {
112 	setGUIOptions(getGlkGUIOptions());
113 	gameSupportLevel = supportLevel;
114 	addExtraEntry("filename", filename);
115 
116 	canBeAdded = true;
117 	hasUnknownFiles = true;
118 
119 	FileProperties fp;
120 	fp.md5 = md5;
121 	fp.size = filesize;
122 	matchedFiles[filename] = fp;
123 }
124 
125 } // End of namespace Glk
126 
getSupportedGames() const127 PlainGameList GlkMetaEngineDetection::getSupportedGames() const {
128 	PlainGameList list;
129 	Glk::Adrift::AdriftMetaEngine::getSupportedGames(list);
130 	Glk::AdvSys::AdvSysMetaEngine::getSupportedGames(list);
131 	Glk::AGT::AGTMetaEngine::getSupportedGames(list);
132 	Glk::Alan2::Alan2MetaEngine::getSupportedGames(list);
133 	Glk::Alan3::Alan3MetaEngine::getSupportedGames(list);
134 	Glk::Archetype::ArchetypeMetaEngine::getSupportedGames(list);
135 	Glk::Comprehend::ComprehendMetaEngine::getSupportedGames(list);
136 	Glk::Glulx::GlulxMetaEngine::getSupportedGames(list);
137 	Glk::Hugo::HugoMetaEngine::getSupportedGames(list);
138 	Glk::JACL::JACLMetaEngine::getSupportedGames(list);
139 	Glk::Level9::Level9MetaEngine::getSupportedGames(list);
140 	Glk::Magnetic::MagneticMetaEngine::getSupportedGames(list);
141 	Glk::Quest::QuestMetaEngine::getSupportedGames(list);
142 	Glk::Scott::ScottMetaEngine::getSupportedGames(list);
143 	Glk::ZCode::ZCodeMetaEngine::getSupportedGames(list);
144 #ifndef RELEASE_BUILD
145 	Glk::TADS::TADSMetaEngine::getSupportedGames(list);
146 #endif
147 
148 	return list;
149 }
150 
151 #define FIND_GAME(SUBENGINE) \
152 	Glk::GameDescriptor gd##SUBENGINE = Glk::SUBENGINE::SUBENGINE##MetaEngine::findGame(gameId); \
153 	if (gd##SUBENGINE._description) return gd##SUBENGINE
154 
getDebugChannels() const155 const DebugChannelDef *GlkMetaEngineDetection::getDebugChannels() const {
156 	return debugFlagList;
157 }
158 
findGame(const char * gameId) const159 PlainGameDescriptor GlkMetaEngineDetection::findGame(const char *gameId) const {
160 	FIND_GAME(Adrift);
161 	FIND_GAME(AdvSys);
162 	FIND_GAME(Alan2);
163 	FIND_GAME(AGT);
164 	FIND_GAME(Alan3);
165 	FIND_GAME(Archetype);
166 	FIND_GAME(Comprehend);
167 	FIND_GAME(Glulx);
168 	FIND_GAME(Hugo);
169 	FIND_GAME(JACL);
170 	FIND_GAME(Level9);
171 	FIND_GAME(Magnetic);
172 	FIND_GAME(Quest);
173 	FIND_GAME(Scott);
174 	FIND_GAME(ZCode);
175 #ifndef RELEASE_BUILD
176 	FIND_GAME(TADS);
177 #endif
178 
179 	return PlainGameDescriptor();
180 }
181 
182 #undef FIND_GAME
183 
detectGames(const Common::FSList & fslist) const184 DetectedGames GlkMetaEngineDetection::detectGames(const Common::FSList &fslist) const {
185 #ifndef RELEASE_BUILD
186 	// This is as good a place as any to detect multiple sub-engines using the same Ids
187 	detectClashes();
188 #endif
189 
190 	DetectedGames detectedGames;
191 	Glk::Adrift::AdriftMetaEngine::detectGames(fslist, detectedGames);
192 	Glk::AdvSys::AdvSysMetaEngine::detectGames(fslist, detectedGames);
193 	Glk::AGT::AGTMetaEngine::detectGames(fslist, detectedGames);
194 	Glk::Alan2::Alan2MetaEngine::detectGames(fslist, detectedGames);
195 	Glk::Alan3::Alan3MetaEngine::detectGames(fslist, detectedGames);
196 	Glk::Archetype::ArchetypeMetaEngine::detectGames(fslist, detectedGames);
197 	Glk::Comprehend::ComprehendMetaEngine::detectGames(fslist, detectedGames);
198 	Glk::Glulx::GlulxMetaEngine::detectGames(fslist, detectedGames);
199 	Glk::Hugo::HugoMetaEngine::detectGames(fslist, detectedGames);
200 	Glk::JACL::JACLMetaEngine::detectGames(fslist, detectedGames);
201 	Glk::Level9::Level9MetaEngine::detectGames(fslist, detectedGames);
202 	Glk::Magnetic::MagneticMetaEngine::detectGames(fslist, detectedGames);
203 	Glk::Quest::QuestMetaEngine::detectGames(fslist, detectedGames);
204 	Glk::Scott::ScottMetaEngine::detectGames(fslist, detectedGames);
205 	Glk::ZCode::ZCodeMetaEngine::detectGames(fslist, detectedGames);
206 #ifndef RELEASE_BUILD
207 	Glk::TADS::TADSMetaEngine::detectGames(fslist, detectedGames);
208 #endif
209 
210 	return detectedGames;
211 }
212 
detectClashes() const213 void GlkMetaEngineDetection::detectClashes() const {
214 	Common::StringMap map;
215 	Glk::Adrift::AdriftMetaEngine::detectClashes(map);
216 	Glk::AdvSys::AdvSysMetaEngine::detectClashes(map);
217 	Glk::AGT::AGTMetaEngine::detectClashes(map);
218 	Glk::Alan2::Alan2MetaEngine::detectClashes(map);
219 	Glk::Alan3::Alan3MetaEngine::detectClashes(map);
220 	Glk::Archetype::ArchetypeMetaEngine::detectClashes(map);
221 	Glk::Comprehend::ComprehendMetaEngine::detectClashes(map);
222 	Glk::Glulx::GlulxMetaEngine::detectClashes(map);
223 	Glk::Hugo::HugoMetaEngine::detectClashes(map);
224 	Glk::JACL::JACLMetaEngine::detectClashes(map);
225 	Glk::Level9::Level9MetaEngine::detectClashes(map);
226 	Glk::Magnetic::MagneticMetaEngine::detectClashes(map);
227 	Glk::Quest::QuestMetaEngine::detectClashes(map);
228 	Glk::Scott::ScottMetaEngine::detectClashes(map);
229 	Glk::ZCode::ZCodeMetaEngine::detectClashes(map);
230 #ifndef RELEASE_BUILD
231 	Glk::TADS::TADSMetaEngine::detectClashes(map);
232 #endif
233 }
234 
getExtraGuiOptions(const Common::String &) const235 const ExtraGuiOptions GlkMetaEngineDetection::getExtraGuiOptions(const Common::String &) const {
236 	ExtraGuiOptions  options;
237 #if defined(USE_TTS)
238 	static const ExtraGuiOption ttsSpeakOptions = {
239 		_s("Enable Text to Speech"),
240 		_s("Use TTS to read the text"),
241 		"speak",
242 		false
243 	};
244 	static const ExtraGuiOption ttsSpeakInputOptions = {
245 		_s("Also read input text"),
246 		_s("Use TTS to read the input text"),
247 		"speak_input",
248 		false
249 	};
250 	options.push_back(ttsSpeakOptions);
251 	options.push_back(ttsSpeakInputOptions);
252 #endif
253 	return options;
254 }
255 
256 REGISTER_PLUGIN_STATIC(GLK_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, GlkMetaEngineDetection);
257