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