Example #1
0
GameList AdvancedMetaEngine::detectGames(const Common::FSList &fslist) const {
    ADGameDescList matches = detectGame(fslist, params, Common::UNK_LANG, Common::kPlatformUnknown, "");
    GameList detectedGames;

    if (cleanupPirated(matches))
        return detectedGames;

    if (matches.empty()) {
        // Use fallback detector if there were no matches by other means
        const ADGameDescription *fallbackDesc = fallbackDetect(fslist);
        if (fallbackDesc != 0) {
            GameDescriptor desc(toGameDescriptor(*fallbackDesc, params.list));
            updateGameDescriptor(desc, fallbackDesc, params);
            detectedGames.push_back(desc);
        }
    } else {
        // Otherwise use the found matches
        for (uint i = 0; i < matches.size(); i++) {
            GameDescriptor desc(toGameDescriptor(*matches[i], params.list));
            updateGameDescriptor(desc, matches[i], params);
            detectedGames.push_back(desc);
        }
    }

    return detectedGames;
}
Example #2
0
GameList QueenMetaEngine::detectGames(const Common::FSList &fslist) const {
	GameList detectedGames;

	// Iterate over all files in the given directory
	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
		if (file->isDirectory()) {
			continue;
		}
		if (file->getName().equalsIgnoreCase("queen.1") || file->getName().equalsIgnoreCase("queen.1c")) {
			Common::File dataFile;
			if (!dataFile.open(*file)) {
				continue;
			}
			Queen::DetectedGameVersion version;
			if (Queen::Resource::detectVersion(&version, &dataFile)) {
				GameDescriptor dg(queenGameDescriptor.gameid, queenGameDescriptor.description, version.language, version.platform);
				if (version.features & Queen::GF_DEMO) {
					dg.updateDesc("Demo");
					dg.setGUIOptions(Common::GUIO_NOSPEECH);
				} else if (version.features & Queen::GF_INTERVIEW) {
					dg.updateDesc("Interview");
					dg.setGUIOptions(Common::GUIO_NOSPEECH);
				} else if (version.features & Queen::GF_FLOPPY) {
					dg.updateDesc("Floppy");
					dg.setGUIOptions(Common::GUIO_NOSPEECH);
				} else if (version.features & Queen::GF_TALKIE) {
					dg.updateDesc("Talkie");
				}
				detectedGames.push_back(dg);
				break;
			}
		}
	}
	return detectedGames;
}
Example #3
0
GameList AdvancedMetaEngine::detectGames(const Common::FSList &fslist) const {
	ADGameDescList matches;
	GameList detectedGames;
	FileMap allFiles;

	if (fslist.empty())
		return detectedGames;

	// Compose a hashmap of all files in fslist.
	composeFileHashMap(allFiles, fslist, (_maxScanDepth == 0 ? 1 : _maxScanDepth));

	// Run the detector on this
	matches = detectGame(fslist.begin()->getParent(), allFiles, Common::UNK_LANG, Common::kPlatformUnknown, "");

	if (matches.empty()) {
		// Use fallback detector if there were no matches by other means
		const ADGameDescription *fallbackDesc = fallbackDetect(allFiles, fslist);
		if (fallbackDesc != 0) {
			GameDescriptor desc(toGameDescriptor(*fallbackDesc, _gameIds));
			updateGameDescriptor(desc, fallbackDesc);
			detectedGames.push_back(desc);
		}
	} else {
		// Otherwise use the found matches
		cleanupPirated(matches);
		for (uint i = 0; i < matches.size(); i++) {
			GameDescriptor desc(toGameDescriptor(*matches[i], _gameIds));
			updateGameDescriptor(desc, matches[i]);
			detectedGames.push_back(desc);
		}
	}

	return detectedGames;
}
Example #4
0
static int findGames(Game *games, int max)
{
  Dir *dirs = new Dir[MAX_DIR];
  int curr_game = 0, curr_dir = 0, num_dirs = 1;
  dirs[0].node = Common::FSNode("");
  while (curr_game < max && curr_dir < num_dirs) {
    strncpy(dirs[curr_dir].name, dirs[curr_dir].node.getPath().c_str(), 252);
    dirs[curr_dir].name[251] = '\0';
    dirs[curr_dir].deficon[0] = '\0';
    Common::FSList files, fslist;
    dirs[curr_dir++].node.getChildren(fslist, Common::FSNode::kListAll);
    for (Common::FSList::const_iterator entry = fslist.begin(); entry != fslist.end();
	 ++entry) {
      if (entry->isDirectory()) {
	if (num_dirs < MAX_DIR && strcasecmp(entry->getDisplayName().c_str(),
					    "install")) {
	  dirs[num_dirs].node = *entry;
	  num_dirs++;
	}
      } else
	if (isIcon(*entry))
	  strcpy(dirs[curr_dir-1].deficon, entry->getDisplayName().c_str());
	else
	  files.push_back(*entry);
    }

    GameList candidates = EngineMan.detectGames(files);

    for (GameList::const_iterator ge = candidates.begin();
	ge != candidates.end(); ++ge)
      if (curr_game < max) {
	strcpy(games[curr_game].filename_base, ge->gameid().c_str());
	strcpy(games[curr_game].dir, dirs[curr_dir-1].name);
	games[curr_game].language = ge->language();
	games[curr_game].platform = ge->platform();
	if (uniqueGame(games[curr_game].filename_base,
		       games[curr_game].dir,
		       games[curr_game].language,
		       games[curr_game].platform, games, curr_game)) {

	  strcpy(games[curr_game].text, ge->description().c_str());
#if 0
	  printf("Registered game <%s> (l:%d p:%d) in <%s> <%s> because of <%s> <*>\n",
		 games[curr_game].text,
		 (int)games[curr_game].language,
		 (int)games[curr_game].platform,
		 games[curr_game].dir, games[curr_game].filename_base,
		 dirs[curr_dir-1].name);
#endif
	  curr_game++;
	}
      }
  }

  for (int i=0; i<curr_game; i++)
    if (!loadIcon(games[i], dirs, num_dirs))
      makeDefIcon(games[i].icon);
  delete[] dirs;
  return curr_game;
}
Example #5
0
GameList Sword2MetaEngine::getSupportedGames() const {
	const Sword2::GameSettings *g = Sword2::sword2_settings;
	GameList games;
	while (g->gameid) {
		games.push_back(GameDescriptor(g->gameid, g->description));
		g++;
	}
	return games;
}
Example #6
0
GameList SwordMetaEngine::getSupportedGames() const {
	GameList games;
	games.push_back(sword1FullSettings);
	games.push_back(sword1DemoSettings);
	games.push_back(sword1MacFullSettings);
	games.push_back(sword1MacDemoSettings);
	games.push_back(sword1PSXSettings);
	games.push_back(sword1PSXDemoSettings);
	return games;
}
Example #7
0
GameList SwordMetaEngine::getSupportedGames() const {
	GameList games;
	games.push_back(GameDescriptor(getEngineID(), sword1FullSettings, GUIO_NOMIDI));
	games.push_back(GameDescriptor(getEngineID(), sword1DemoSettings, GUIO_NOMIDI));
	games.push_back(GameDescriptor(getEngineID(), sword1MacFullSettings, GUIO_NOMIDI));
	games.push_back(GameDescriptor(getEngineID(), sword1MacDemoSettings, GUIO_NOMIDI));
	games.push_back(GameDescriptor(getEngineID(), sword1PSXSettings, GUIO_NOMIDI));
	games.push_back(GameDescriptor(getEngineID(), sword1PSXDemoSettings, GUIO_NOMIDI));
	return games;
}
Example #8
0
GameList Engine_GOB_gameIDList() {
	GameList games;
	const PlainGameDescriptor *g = gob_list;

	while (g->gameid) {
		games.push_back(*g);
		g++;
	}

	return games;
}
Example #9
0
GameList ScummMetaEngine::detectGames(const Common::FSList &fslist) const {
	GameList detectedGames;
	Common::List<DetectorResult> results;

	::detectGames(fslist, results, 0);

	// TODO: We still don't handle the FM-TOWNS demos (like zakloom) very well.
	// In particular, they are detected as ZakTowns, which is bad.

	for (Common::List<DetectorResult>::iterator
	          x = results.begin(); x != results.end(); ++x) {
		const PlainGameDescriptor *g = findPlainGameDescriptor(x->game.gameid, gameDescriptions);
		assert(g);
		GameDescriptor dg(x->game.gameid, g->description, x->language, x->game.platform);

		// Append additional information, if set, to the description.
		dg.updateDesc(x->extra);

		// Compute and set the preferred target name for this game.
		// Based on generateComplexID() in advancedDetector.cpp.
		dg["preferredtarget"] = generatePreferredTarget(*x);

		// HACK: Detect and distinguish the FM-TOWNS demos
		if (x->game.platform == Common::kPlatformFMTowns && (x->game.features & GF_DEMO)) {
			if (x->md5 == "2d388339d6050d8ccaa757b64633954e") {
				// Indy + Loom demo
				dg.description() = "Indiana Jones and the Last Crusade & Loom";
				dg.updateDesc(x->extra);
				dg["preferredtarget"] = "indyloom";
			} else if (x->md5 == "77f5c9cc0986eb729c1a6b4c8823bbae") {
				// Zak + Loom demo
				dg.description() = "Zak McKracken & Loom";
				dg.updateDesc(x->extra);
				dg["preferredtarget"] = "zakloom";
			} else if (x->md5 == "3938ee1aa4433fca9d9308c9891172b1") {
				// Indy + Zak demo
				dg.description() = "Indiana Jones and the Last Crusade & Zak McKracken";
				dg.updateDesc(x->extra);
				dg["preferredtarget"] = "indyzak";
			}
		}

		dg.setGUIOptions(x->game.guioptions | MidiDriver::musicType2GUIO(x->game.midi));
		dg.appendGUIOptions(getGameGUIOptionsDescriptionLanguage(x->language));

		detectedGames.push_back(dg);
	}

	return detectedGames;
}
Example #10
0
GameList SkyMetaEngine::detectGames(const Common::FSList &fslist) const {
	GameList detectedGames;
	bool hasSkyDsk = false;
	bool hasSkyDnr = false;
	int dinnerTableEntries = -1;
	int dataDiskSize = -1;

	// Iterate over all files in the given directory
	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
		if (!file->isDirectory()) {
			const char *fileName = file->getName().c_str();

			if (0 == scumm_stricmp("sky.dsk", fileName)) {
				Common::File dataDisk;
				if (dataDisk.open(*file)) {
					hasSkyDsk = true;
					dataDiskSize = dataDisk.size();
				}
			}

			if (0 == scumm_stricmp("sky.dnr", fileName)) {
				Common::File dinner;
				if (dinner.open(*file)) {
					hasSkyDnr = true;
					dinnerTableEntries = dinner.readUint32LE();
				}
			}
		}
	}

	if (hasSkyDsk && hasSkyDnr) {
		// Match found, add to list of candidates, then abort inner loop.
		// The game detector uses US English by default. We want British
		// English to match the recorded voices better.
		GameDescriptor dg("sky", skySetting.gameid, skySetting.description, Common::UNK_LANG, Common::kPlatformUnknown);
		const SkyVersion *sv = skyVersions;
		while (sv->dinnerTableEntries) {
			if (dinnerTableEntries == sv->dinnerTableEntries &&
				(sv->dataDiskSize == dataDiskSize || sv->dataDiskSize == -1)) {
				dg.updateDesc(Common::String::format("v0.0%d %s", sv->version, sv->extraDesc).c_str());
				dg.setGUIOptions(sv->guioptions);
				break;
			}
			++sv;
		}
		detectedGames.push_back(dg);
	}

	return detectedGames;
}
Example #11
0
GameList Sword2MetaEngine::detectGames(const Common::FSList &fslist) const {
	GameList detectedGames;
	const Sword2::GameSettings *g;
	Common::FSList::const_iterator file;

	// TODO: It would be nice if we had code here which distinguishes
	// between the 'sword2' and 'sword2demo' targets. The current code
	// can't do that since they use the same detectname.

	for (g = Sword2::sword2_settings; g->gameid; ++g) {
		// Iterate over all files in the given directory
		for (file = fslist.begin(); file != fslist.end(); ++file) {
			if (!file->isDirectory()) {
				const char *fileName = file->getName().c_str();

				if (0 == scumm_stricmp(g->detectname, fileName)) {
					// Match found, add to list of candidates, then abort inner loop.
					detectedGames.push_back(GameDescriptor(g->gameid, g->description, Common::UNK_LANG, Common::kPlatformUnknown, Common::GUIO_NOMIDI));
					break;
				}
			}
		}
	}


	if (detectedGames.empty()) {
		// Nothing found -- try to recurse into the 'clusters' subdirectory,
		// present e.g. if the user copied the data straight from CD.
		for (file = fslist.begin(); file != fslist.end(); ++file) {
			if (file->isDirectory()) {
				const char *fileName = file->getName().c_str();

				if (0 == scumm_stricmp("clusters", fileName)) {
					Common::FSList recList;
					if (file->getChildren(recList, Common::FSNode::kListAll)) {
						GameList recGames(detectGames(recList));
						if (!recGames.empty()) {
							detectedGames.push_back(recGames);
							break;
						}
					}
				}
			}
		}
	}


	return detectedGames;
}
Example #12
0
/**
 * Returns list of targets supported by the engine.
 * Distinguishes engines with single ID
 */
static GameList gameIDList(const ADParams &params) {
    if (params.singleid != NULL) {
        GameList gl;

        const PlainGameDescriptor *g = params.list;
        while (g->gameid) {
            if (0 == scumm_stricmp(params.singleid, g->gameid)) {
                gl.push_back(GameDescriptor(g->gameid, g->description));

                return gl;
            }
            g++;
        }
        error("Engine %s doesn't have its singleid specified in ids list", params.singleid);
    }

    return GameList(params.list);
}
Example #13
0
GameList AdvancedMetaEngine::getSupportedGames() const {
	if (_singleId != NULL) {
		GameList gl;

		const PlainGameDescriptor *g = _gameIds;
		while (g->gameId) {
			if (0 == scumm_stricmp(_singleId, g->gameId)) {
				gl.push_back(GameDescriptor(g->gameId, g->description));

				return gl;
			}
			g++;
		}
		error("Engine %s doesn't have its singleid specified in ids list", _singleId);
	}

	return GameList(_gameIds);
}
Example #14
0
Common::Error Sword2MetaEngine::createInstance(OSystem *syst, Engine **engine) const {
	assert(syst);
	assert(engine);

	Common::FSList fslist;
	Common::FSNode dir(ConfMan.get("path"));
	if (!dir.getChildren(fslist, Common::FSNode::kListAll)) {
		return Common::kNoGameDataFoundError;
	}

	// Invoke the detector
	Common::String gameid = ConfMan.get("gameid");
	GameList detectedGames = detectGames(fslist);

	for (uint i = 0; i < detectedGames.size(); i++) {
		if (detectedGames[i].gameid() == gameid) {
			*engine = new Sword2::Sword2Engine(syst);
			return Common::kNoError;
		}
	}

	return Common::kNoGameDataFoundError;
}
Example #15
0
GameList SwordMetaEngine::detectGames(const Common::FSList &fslist) const {
	int i, j;
	GameList detectedGames;
	bool filesFound[NUM_FILES_TO_CHECK];
	for (i = 0; i < NUM_FILES_TO_CHECK; i++)
		filesFound[i] = false;

	Sword1CheckDirectory(fslist, filesFound);
	bool mainFilesFound = true;
	bool pcFilesFound = true;
	bool macFilesFound = true;
	bool demoFilesFound = true;
	bool macDemoFilesFound = true;
	bool psxFilesFound = true;
	bool psxDemoFilesFound = true;
	for (i = 0; i < NUM_COMMON_FILES_TO_CHECK; i++)
		if (!filesFound[i])
			mainFilesFound = false;
	for (j = 0; j < NUM_PC_FILES_TO_CHECK; i++, j++)
		if (!filesFound[i])
			pcFilesFound = false;
	for (j = 0; j < NUM_MAC_FILES_TO_CHECK; i++, j++)
		if (!filesFound[i])
			macFilesFound = false;
	for (j = 0; j < NUM_DEMO_FILES_TO_CHECK; i++, j++)
		if (!filesFound[i])
			demoFilesFound = false;
	for (j = 0; j < NUM_DEMO_FILES_TO_CHECK; i++, j++)
		if (!filesFound[i])
			macDemoFilesFound = false;
	for (j = 0; j < NUM_PSX_FILES_TO_CHECK; i++, j++)
		if (!filesFound[i])
			psxFilesFound = false;
	for (j = 0; j < NUM_PSX_DEMO_FILES_TO_CHECK; i++, j++)
		if (!filesFound[i] || psxFilesFound)
			psxDemoFilesFound = false;

	if (mainFilesFound && pcFilesFound && demoFilesFound)
		detectedGames.push_back(GameDescriptor(getEngineID(), sword1DemoSettings, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)));
	else if (mainFilesFound && pcFilesFound && psxFilesFound)
		detectedGames.push_back(GameDescriptor(getEngineID(), sword1PSXSettings, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)));
	else if (mainFilesFound && pcFilesFound && psxDemoFilesFound)
		detectedGames.push_back(GameDescriptor(getEngineID(), sword1PSXDemoSettings, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)));
	else if (mainFilesFound && pcFilesFound && !psxFilesFound)
		detectedGames.push_back(GameDescriptor(getEngineID(), sword1FullSettings, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)));
	else if (mainFilesFound && macFilesFound)
		detectedGames.push_back(GameDescriptor(getEngineID(), sword1MacFullSettings, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)));
	else if (mainFilesFound && macDemoFilesFound)
		detectedGames.push_back(GameDescriptor(getEngineID(), sword1MacDemoSettings, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)));

	return detectedGames;
}
Example #16
0
GameList SkyMetaEngine::getSupportedGames() const {
	GameList games;
	games.push_back(GameDescriptor("sky", skySetting));
	return games;
}
Example #17
0
GameList QueenMetaEngine::getSupportedGames() const {
	GameList games;
	games.push_back(queenGameDescriptor);
	return games;
}
Example #18
0
GameList detectGamesImpl(const Common::FSList &fslist, bool recursion = false) {
	GameList detectedGames;
	const Sword2::GameSettings *g;
	Common::FSList::const_iterator file;
	bool isFullVersion = isFullGame(fslist);

	for (g = Sword2::sword2_settings; g->gameid; ++g) {
		// Iterate over all files in the given directory
		for (file = fslist.begin(); file != fslist.end(); ++file) {
			if (!file->isDirectory()) {
				// The required game data files can be located in the game directory, or in
				// a subdirectory called "clusters". In the latter case, we don't want to
				// detect the game in that subdirectory, as this will detect the game twice
				// when mass add is searching inside a directory. In this case, the first
				// result (the game directory) will be correct, but the second result (the
				// clusters subdirectory) will be wrong, as the optional speech, music and
				// video data files will be ignored. Note that this fix will skip the game
				// data files if the user has placed them inside a "clusters" subdirectory,
				// or if he/she points ScummVM directly to the "clusters" directory of the
				// game CD. Fixes bug #3049336.
				Common::String directory = file->getParent().getName();
				directory.toLowercase();
				if (directory.hasPrefix("clusters") && directory.size() <= 9 && !recursion)
					continue;

				if (file->getName().equalsIgnoreCase(g->detectname)) {
					// Make sure that the sword2 demo is not mixed up with the
					// full version, since they use the same filename for detection
					if ((g->features == Sword2::GF_DEMO && isFullVersion) ||
						(g->features == 0 && !isFullVersion))
						continue;

					// Match found, add to list of candidates, then abort inner loop.
					detectedGames.push_back(GameDescriptor(g->gameid, g->description, Common::UNK_LANG, Common::kPlatformUnknown, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)));
					break;
				}
			}
		}
	}


	if (detectedGames.empty()) {
		// Nothing found -- try to recurse into the 'clusters' subdirectory,
		// present e.g. if the user copied the data straight from CD.
		for (file = fslist.begin(); file != fslist.end(); ++file) {
			if (file->isDirectory()) {
				if (file->getName().equalsIgnoreCase("clusters")) {
					Common::FSList recList;
					if (file->getChildren(recList, Common::FSNode::kListAll)) {
						GameList recGames(detectGamesImpl(recList, true));
						if (!recGames.empty()) {
							detectedGames.push_back(recGames);
							break;
						}
					}
				}
			}
		}
	}


	return detectedGames;
}
Example #19
0
GameList Engine_SWORD1_gameIDList() {
	GameList games;
	games.push_back(sword1FullSettings);
	games.push_back(sword1DemoSettings);
	return games;
}
Example #20
0
GameList SkyMetaEngine::getSupportedGames() const {
	GameList games;
	games.push_back(skySetting);
	return games;
}