aboutsummaryrefslogtreecommitdiff
path: root/common/advancedDetector.h
blob: f910450a25d16bdb3843fce1a1c9a27746f8b213 (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
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2005-2006 The ScummVM project
 *
 * 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.
 *
 * $URL$
 * $Id$
 *
 */
#ifndef COMMON_ADVANCED_DETECTOR_H
#define COMMON_ADVANCED_DETECTOR_H

#include "common/fs.h"

#include "base/game.h"	// For PlainGameDescriptor and GameList
#include "base/plugins.h"	// For DetectedGameList


namespace Common {

struct ADGameFileDescription {
	const char *fileName;
	uint16 fileType;
	const char *md5;
};

struct ADGameDescription {
	const char *name;
	const char *extra;
	int filesCount;
	const ADGameFileDescription *filesDescriptions;
	Language language;
	Platform platform;
};

struct ADObsoleteGameID {
	const char *from;
	const char *to;
	Common::Platform platform;
};

typedef Array<int> ADList;
typedef Array<const ADGameDescription*> ADGameDescList;

// FIXME/TODO: Rename this function to something more sensible.
// Possibly move it inside class AdvancedDetector ?
// Maybe rename it to something like asGameList or pgdArrayToGameList,
// and move it to base/game.h. Or add a constructor to GameList ... ?
GameList real_ADVANCED_DETECTOR_GAMEID_LIST(const PlainGameDescriptor *list);

// FIXME/TODO: Rename this function to something more sensible.
// Possibly move it inside class AdvancedDetector ?
GameDescriptor real_ADVANCED_DETECTOR_FIND_GAMEID(
	const char *gameid,
	const PlainGameDescriptor *list,
	const Common::ADObsoleteGameID *obsoleteList
	);


// FIXME/TODO: Rename this function to something more sensible.
// Possibly move it inside class AdvancedDetector ?
// Also, we could get rid of the descSize parameter, if we simply terminated the
// list of game descriptions by an all-zero entry (like the SCUMM engine does in
// similar cases).
DetectedGameList real_ADVANCED_DETECTOR_DETECT_GAMES_FUNCTION(
	const FSList &fslist,
	const byte *descs,
	const int descItemSize,
	const int md5Bytes,
	const PlainGameDescriptor *list
	);


// FIXME/TODO: Rename this function to something more sensible.
// Possibly move it inside class AdvancedDetector ?
// Also, we could get rid of the descSize parameter, if we simply terminated the
// list of game descriptions by an all-zero entry (like the SCUMM engine does in
// similar cases).
int real_ADVANCED_DETECTOR_DETECT_INIT_GAME(
	const byte *descs,
	const int descItemSize,
	const int md5Bytes,
	const PlainGameDescriptor *list
	);

// FIXME/TODO: Rename this function to something more sensible.
// Possibly move it inside class AdvancedDetector ?
PluginError real_ADVANCED_DETECTOR_ENGINE_CREATE(
	DetectedGameList (*detectFunc)(const FSList &fslist),
	const Common::ADObsoleteGameID *obsoleteList
	);


#define ADVANCED_DETECTOR_GAMEID_LIST(engine,list) \
	GameList Engine_##engine##_gameIDList() { \
		return Common::real_ADVANCED_DETECTOR_GAMEID_LIST(list); \
	} \
	void dummyFuncToAllowTrailingSemicolon()

#define ADVANCED_DETECTOR_FIND_GAMEID(engine,list,obsoleteList) \
	GameDescriptor Engine_##engine##_findGameID(const char *gameid) { \
		return Common::real_ADVANCED_DETECTOR_FIND_GAMEID(gameid,list,obsoleteList); \
	} \
	void dummyFuncToAllowTrailingSemicolon()

#define ADVANCED_DETECTOR_DETECT_GAMES(engine,detectFunc) \
	DetectedGameList Engine_##engine##_detectGames(const FSList &fslist) { \
		return detectFunc(fslist);						\
	} \
	void dummyFuncToAllowTrailingSemicolon()

#define ADVANCED_DETECTOR_ENGINE_CREATE(engine,createFunction,detectFunc,obsoleteList) \
	PluginError Engine_##engine##_create(OSystem *syst, Engine **engine) { \
		assert(syst); \
		assert(engine); \
		PluginError err = real_ADVANCED_DETECTOR_ENGINE_CREATE(detectFunc, obsoleteList); \
		if (err == kNoError) \
			*engine = new createFunction(syst); \
		return err; \
	} \
	void dummyFuncToAllowTrailingSemicolon()

#define ADVANCED_DETECTOR_DEFINE_PLUGIN(engine,createFunction,detectFunc,list,obsoleteList) \
	ADVANCED_DETECTOR_GAMEID_LIST(engine, list); \
	ADVANCED_DETECTOR_FIND_GAMEID(engine, list, obsoleteList); \
	ADVANCED_DETECTOR_DETECT_GAMES(engine, detectFunc); \
	ADVANCED_DETECTOR_ENGINE_CREATE(engine, createFunction, detectFunc, obsoleteList)


// TODO/FIXME: Fingolfin asks: Why is AdvancedDetector a class, considering that
// it is only used as follow:
//  1) Create an instance of it on the stack
//  2) invoke registerGameDescriptions and setFileMD5Bytes 
//  3) invoke detectGame *once*
// Obviously, 2) could also be handled by passing more params to detectGame.
// So it seem we could replace this class by a simple advancedDetectGame(...)
// function, w/o a class or instantiating object... ? Or is there a deeper
// reason I miss?
class AdvancedDetector {

public:
	AdvancedDetector();
	~AdvancedDetector() {};


	void registerGameDescriptions(ADGameDescList gameDescriptions) {
		_gameDescriptions = gameDescriptions;
	}

	/**
	 * Specify number of bytes which are used to calculate MD5.
	 * Default value is 0 which means whole file.
	 */
	void setFileMD5Bytes(int bytes) { _fileMD5Bytes = bytes; }

	/**
	 * Detect games in specified directory.
	 * Parameters language and platform are used to pass on values
	 * specified by the user. I.e. this is used to restrict search scope.
	 *
	 * @param fslist	FSList to scan or NULL for scanning all specified
	 *  default directories.
	 * @param language	restrict results to specified language only
	 * @param platform	restrict results to specified platform only
	 * @return	list of indexes to GameDescriptions of matched games
	 */
	ADList detectGame(const FSList *fslist, Language language, Platform platform);

private:
	ADGameDescList _gameDescriptions;

	int _fileMD5Bytes;

	String getDescription(int num) const;
};

}	// End of namespace Common

#endif