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  * Additional copyright for this file:
8  * Copyright (C) 1994-1998 Revolution Software Ltd.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23  */
24 
25 #ifndef SWORD2_DETECTION_INTERNAL_H
26 #define SWORD2_DETECTION_INTERNAL_H
27 
28 #include "engines/metaengine.h"
29 #include "common/gui_options.h"
30 #include "sword2/detection.h"
31 
32 /**
33  * The contents of this file are helpful in detecting games,
34  * as well as helping to create an instance of the game.
35  */
36 namespace Sword2 {
37 
38 struct GameSettings {
39 	const char *gameid;
40 	const char *description;
41 	uint32 features;
42 	const char *detectname;
43 };
44 
45 static const GameSettings sword2_settings[] = {
46 	/* Broken Sword II */
47 	{"sword2", "Broken Sword II: The Smoking Mirror", 0, "players.clu" },
48 	{"sword2alt", "Broken Sword II: The Smoking Mirror (alt)", 0, "r2ctlns.ocx" },
49 	{"sword2psx", "Broken Sword II: The Smoking Mirror (PlayStation)", 0, "screens.clu"},
50 	{"sword2psxdemo", "Broken Sword II: The Smoking Mirror (PlayStation/Demo)", Sword2::GF_DEMO, "screens.clu"},
51 	{"sword2demo", "Broken Sword II: The Smoking Mirror (Demo)", Sword2::GF_DEMO, "players.clu" },
52 	{"sword2demo-es", "Broken Sword II: The Smoking Mirror (Spanish/Demo)", Sword2::GF_DEMO | Sword2::GF_SPANISHDEMO, "vielogo.tga" },
53 	{NULL, NULL, 0, NULL}
54 };
55 
56 } // End of namespace Sword2
57 
isFullGame(const Common::FSList & fslist)58 static bool isFullGame(const Common::FSList &fslist) {
59 	Common::FSList::const_iterator file;
60 
61 	// We distinguish between the two versions by the presence of paris.clu
62 	for (file = fslist.begin(); file != fslist.end(); ++file) {
63 		if (!file->isDirectory()) {
64 			if (file->getName().equalsIgnoreCase("paris.clu"))
65 				return true;
66 		}
67 	}
68 
69 	return false;
70 }
71 
72 static DetectedGames detectGamesImpl(const Common::FSList &fslist, bool recursion = false) {
73 	DetectedGames detectedGames;
74 	const Sword2::GameSettings *g;
75 	Common::FSList::const_iterator file;
76 	bool isFullVersion = isFullGame(fslist);
77 
78 	for (g = Sword2::sword2_settings; g->gameid; ++g) {
79 		// Iterate over all files in the given directory
80 		for (file = fslist.begin(); file != fslist.end(); ++file) {
81 			if (file->isDirectory()) continue;
82 
83 			if (file->getName().equalsIgnoreCase(g->detectname)) {
84 				// Make sure that the sword2 demo is not mixed up with the
85 				// full version, since they use the same filename for detection
86 				if ((g->features == Sword2::GF_DEMO && isFullVersion) ||
87 					(g->features == 0 && !isFullVersion))
88 					continue;
89 
90 				// Match found, add to list of candidates, then abort inner loop.
91 				DetectedGame game = DetectedGame("sword2", g->gameid, g->description);
92 				game.setGUIOptions(GUIO2(GUIO_NOMIDI, GUIO_NOASPECT));
93 
94 				detectedGames.push_back(game);
95 				break;
96 			}
97 		}
98 	}
99 
100 
101 	if (detectedGames.empty() && !recursion) {
102 		// Nothing found -- try to recurse into the 'clusters' subdirectory,
103 		// present e.g. if the user copied the data straight from CD.
104 		for (file = fslist.begin(); file != fslist.end(); ++file) {
105 			if (file->isDirectory()) {
106 				if (file->getName().equalsIgnoreCase("clusters")) {
107 					Common::FSList recList;
108 					if (file->getChildren(recList, Common::FSNode::kListAll)) {
109 						DetectedGames recGames = detectGamesImpl(recList, true);
110 						if (!recGames.empty()) {
111 							detectedGames.push_back(recGames);
112 							break;
113 						}
114 					}
115 				}
116 			}
117 		}
118 	}
119 
120 
121 	return detectedGames;
122 }
123 
124 #endif // SWORD2_DETECTION_INTERNAL_H
125