aboutsummaryrefslogtreecommitdiff
path: root/engines/game.h
blob: 8316857e2494503a772f722551c4a5701fc7ec83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/* 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.
 *
 */

#ifndef ENGINES_GAME_H
#define ENGINES_GAME_H

#include "common/array.h"
#include "common/hash-str.h"
#include "common/str.h"
#include "common/str-array.h"
#include "common/language.h"
#include "common/platform.h"

/**
 * A simple structure used to map gameids (like "monkey", "sword1", ...) to
 * nice human readable and descriptive game titles (like "The Secret of Monkey Island").
 * This is a plain struct to make it possible to declare NULL-terminated C arrays
 * consisting of PlainGameDescriptors.
 */
struct PlainGameDescriptor {
	const char *gameId;
	const char *description;

	static PlainGameDescriptor empty();
	static PlainGameDescriptor of(const char *gameId, const char *description);
};

/**
 * Given a list of PlainGameDescriptors, returns the first PlainGameDescriptor
 * matching the given gameid. If not match is found return 0.
 * The end of the list must be marked by an entry with gameid 0.
 */
const PlainGameDescriptor *findPlainGameDescriptor(const char *gameid, const PlainGameDescriptor *list);

class PlainGameList : public Common::Array<PlainGameDescriptor> {
public:
	PlainGameList() {}
	PlainGameList(const PlainGameList &list) : Common::Array<PlainGameDescriptor>(list) {}
	PlainGameList(const PlainGameDescriptor *g) {
		while (g->gameId) {
			push_back(*g);
			g++;
		}
	}
};

/**
 * The description of a game supported by an engine
 */
struct QualifiedGameDescriptor {
	Common::String engineId;
	Common::String gameId;
	Common::String description;

	QualifiedGameDescriptor() {}
	QualifiedGameDescriptor(const char *engine, const PlainGameDescriptor &pgd);
};

typedef Common::Array<QualifiedGameDescriptor> QualifiedGameList;

/**
 * Ths is an enum to describe how done a game is. This also indicates what level of support is expected.
 */
enum GameSupportLevel {
	kStableGame = 0, // the game is fully supported
	kTestingGame, // the game is not supposed to end up in releases yet but is ready for public testing
	kUnstableGame // the game is not even ready for public testing yet
};


/**
 * A record describing the properties of a file. Used on the existing
 * files while detecting a game.
 */
struct FileProperties {
	int32 size;
	Common::String md5;

	FileProperties() : size(-1) {}
};

/**
 * A map of all relevant existing files while detecting.
 */
typedef Common::HashMap<Common::String, FileProperties, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FilePropertiesMap;

/**
 * Details about a given game.
 *
 * While PlainGameDescriptor refers to a game supported by an engine, this refers to a game copy
 * that has been detected by an engine's detector.
 * It contains all the necessary data to add the game to the configuration manager and / or to launch it.
 */
struct DetectedGame {
	DetectedGame();
	DetectedGame(const Common::String &engine, const PlainGameDescriptor &pgd);
	DetectedGame(const Common::String &engine, const Common::String &id,
	               const Common::String &description,
	               Common::Language language = Common::UNK_LANG,
	               Common::Platform platform = Common::kPlatformUnknown,
	               const Common::String &extra = Common::String());

	void setGUIOptions(const Common::String &options);
	void appendGUIOptions(const Common::String &str);
	Common::String getGUIOptions() const { return _guiOptions; }

	Common::String engineId;

	/**
	 * A game was detected, but some files were not recognized
	 *
	 * This can happen when the md5 or size of the detected files did not match the engine's detection tables.
	 * When this is true, the list of matched files below contains detail about the unknown files.
	 *
	 * @see matchedFiles
	 */
	bool hasUnknownFiles;

	/**
	 * An optional list of the files that were used to match the game with the engine's detection tables
	 */
	FilePropertiesMap matchedFiles;

	/**
	 * This detection entry contains enough data to add the game to the configuration manager and launch it
	 *
	 * @see matchedGame
	 */
	bool canBeAdded;

	Common::String gameId;
	Common::String preferredTarget;
	Common::String description;
	Common::Language language;
	Common::Platform platform;
	Common::String path;
	Common::String shortPath;
	Common::String extra;

	/**
	 * What level of support is expected of this game
	 */
	GameSupportLevel gameSupportLevel;

	/**
	 * A list of extra keys to write to the configuration file
	 */
	Common::StringMap _extraConfigEntries;

	/**
	 * Allows adding of extra entries to be saved as part of the detection entry
	 * in the configuration file.
	 * @remarks		Any entry added using this should not be relied on being present
	 *				in the configuration file, since starting games directly from the
	 *				command line bypasses the game detection code
	 */
	void addExtraEntry(const Common::String &key, const Common::String &value) {
		_extraConfigEntries[key] = value;
	}
private:
	/**
	 * Update the description string by appending (EXTRA/PLATFORM/LANG) to it.
	 * Values that are missing are omitted, so e.g. (EXTRA/LANG) would be
	 * added if no platform has been specified but a language and an extra string.
	 */
	Common::String updateDesc() const;

	Common::String _guiOptions;
};

/** List of games. */
typedef Common::Array<DetectedGame> DetectedGames;

/**
 * Contains a list of games found by the engines' detectors.
 *
 * Each detected game can either:
 * - be fully recognized (e.g. an exact match was found in the detection tables of an engine)
 * - be an unknown variant (e.g. a game using files with the same name was found in the detection tables)
 * - be recognized with unknown files (e.g. the game was exactly not found in the detection tables,
 *              but the detector was able to gather enough data to allow launching the game)
 *
 * Practically, this means a detected game can be in both the recognized game list and in the unknown game
 * report handled by this class.
 */
class DetectionResults {
public:
	explicit DetectionResults(const DetectedGames &detectedGames);

	/**
	 * List all the games that were recognized by the engines
	 *
	 * Recognized games can be added to the configuration manager and then launched.
	 */
	DetectedGames listRecognizedGames() const;

	/**
	 * List all the games that were detected
	 *
	 * That includes entries that don't have enough information to be added to the
	 * configuration manager.
	 */
	DetectedGames listDetectedGames() const;

	/**
	 * Were unknown game variants found by the engines?
	 *
	 * When unknown game variants are found, an unknown game report can be generated.
	 */
	bool foundUnknownGames() const;

	/**
	 * Generate a report that we found an unknown game variant.
	 *
	 * @see ::generateUnknownGameReport
	 */
	Common::String generateUnknownGameReport(bool translate, uint32 wordwrapAt = 0) const;

private:
	DetectedGames _detectedGames;
};

/**
 * Generate a report that we found an unknown game variant, together with the file
 * names, sizes and MD5 sums.
 *
 * @param translate translate the report to the currently active GUI language
 * @param fullPath include the full path where the files are located, otherwise only the name
 *                 of last component of the path is included
 * @param wordwrapAt word wrap the text part of the report after a number of characters
 */
Common::String generateUnknownGameReport(const DetectedGames &detectedGames, bool translate, bool fullPath, uint32 wordwrapAt = 0);
Common::String generateUnknownGameReport(const DetectedGame &detectedGame, bool translate, bool fullPath, uint32 wordwrapAt = 0);

#endif