aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base/plugins.cpp1
-rw-r--r--engines/game.cpp35
-rw-r--r--engines/game.h32
-rw-r--r--gui/launcher.cpp30
-rw-r--r--gui/unknown-game-dialog.cpp71
-rw-r--r--gui/unknown-game-dialog.h15
6 files changed, 109 insertions, 75 deletions
diff --git a/base/plugins.cpp b/base/plugins.cpp
index 55c99b1eda..ac217ab960 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -553,6 +553,7 @@ DetectionResults EngineManager::detectGames(const Common::FSList &fslist) const
for (uint i = 0; i < engineCandidates.size(); i++) {
engineCandidates[i].engineName = metaEngine.getName();
engineCandidates[i].path = fslist.begin()->getParent().getPath();
+ engineCandidates[i].shortPath = fslist.begin()->getParent().getDisplayName();
candidates.push_back(engineCandidates[i]);
}
diff --git a/engines/game.cpp b/engines/game.cpp
index bb5f4ae6cb..24e125825f 100644
--- a/engines/game.cpp
+++ b/engines/game.cpp
@@ -152,8 +152,16 @@ DetectedGames DetectionResults::listRecognizedGames() const {
return candidates;
}
+DetectedGames DetectionResults::listDetectedGames() const {
+ return _detectedGames;
+}
+
Common::String DetectionResults::generateUnknownGameReport(bool translate, uint32 wordwrapAt) const {
- assert(!_detectedGames.empty());
+ return ::generateUnknownGameReport(_detectedGames, translate, false, wordwrapAt);
+}
+
+Common::String generateUnknownGameReport(const DetectedGames &detectedGames, bool translate, bool fullPath, uint32 wordwrapAt) {
+ assert(!detectedGames.empty());
const char *reportStart = _s("The game in '%s' seems to be an unknown game variant.\n\n"
"Please report the following data to the ScummVM team at %s "
@@ -162,7 +170,8 @@ Common::String DetectionResults::generateUnknownGameReport(bool translate, uint3
const char *reportEngineHeader = _s("Matched game IDs for the %s engine:");
Common::String report = Common::String::format(
- translate ? _(reportStart) : reportStart, _detectedGames[0].path.c_str(),
+ translate ? _(reportStart) : reportStart,
+ fullPath ? detectedGames[0].path.c_str() : detectedGames[0].shortPath.c_str(),
"https://bugs.scummvm.org/"
);
report += "\n";
@@ -170,8 +179,8 @@ Common::String DetectionResults::generateUnknownGameReport(bool translate, uint3
FilePropertiesMap matchedFiles;
const char *currentEngineName = nullptr;
- for (uint i = 0; i < _detectedGames.size(); i++) {
- const DetectedGame &game = _detectedGames[i];
+ for (uint i = 0; i < detectedGames.size(); i++) {
+ const DetectedGame &game = detectedGames[i];
if (!game.hasUnknownFiles) continue;
@@ -215,17 +224,9 @@ Common::String DetectionResults::generateUnknownGameReport(bool translate, uint3
return report;
}
-Common::StringArray DetectionResults::getUnknownGameEngines() const {
- Common::StringArray engines;
- const char *currentEngineName = nullptr;
- for (uint i = 0; i < _detectedGames.size(); i++) {
- const DetectedGame &game = _detectedGames[i];
- if (!game.hasUnknownFiles)
- continue;
- if (!currentEngineName || strcmp(currentEngineName, game.engineName) != 0) {
- currentEngineName = game.engineName;
- engines.push_back(Common::String(currentEngineName));
- }
- }
- return engines;
+Common::String generateUnknownGameReport(const DetectedGame &detectedGame, bool translate, bool fullPath, uint32 wordwrapAt) {
+ DetectedGames detectedGames;
+ detectedGames.push_back(detectedGame);
+
+ return generateUnknownGameReport(detectedGames, translate, fullPath, wordwrapAt);
}
diff --git a/engines/game.h b/engines/game.h
index fcaae62e5c..8a678cfd2c 100644
--- a/engines/game.h
+++ b/engines/game.h
@@ -142,6 +142,7 @@ struct DetectedGame {
Common::Language language;
Common::Platform platform;
Common::String path;
+ Common::String shortPath;
Common::String extra;
/**
@@ -202,6 +203,14 @@ public:
DetectedGames listRecognizedGames() const;
/**
+ * List all the games that were detected
+ *
+ * That includes entries that don't have enough information to be added to the
+ * configuration manager.
+ */
+ DetectedGames listDetectedGames() const;
+
+ /**
* Were unknown game variants found by the engines?
*
* When unknown game variants are found, an unknown game report can be generated.
@@ -209,21 +218,26 @@ public:
bool foundUnknownGames() const;
/**
- * Generate a report that we found an unknown game variant, together with the file
- * names, sizes and MD5 sums.
+ * Generate a report that we found an unknown game variant.
*
- * @param translate translate the report to the currently active GUI language
- * @param wordwrapAt word wrap the text part of the report after a number of characters
+ * @see ::generateUnknownGameReport
*/
Common::String generateUnknownGameReport(bool translate, uint32 wordwrapAt = 0) const;
- /**
- * Get the list of engines for which an unknown game variant was found.
- */
- Common::StringArray getUnknownGameEngines() const;
-
private:
DetectedGames _detectedGames;
};
+/**
+ * Generate a report that we found an unknown game variant, together with the file
+ * names, sizes and MD5 sums.
+ *
+ * @param translate translate the report to the currently active GUI language
+ * @param fullPath include the full path where the files are located, otherwise only the name
+ * of last component of the path is included
+ * @param wordwrapAt word wrap the text part of the report after a number of characters
+ */
+Common::String generateUnknownGameReport(const DetectedGames &detectedGames, bool translate, bool fullPath, uint32 wordwrapAt = 0);
+Common::String generateUnknownGameReport(const DetectedGame &detectedGame, bool translate, bool fullPath, uint32 wordwrapAt = 0);
+
#endif
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index 14e0e96a3b..b09f650fc9 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -563,12 +563,9 @@ bool LauncherDialog::doGameDetection(const Common::String &path) {
if (detectionResults.foundUnknownGames()) {
Common::String report = detectionResults.generateUnknownGameReport(false, 80);
g_system->logMessage(LogMessageType::kInfo, report.c_str());
-
- UnknownGameDialog dialog(detectionResults);
- dialog.runModal();
}
- Common::Array<DetectedGame> candidates = detectionResults.listRecognizedGames();
+ Common::Array<DetectedGame> candidates = detectionResults.listDetectedGames();
int idx;
if (candidates.empty()) {
@@ -583,16 +580,37 @@ bool LauncherDialog::doGameDetection(const Common::String &path) {
} else {
// Display the candidates to the user and let her/him pick one
StringArray list;
- for (idx = 0; idx < (int)candidates.size(); idx++)
- list.push_back(candidates[idx].description);
+ for (idx = 0; idx < (int)candidates.size(); idx++) {
+ Common::String description = candidates[idx].description;
+
+ if (candidates[idx].hasUnknownFiles) {
+ description += " - ";
+ description += _("Unknown variant");
+ }
+
+ list.push_back(description);
+ }
ChooserDialog dialog(_("Pick the game:"));
dialog.setList(list);
idx = dialog.runModal();
}
+
if (0 <= idx && idx < (int)candidates.size()) {
const DetectedGame &result = candidates[idx];
+ if (result.hasUnknownFiles) {
+ UnknownGameDialog dialog(result);
+
+ bool cancel = dialog.runModal() == -1;
+ if (cancel) {
+ idx = -1;
+ }
+ }
+ }
+
+ if (0 <= idx && idx < (int)candidates.size()) {
+ const DetectedGame &result = candidates[idx];
Common::String domain = EngineMan.createTargetForGame(result);
// Display edit dialog for the new entry
diff --git a/gui/unknown-game-dialog.cpp b/gui/unknown-game-dialog.cpp
index d96791742e..0aa8cc5750 100644
--- a/gui/unknown-game-dialog.cpp
+++ b/gui/unknown-game-dialog.cpp
@@ -38,14 +38,21 @@ enum {
kCopyToClipboard = 'cpcl',
kOpenBugtrackerURL = 'ourl',
kClose = 'clse',
+ kAddAnyway = 'adda',
kScrollContainerReflow = 'SCRf'
};
-UnknownGameDialog::UnknownGameDialog(const DetectionResults &detectionResults) :
+UnknownGameDialog::UnknownGameDialog(const DetectedGame &detectedGame) :
Dialog(30, 20, 260, 124),
- _detectionResults(detectionResults) {
+ _detectedGame(detectedGame) {
// For now place the buttons with a default place and size. They will be resized and moved when rebuild() is called.
- _closeButton = new ButtonWidget(this, 0, 0, 0, 0, _("Close"), 0, kClose);
+ _closeButton = new ButtonWidget(this, 0, 0, 0, 0, detectedGame.canBeAdded ? _("Cancel") : _("Close"), 0, kClose);
+
+ if (detectedGame.canBeAdded) {
+ _addAnywayButton = new ButtonWidget(this, 0, 0, 0, 0, _("Add anyway"), 0, kAddAnyway);
+ } else {
+ _addAnywayButton = nullptr;
+ }
//Check if we have clipboard functionality
if (g_system->hasFeature(OSystem::kFeatureClipboardSupport)) {
@@ -76,6 +83,8 @@ void UnknownGameDialog::reflowLayout() {
}
void UnknownGameDialog::rebuild() {
+ // TODO: Use a theme layout dialog definition
+
// First remove the old text widgets
for (uint i = 0; i < _textWidgets.size() ; i++) {
_textContainer->removeWidget(_textWidgets[i]);
@@ -91,7 +100,7 @@ void UnknownGameDialog::rebuild() {
int buttonHeight = g_gui.xmlEval()->getVar("Globals.Button.Height", 0);
int buttonWidth = g_gui.xmlEval()->getVar("Globals.Button.Width", 0);
- Common::String reportTranslated = _detectionResults.generateUnknownGameReport(true);
+ Common::String reportTranslated = generateUnknownGameReport(_detectedGame, true, true);
// Check if we have clipboard functionality and expand the reportTranslated message if needed...
if (g_system->hasFeature(OSystem::kFeatureClipboardSupport)) {
@@ -116,7 +125,9 @@ void UnknownGameDialog::rebuild() {
_h = MIN(screenH - 20, lineCount * kLineHeight + kLineHeight + buttonHeight + 24);
int closeButtonWidth = MAX(buttonWidth, g_gui.getFont().getStringWidth(_closeButton->getLabel()) + 10);
- int copyToClipboardButtonWidth = 0, openBugtrackerURLButtonWidth = 0, totalButtonWidth = closeButtonWidth;
+ int copyToClipboardButtonWidth = 0, openBugtrackerURLButtonWidth = 0, addAnywayButtonWidth = 0;
+ int totalButtonWidth = closeButtonWidth;
+
if (_copyToClipboardButton) {
copyToClipboardButtonWidth = MAX(buttonWidth, g_gui.getFont().getStringWidth(_copyToClipboardButton->getLabel()) + 10);
totalButtonWidth += copyToClipboardButtonWidth + 10;
@@ -125,6 +136,10 @@ void UnknownGameDialog::rebuild() {
openBugtrackerURLButtonWidth = MAX(buttonWidth, g_gui.getFont().getStringWidth(_openBugTrackerUrlButton->getLabel()) + 10);
totalButtonWidth += openBugtrackerURLButtonWidth + 10;
}
+ if (_addAnywayButton) {
+ addAnywayButtonWidth = MAX(buttonWidth, g_gui.getFont().getStringWidth(_addAnywayButton->getLabel()) + 10);
+ totalButtonWidth += addAnywayButtonWidth + 10;
+ }
_w = MAX(MAX(maxlineWidth, 0) + 16 + scrollbarWidth, totalButtonWidth) + 20;
@@ -133,7 +148,12 @@ void UnknownGameDialog::rebuild() {
_y = (g_system->getOverlayHeight() - _h) / 2;
// Now move the buttons and text container to their proper place
- int buttonPos = _w - closeButtonWidth - 10;
+ int buttonPos = _w - 10;
+ if (_addAnywayButton) {
+ buttonPos -= addAnywayButtonWidth + 5;
+ _addAnywayButton->resize(buttonPos, _h - buttonHeight - 8, addAnywayButtonWidth, buttonHeight);
+ }
+ buttonPos -= closeButtonWidth + 5;
_closeButton->resize(buttonPos, _h - buttonHeight - 8, closeButtonWidth, buttonHeight);
if (_copyToClipboardButton) {
buttonPos -= copyToClipboardButtonWidth + 5;
@@ -156,7 +176,7 @@ void UnknownGameDialog::rebuild() {
}
}
-Common::String UnknownGameDialog::encodeUrlString(const Common::String& string) {
+Common::String UnknownGameDialog::encodeUrlString(const Common::String &string) {
Common::String encoded;
for (uint i = 0 ; i < string.size() ; ++i) {
char c = string[i];
@@ -170,34 +190,10 @@ Common::String UnknownGameDialog::encodeUrlString(const Common::String& string)
}
Common::String UnknownGameDialog::generateBugtrackerURL() {
- Common::String report = _detectionResults.generateUnknownGameReport(false);
- // Remove the filesystem path from the bugtracker report.
- // The path is on the first line between single quotes. We strip everything except the last level.
- int path_start = -1, path_size = 0;
- for (uint i = 0 ; i < report.size() ; ++i) {
- char c = report[i];
- if (c == '\'') {
- if (path_start == -1)
- path_start = i + 1;
- else
- break;
- } else if (path_start != -1 && (c == '/' || c == '\\')) {
- path_size = 1 + i - path_start;
- } else if (c == '\n') {
- path_size = 0;
- break;
- }
- }
- if (path_size > 0)
- report.erase(path_start, path_size);
+ Common::String report = generateUnknownGameReport(_detectedGame, false, false);
report = encodeUrlString(report);
- // Pass engine name if there is only one.
- Common::String engineName = "unknown";
- Common::StringArray engines = _detectionResults.getUnknownGameEngines();
- if (engines.size() == 1)
- engineName = engines.front();
- engineName = encodeUrlString(engineName);
+ Common::String engineName = encodeUrlString(_detectedGame.engineName);
return Common::String::format(
"https://www.scummvm.org/unknowngame?"
@@ -210,8 +206,7 @@ Common::String UnknownGameDialog::generateBugtrackerURL() {
void UnknownGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
switch(cmd) {
case kCopyToClipboard: {
- // TODO: Remove the filesystem path from the report
- Common::String report = _detectionResults.generateUnknownGameReport(false);
+ Common::String report = generateUnknownGameReport(_detectedGame, false, false);
if (g_system->setTextInClipboard(report)) {
g_system->displayMessageOnOSD(
@@ -222,8 +217,12 @@ void UnknownGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32
break;
}
case kClose:
+ // The user cancelled adding the game
+ setResult(-1);
+ close();
+ break;
+ case kAddAnyway:
// When the detection entry comes from the fallback detector, the game can be added / launched anyways.
- // TODO: Add a button to cancel adding the game. And make it clear that launching the game may not work properly.
close();
break;
case kOpenBugtrackerURL:
diff --git a/gui/unknown-game-dialog.h b/gui/unknown-game-dialog.h
index 30ac13cc84..24e4179bf4 100644
--- a/gui/unknown-game-dialog.h
+++ b/gui/unknown-game-dialog.h
@@ -35,9 +35,9 @@ class ButtonWidget;
class UnknownGameDialog : public Dialog {
public:
- UnknownGameDialog(const DetectionResults &detectionResults);
+ UnknownGameDialog(const DetectedGame &detectedGame);
- void handleMouseWheel(int x, int y, int direction);
+ void handleMouseWheel(int x, int y, int direction) override;
private:
void rebuild();
@@ -46,14 +46,15 @@ private:
void reflowLayout() override;
Common::String generateBugtrackerURL();
- Common::String encodeUrlString(const Common::String&);
+ static Common::String encodeUrlString(const Common::String &string);
- const DetectionResults &_detectionResults;
+ const DetectedGame &_detectedGame;
ScrollContainerWidget *_textContainer;
Common::Array<StaticTextWidget *> _textWidgets;
- ButtonWidget* _openBugTrackerUrlButton;
- ButtonWidget* _copyToClipboardButton;
- ButtonWidget* _closeButton;
+ ButtonWidget *_openBugTrackerUrlButton;
+ ButtonWidget *_copyToClipboardButton;
+ ButtonWidget *_closeButton;
+ ButtonWidget *_addAnywayButton;
};
} // End of namespace GUI