ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

game.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "engines/game.h"
00024 #include "common/gui_options.h"
00025 #include "common/translation.h"
00026 
00027 
00028 const PlainGameDescriptor *findPlainGameDescriptor(const char *gameid, const PlainGameDescriptor *list) {
00029     const PlainGameDescriptor *g = list;
00030     while (g->gameId) {
00031         if (0 == scumm_stricmp(gameid, g->gameId))
00032             return g;
00033         g++;
00034     }
00035     return 0;
00036 }
00037 
00038 PlainGameDescriptor PlainGameDescriptor::empty() {
00039     PlainGameDescriptor pgd;
00040     pgd.gameId = nullptr;
00041     pgd.description = nullptr;
00042     return pgd;
00043 }
00044 
00045 PlainGameDescriptor PlainGameDescriptor::of(const char *gameId, const char *description) {
00046     PlainGameDescriptor pgd;
00047     pgd.gameId = gameId;
00048     pgd.description = description;
00049     return pgd;
00050 }
00051 
00052 QualifiedGameDescriptor::QualifiedGameDescriptor() :
00053         PlainGameDescriptor() {
00054     engineId    = nullptr;
00055     gameId      = nullptr;
00056     description = nullptr;
00057 }
00058 
00059 QualifiedGameDescriptor::QualifiedGameDescriptor(const char *engine, const PlainGameDescriptor &pgd) :
00060         PlainGameDescriptor() {
00061     engineId    = engine;
00062     gameId      = pgd.gameId;
00063     description = pgd.description;
00064 }
00065 
00066 DetectedGame::DetectedGame() :
00067         hasUnknownFiles(false),
00068         canBeAdded(true),
00069         language(Common::UNK_LANG),
00070         platform(Common::kPlatformUnknown),
00071         gameSupportLevel(kStableGame) {
00072 }
00073 
00074 DetectedGame::DetectedGame(const Common::String &engine, const PlainGameDescriptor &pgd) :
00075         engineId(engine),
00076         hasUnknownFiles(false),
00077         canBeAdded(true),
00078         language(Common::UNK_LANG),
00079         platform(Common::kPlatformUnknown),
00080         gameSupportLevel(kStableGame) {
00081 
00082     gameId = pgd.gameId;
00083     preferredTarget = pgd.gameId;
00084     description = pgd.description;
00085 }
00086 
00087 DetectedGame::DetectedGame(const Common::String &engine, const Common::String &id, const Common::String &d, Common::Language l, Common::Platform p, const Common::String &ex) :
00088         engineId(engine),
00089         hasUnknownFiles(false),
00090         canBeAdded(true),
00091         gameSupportLevel(kStableGame) {
00092 
00093     gameId = id;
00094     preferredTarget = id;
00095     description = d;
00096     language = l;
00097     platform = p;
00098     extra = ex;
00099 
00100     // Append additional information, if set, to the description.
00101     description += updateDesc();
00102 }
00103 
00104 void DetectedGame::setGUIOptions(const Common::String &guioptions) {
00105     _guiOptions = Common::getGameGUIOptionsDescription(guioptions);
00106 }
00107 
00108 void DetectedGame::appendGUIOptions(const Common::String &str) {
00109     if (!_guiOptions.empty())
00110         _guiOptions += " ";
00111 
00112     _guiOptions += str;
00113 }
00114 
00115 Common::String DetectedGame::updateDesc() const {
00116     const bool hasCustomLanguage = (language != Common::UNK_LANG);
00117     const bool hasCustomPlatform = (platform != Common::kPlatformUnknown);
00118     const bool hasExtraDesc = !extra.empty();
00119 
00120     // Adapt the description string if custom platform/language is set.
00121     Common::String descr;
00122     if (!hasCustomLanguage && !hasCustomPlatform && !hasExtraDesc)
00123         return descr;
00124 
00125     descr += " (";
00126 
00127     if (hasExtraDesc)
00128         descr += extra;
00129     if (hasCustomPlatform) {
00130         if (hasExtraDesc)
00131             descr += "/";
00132         descr += Common::getPlatformDescription(platform);
00133     }
00134     if (hasCustomLanguage) {
00135         if (hasExtraDesc || hasCustomPlatform)
00136             descr += "/";
00137         descr += Common::getLanguageDescription(language);
00138     }
00139 
00140     descr += ")";
00141 
00142     return descr;
00143 }
00144 
00145 DetectionResults::DetectionResults(const DetectedGames &detectedGames) :
00146         _detectedGames(detectedGames) {
00147 }
00148 
00149 bool DetectionResults::foundUnknownGames() const {
00150     for (uint i = 0; i < _detectedGames.size(); i++) {
00151         if (_detectedGames[i].hasUnknownFiles) {
00152             return true;
00153         }
00154     }
00155     return false;
00156 }
00157 
00158 DetectedGames DetectionResults::listRecognizedGames() const {
00159     DetectedGames candidates;
00160     for (uint i = 0; i < _detectedGames.size(); i++) {
00161         if (_detectedGames[i].canBeAdded) {
00162             candidates.push_back(_detectedGames[i]);
00163         }
00164     }
00165     return candidates;
00166 }
00167 
00168 DetectedGames DetectionResults::listDetectedGames() const {
00169     return _detectedGames;
00170 }
00171 
00172 Common::String DetectionResults::generateUnknownGameReport(bool translate, uint32 wordwrapAt) const {
00173     return ::generateUnknownGameReport(_detectedGames, translate, false, wordwrapAt);
00174 }
00175 
00176 Common::String generateUnknownGameReport(const DetectedGames &detectedGames, bool translate, bool fullPath, uint32 wordwrapAt) {
00177     assert(!detectedGames.empty());
00178 
00179     const char *reportStart = _s("The game in '%s' seems to be an unknown game variant.\n\n"
00180                                  "Please report the following data to the ResidualVM team at %s "
00181                                  "along with the name of the game you tried to add and "
00182                                  "its version, language, etc.:");
00183     const char *reportEngineHeader = _s("Matched game IDs for the %s engine:");
00184 
00185     Common::String report = Common::String::format(
00186             translate ? _(reportStart) : reportStart,
00187             fullPath ? detectedGames[0].path.c_str() : detectedGames[0].shortPath.c_str(),
00188             "https://github.com/residualvm/residualvm/issues"
00189     );
00190     report += "\n";
00191 
00192     FilePropertiesMap matchedFiles;
00193 
00194     Common::String currentEngineId;
00195     for (uint i = 0; i < detectedGames.size(); i++) {
00196         const DetectedGame &game = detectedGames[i];
00197 
00198         if (!game.hasUnknownFiles) continue;
00199 
00200         if (currentEngineId.empty() || currentEngineId != game.engineId) {
00201             currentEngineId = game.engineId;
00202 
00203             // If the engine is not the same as for the previous entry, print an engine line header
00204             report += "\n";
00205             report += Common::String::format(
00206                     translate ? _(reportEngineHeader) : reportEngineHeader,
00207                     game.engineId.c_str()
00208             );
00209             report += " ";
00210 
00211         } else {
00212             report += ", ";
00213         }
00214 
00215         // Add the gameId to the list of matched games for the engine
00216         // TODO: Use the gameId here instead of the preferred target.
00217         // This is currently impossible due to the AD singleId feature losing the information.
00218         report += game.preferredTarget;
00219 
00220         // Consolidate matched files across all engines and detection entries
00221         for (FilePropertiesMap::const_iterator it = game.matchedFiles.begin(); it != game.matchedFiles.end(); it++) {
00222             matchedFiles.setVal(it->_key, it->_value);
00223         }
00224     }
00225 
00226     if (wordwrapAt) {
00227         report.wordWrap(wordwrapAt);
00228     }
00229 
00230     report += "\n\n";
00231 
00232     for (FilePropertiesMap::const_iterator file = matchedFiles.begin(); file != matchedFiles.end(); ++file)
00233         report += Common::String::format("  {\"%s\", 0, \"%s\", %d},\n", file->_key.c_str(), file->_value.md5.c_str(), file->_value.size);
00234 
00235     report += "\n";
00236 
00237     return report;
00238 }
00239 
00240 Common::String generateUnknownGameReport(const DetectedGame &detectedGame, bool translate, bool fullPath, uint32 wordwrapAt) {
00241     DetectedGames detectedGames;
00242     detectedGames.push_back(detectedGame);
00243 
00244     return generateUnknownGameReport(detectedGames, translate, fullPath, wordwrapAt);
00245 }


Generated on Sat Dec 14 2019 05:00:34 for ResidualVM by doxygen 1.7.1
curved edge   curved edge