[Scummvm-git-logs] scummvm master -> fb4ed4eaa351f6a487a2de7b44f92b58efdb2c46

sev- noreply at scummvm.org
Thu Jun 13 23:22:13 UTC 2024


This automated email contains information about 32 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
65e7f23ae8 GUI: Implement checksum calculation for game files
d529ca5966 GUI: Fix filesize while calculating checksums
60e44c3590 GUI: Update integrity JSON to use relative paths
57f36e185b GUI: Create IntegrityDialog class
5e173beaad GUI: Create 'Check Integrity' button
31ffefa93d GUI: Check Integrity button now sends JSON request
d9c545bb9d GUI: Fix JSON connection
71121e18ec GUI: Add Checkintegrity button to GameOptions_Path
c8a2fc28ea GUI: Update Checkintegrity button, endpoint
2d3db55e21 GUI: Add percentage bar for checksum calculation
e9622b15ae GUI: Add parseJSON() to IntegrityDialog
1c423d5c06 GUI: Add dialog for calculation progress, results
70eb3d654f GUI: Update integrity dialog message text
f7919980d5 GUI: Update file validation endpoint
a1213ecb46 GUI: Calculate checksums of mac files correctly
479ae47af1 GUI: Add integrity-dialog.cpp to POTFILES
17e695e8bf GUI: Update translatable and debug strings
b4b86bad7d GUI: Add button to copy email to clipboard
d98e371ad6 GUI: Update integrityDialog to not use pop-ups
54d58463dc GUI: Display results in IntegrityDialog
bb46b4fc44 GUI: Display results in scrollable ListWidget
b039adeb1f GUI: Update email formatting in integrity dialog
6dc1950207 COMMON: Fix percentEncodeString()
d9fb4421f2 GUI: Fix relativePath in integrity JSON request
10211e6a2e GUI: Update identifiers to avoid namespace clashes
18a47da6ce GUI: User filesets dialog can launch email client
2d7559c772 GUI: Calculate checksums of rsrc forks correctly
9b1fb61eee GUI: Percent encode mailto link in IntegrityDialog
8a986d51df GUI: Add no_metadata error code to IntegrityDialog
228b19dafd GUI: Hid integrity checker behind config option
154ba3b43d GUI: Added integrity dialog to all themes and bumped theme version
fb4ed4eaa3 GUI: Regenerated theme files


Commit: 65e7f23ae8b89dd0231f0e66da512a065267724f
    https://github.com/scummvm/scummvm/commit/65e7f23ae8b89dd0231f0e66da512a065267724f
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:41+02:00

Commit Message:
GUI: Implement checksum calculation for game files

Changed paths:
  A gui/integrity-dialog.cpp
  A gui/integrity-dialog.h
    gui/module.mk


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
new file mode 100644
index 00000000000..8d370b8c863
--- /dev/null
+++ b/gui/integrity-dialog.cpp
@@ -0,0 +1,116 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "gui/integrity-dialog.h"
+
+#include "common/array.h"
+#include "common/debug.h"
+#include "common/file.h"
+#include "common/formats/json.h"
+#include "common/md5.h"
+
+namespace GUI {
+
+Common::Array<Common::StringArray> generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums) {
+	const Common::FSNode dir(gamePath);
+
+	if (!dir.exists() || !dir.isDirectory())
+		return {};
+
+	Common::FSList fileList;
+	if (!dir.getChildren(fileList, Common::FSNode::kListAll))
+		return {};
+
+	if (fileList.empty())
+		return {};
+
+	// Process the files and subdirectories in the current directory recursively
+	for (Common::FSList::const_iterator it = fileList.begin(); it != fileList.end(); it++) {
+		const Common::FSNode &entry = *it;
+
+		if (entry.isDirectory())
+			generateChecksums(entry.getPath(), fileChecksums);
+		else {
+			const Common::Path filename(entry.getPath());
+			Common::File file;
+			if (!file.open(entry))
+				continue;
+
+			Common::Array<Common::String> fileChecksum =
+				{filename.toString(), Common::String(file.size())};
+			// Various checksizes
+			for (auto size : {0, 5000, 1024 * 1024}) {
+				fileChecksum.push_back(Common::computeStreamMD5AsString(file, size).c_str());
+			}
+			// Tail checksums with checksize 5000
+			file.seek(-5000, SEEK_END);
+			fileChecksum.push_back(Common::computeStreamMD5AsString(file).c_str());
+
+			fileChecksums.push_back(fileChecksum);
+		}
+	}
+
+	return fileChecksums;
+}
+
+void generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language) {
+	Common::Array<Common::StringArray> fileChecksums = {};
+	fileChecksums = generateChecksums(gamePath, fileChecksums);
+	Common::JSONObject requestObject;
+
+	requestObject.setVal("gameid", new Common::JSONValue(gameid));
+	requestObject.setVal("engineid", new Common::JSONValue(engineid));
+	requestObject.setVal("extra", new Common::JSONValue(extra));
+	requestObject.setVal("platform", new Common::JSONValue(platform));
+	requestObject.setVal("language", new Common::JSONValue(language));
+
+	Common::JSONArray filesObject;
+
+	for (Common::StringArray fileChecksum : fileChecksums) {
+		Common::JSONObject file;
+		file.setVal("name", new Common::JSONValue(fileChecksum[0]));
+		file.setVal("size", new Common::JSONValue(fileChecksum[1]));
+
+		Common::JSONArray checksums;
+		int index = 0;
+		for (Common::String val : fileChecksum) {
+			Common::JSONObject checksum;
+			if (index < 2) {
+				index++;
+				continue;
+			}
+			checksum.setVal("type", new Common::JSONValue("md5"));
+			checksum.setVal("checksum", new Common::JSONValue(val));
+
+			checksums.push_back(new Common::JSONValue(checksum));
+		}
+		file.setVal("checksums", new Common::JSONValue(checksums));
+
+		filesObject.push_back(new Common::JSONValue(file));
+	}
+
+	requestObject.setVal("files", new Common::JSONValue(filesObject));
+
+	Common::JSONValue request(requestObject);
+	debug(request.stringify().c_str());
+}
+
+} // End of namespace GUI
diff --git a/gui/integrity-dialog.h b/gui/integrity-dialog.h
new file mode 100644
index 00000000000..39ec7c7f5bc
--- /dev/null
+++ b/gui/integrity-dialog.h
@@ -0,0 +1,34 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef GUI_INTEGRITY_DIALOG_H
+#define GUI_INTEGRITY_DIALOG_H
+
+#include "common/array.h"
+#include "common/str.h"
+
+namespace GUI {
+
+void generateJSONRequest(Common::String gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language);
+
+} // End of namespace GUI
+
+#endif // GUI_INTEGRITY_DIALOG_H
diff --git a/gui/module.mk b/gui/module.mk
index 09026f5f56e..1a969b8f033 100644
--- a/gui/module.mk
+++ b/gui/module.mk
@@ -9,6 +9,7 @@ MODULE_OBJS := \
 	dialog.o \
 	dump-all-dialogs.o \
 	editgamedialog.o \
+	integrity-dialog.o \
 	error.o \
 	EventRecorder.o \
 	filebrowser-dialog.o \


Commit: d529ca59660ec2d0572f87accbb5574abb366722
    https://github.com/scummvm/scummvm/commit/d529ca59660ec2d0572f87accbb5574abb366722
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:41+02:00

Commit Message:
GUI: Fix filesize while calculating checksums

Changed paths:
    gui/integrity-dialog.cpp


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index 8d370b8c863..f2d8f7bbc62 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -54,16 +54,17 @@ Common::Array<Common::StringArray> generateChecksums(Common::Path gamePath, Comm
 			if (!file.open(entry))
 				continue;
 
-			Common::Array<Common::String> fileChecksum =
-				{filename.toString(), Common::String(file.size())};
+			Common::Array<Common::String> fileChecksum = {filename.toString()};
 			// Various checksizes
 			for (auto size : {0, 5000, 1024 * 1024}) {
 				fileChecksum.push_back(Common::computeStreamMD5AsString(file, size).c_str());
+				file.seek(0);
 			}
 			// Tail checksums with checksize 5000
 			file.seek(-5000, SEEK_END);
 			fileChecksum.push_back(Common::computeStreamMD5AsString(file).c_str());
 
+			file.close();
 			fileChecksums.push_back(fileChecksum);
 		}
 	}
@@ -87,17 +88,29 @@ void generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::S
 	for (Common::StringArray fileChecksum : fileChecksums) {
 		Common::JSONObject file;
 		file.setVal("name", new Common::JSONValue(fileChecksum[0]));
-		file.setVal("size", new Common::JSONValue(fileChecksum[1]));
+
+		auto tempNode = Common::FSNode(Common::Path(fileChecksum[0]));
+		Common::File tempFile;
+		if (!tempFile.open(tempNode))
+			continue;
+		long long fileSize = tempFile.size();
+		tempFile.close();
+
+		file.setVal("size", new Common::JSONValue(fileSize));
 
 		Common::JSONArray checksums;
-		int index = 0;
+		Common::StringArray checkcodes = {"md5", "md5-5000", "md5-1M", "md5-t-5000"};
+
+		int index = -1;
 		for (Common::String val : fileChecksum) {
+			index++;
+
 			Common::JSONObject checksum;
-			if (index < 2) {
-				index++;
+			if (index < 1) {
 				continue;
 			}
-			checksum.setVal("type", new Common::JSONValue("md5"));
+
+			checksum.setVal("type", new Common::JSONValue(checkcodes[index - 1]));
 			checksum.setVal("checksum", new Common::JSONValue(val));
 
 			checksums.push_back(new Common::JSONValue(checksum));
@@ -110,7 +123,11 @@ void generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::S
 	requestObject.setVal("files", new Common::JSONValue(filesObject));
 
 	Common::JSONValue request(requestObject);
-	debug(request.stringify().c_str());
+	Common::DumpFile outFile;
+	if (outFile.open("output.json"))
+		outFile.write(request.stringify().c_str(), request.stringify().size());
+
+	outFile.close();
 }
 
 } // End of namespace GUI


Commit: 60e44c3590c0e6c4e66764372a94fe530b35daca
    https://github.com/scummvm/scummvm/commit/60e44c3590c0e6c4e66764372a94fe530b35daca
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:41+02:00

Commit Message:
GUI: Update integrity JSON to use relative paths

Changed paths:
    gui/integrity-dialog.cpp


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index f2d8f7bbc62..3da8dd385c6 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -87,7 +87,8 @@ void generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::S
 
 	for (Common::StringArray fileChecksum : fileChecksums) {
 		Common::JSONObject file;
-		file.setVal("name", new Common::JSONValue(fileChecksum[0]));
+		Common::Path relativePath = Common::Path(fileChecksum[0]).relativeTo(gamePath);
+		file.setVal("name", new Common::JSONValue(relativePath.toConfig()));
 
 		auto tempNode = Common::FSNode(Common::Path(fileChecksum[0]));
 		Common::File tempFile;


Commit: 57f36e185b9ef64397fa33c1beb6f4c3e43fe860
    https://github.com/scummvm/scummvm/commit/57f36e185b9ef64397fa33c1beb6f4c3e43fe860
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:41+02:00

Commit Message:
GUI: Create IntegrityDialog class

Changed paths:
    gui/integrity-dialog.cpp
    gui/integrity-dialog.h


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index 3da8dd385c6..cd2accccd40 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -29,7 +29,7 @@
 
 namespace GUI {
 
-Common::Array<Common::StringArray> generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums) {
+Common::Array<Common::StringArray> IntegrityDialog::generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums) {
 	const Common::FSNode dir(gamePath);
 
 	if (!dir.exists() || !dir.isDirectory())
@@ -72,7 +72,7 @@ Common::Array<Common::StringArray> generateChecksums(Common::Path gamePath, Comm
 	return fileChecksums;
 }
 
-void generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language) {
+void IntegrityDialog::generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language) {
 	Common::Array<Common::StringArray> fileChecksums = {};
 	fileChecksums = generateChecksums(gamePath, fileChecksums);
 	Common::JSONObject requestObject;
diff --git a/gui/integrity-dialog.h b/gui/integrity-dialog.h
index 39ec7c7f5bc..5dbd410fa0c 100644
--- a/gui/integrity-dialog.h
+++ b/gui/integrity-dialog.h
@@ -25,9 +25,18 @@
 #include "common/array.h"
 #include "common/str.h"
 
+#include "gui/dialog.h"
+
 namespace GUI {
 
-void generateJSONRequest(Common::String gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language);
+class IntegrityDialog : public Dialog {
+
+public:
+	static void generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language);
+
+private:
+	static Common::Array<Common::StringArray> generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums);
+};
 
 } // End of namespace GUI
 


Commit: 5e173beaad43f3cfe94713195e42a05f818ef8a4
    https://github.com/scummvm/scummvm/commit/5e173beaad43f3cfe94713195e42a05f818ef8a4
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:41+02:00

Commit Message:
GUI: Create 'Check Integrity' button

Changed paths:
    gui/editgamedialog.cpp
    gui/editgamedialog.h
    gui/launcher.cpp


diff --git a/gui/editgamedialog.cpp b/gui/editgamedialog.cpp
index e3047b6dcb1..cb929197c0a 100644
--- a/gui/editgamedialog.cpp
+++ b/gui/editgamedialog.cpp
@@ -36,6 +36,7 @@
 #include "gui/recorderdialog.h"
 #include "gui/EventRecorder.h"
 #endif
+#include "gui/integrity-dialog.h"
 #include "gui/widgets/edittext.h"
 #include "gui/widgets/tab.h"
 #include "gui/widgets/popup.h"
@@ -76,6 +77,7 @@ enum {
 	kCmdGameBrowser = 'PGME',
 	kCmdSaveBrowser = 'PSAV',
 	kCmdSavePathClear = 'PSAC',
+	kCmdCheckIntegrity = 'PCHI',
 
 	kGraphicsTabContainerReflowCmd = 'gtcr'
 };
@@ -282,6 +284,9 @@ EditGameDialog::EditGameDialog(const Common::String &domain)
 	// These buttons have to be extra wide, or the text will be truncated
 	// in the small version of the GUI.
 
+	// GUI: Check integrity button
+	_checkIntegrityButton = new ButtonWidget(tab, 350, 350, 50, 50, _("Check Integrity"), _("Perform integrity check for all game files"), kCmdCheckIntegrity);
+
 	// GUI:  Button + Label for the game path
 	if (!g_gui.useLowResGUI())
 		new ButtonWidget(tab, "GameOptions_Paths.Gamepath", _("Game Path:"), Common::U32String(), kCmdGameBrowser);
@@ -614,6 +619,15 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
 		_savePathWidget->setLabel(Common::Path());
 		break;
 
+	case kCmdCheckIntegrity:
+		IntegrityDialog::generateJSONRequest(Common::Path(ConfMan.get("path", _domain)),
+											 ConfMan.get("gameid", _domain),
+											 ConfMan.get("engineid", _domain),
+											 ConfMan.get("extra", _domain),
+											 ConfMan.get("platform", _domain),
+											 ConfMan.get("language", _domain));
+		break;
+
 	case kOKCmd:
 	{
 		// Write back changes made to config object
diff --git a/gui/editgamedialog.h b/gui/editgamedialog.h
index b02142bfef6..73bc28ca5f7 100644
--- a/gui/editgamedialog.h
+++ b/gui/editgamedialog.h
@@ -77,6 +77,7 @@ protected:
 	PathWidget *_savePathWidget;
 	ButtonWidget *_extraPathClearButton;
 	ButtonWidget *_savePathClearButton;
+	ButtonWidget *_checkIntegrityButton;
 
 	StaticTextWidget *_langPopUpDesc;
 	PopUpWidget *_langPopUp;
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index 14d3169d28e..ce0cd472e89 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -97,7 +97,8 @@ enum {
 	kCmdExtraPathClear = 'PEXC',
 	kCmdGameBrowser = 'PGME',
 	kCmdSaveBrowser = 'PSAV',
-	kCmdSavePathClear = 'PSAC'
+	kCmdSavePathClear = 'PSAC',
+	kCmdCheckIntegrity = 'PCHI'
 };
 
 const GroupingMode groupingModes[] = {


Commit: 31ffefa93dcaccd4de43d7a93f171fb231d61b49
    https://github.com/scummvm/scummvm/commit/31ffefa93dcaccd4de43d7a93f171fb231d61b49
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:42+02:00

Commit Message:
GUI: Check Integrity button now sends JSON request

Changed paths:
    gui/editgamedialog.cpp
    gui/integrity-dialog.cpp
    gui/integrity-dialog.h


diff --git a/gui/editgamedialog.cpp b/gui/editgamedialog.cpp
index cb929197c0a..2b609a0027a 100644
--- a/gui/editgamedialog.cpp
+++ b/gui/editgamedialog.cpp
@@ -620,12 +620,7 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
 		break;
 
 	case kCmdCheckIntegrity:
-		IntegrityDialog::generateJSONRequest(Common::Path(ConfMan.get("path", _domain)),
-											 ConfMan.get("gameid", _domain),
-											 ConfMan.get("engineid", _domain),
-											 ConfMan.get("extra", _domain),
-											 ConfMan.get("platform", _domain),
-											 ConfMan.get("language", _domain));
+		IntegrityDialog("https://example.com/api", _domain).sendJSON();
 		break;
 
 	case kOKCmd:
diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index cd2accccd40..5ceaa122e35 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -22,13 +22,26 @@
 #include "gui/integrity-dialog.h"
 
 #include "common/array.h"
+#include "common/config-manager.h"
 #include "common/debug.h"
 #include "common/file.h"
-#include "common/formats/json.h"
 #include "common/md5.h"
 
 namespace GUI {
 
+IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String gameConfig) : Dialog("GameOptions_IntegrityDialog") {
+	_endpoint = endpoint;
+	_gamePath = ConfMan.get("path", gameConfig);
+	_gameid = ConfMan.get("gameid", gameConfig);
+	_engineid = ConfMan.get("engineid", gameConfig);
+	_extra = ConfMan.get("extra", gameConfig);
+	_platform = ConfMan.get("platform", gameConfig);
+	_language = ConfMan.get("language", gameConfig);
+}
+
+IntegrityDialog::~IntegrityDialog() {
+}
+
 Common::Array<Common::StringArray> IntegrityDialog::generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums) {
 	const Common::FSNode dir(gamePath);
 
@@ -72,7 +85,7 @@ Common::Array<Common::StringArray> IntegrityDialog::generateChecksums(Common::Pa
 	return fileChecksums;
 }
 
-void IntegrityDialog::generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language) {
+Common::JSONValue *IntegrityDialog::generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language) {
 	Common::Array<Common::StringArray> fileChecksums = {};
 	fileChecksums = generateChecksums(gamePath, fileChecksums);
 	Common::JSONObject requestObject;
@@ -123,12 +136,27 @@ void IntegrityDialog::generateJSONRequest(Common::Path gamePath, Common::String
 
 	requestObject.setVal("files", new Common::JSONValue(filesObject));
 
-	Common::JSONValue request(requestObject);
-	Common::DumpFile outFile;
-	if (outFile.open("output.json"))
-		outFile.write(request.stringify().c_str(), request.stringify().size());
+	Common::JSONValue *request = new Common::JSONValue(requestObject);
+	return request;
+}
+
+void IntegrityDialog::checksumResponseCallback(const Common::JSONValue *r) {
+	debug("Response recieved!");
+}
+
+void IntegrityDialog::errorCallback(const Networking::ErrorResponse &error) {
+	debug("ERROR %ld: %s", error.httpResponseCode, error.response.c_str());
+}
+
+void IntegrityDialog::sendJSON() {
+	Networking::PostRequest conn(_endpoint,
+		new Common::Callback<IntegrityDialog, const Common::JSONValue *>(this, &IntegrityDialog::checksumResponseCallback),
+		new Common::Callback<IntegrityDialog, const Networking::ErrorResponse &>(this, &IntegrityDialog::errorCallback));
 
-	outFile.close();
+	Common::JSONValue *json = generateJSONRequest(Common::Path(_gamePath), _gameid, _engineid, _extra, _platform, _language);
+	conn.setJSONData(json);
+	conn.start();
+	delete json;
 }
 
 } // End of namespace GUI
diff --git a/gui/integrity-dialog.h b/gui/integrity-dialog.h
index 5dbd410fa0c..1bdadc67654 100644
--- a/gui/integrity-dialog.h
+++ b/gui/integrity-dialog.h
@@ -22,19 +22,35 @@
 #ifndef GUI_INTEGRITY_DIALOG_H
 #define GUI_INTEGRITY_DIALOG_H
 
+#include "backends/networking/curl/postrequest.h"
+
 #include "common/array.h"
+#include "common/formats/json.h"
 #include "common/str.h"
 
 #include "gui/dialog.h"
 
 namespace GUI {
 
-class IntegrityDialog : public Dialog {
+class IntegrityDialog : Dialog {
+	Common::String _endpoint;
+	Common::String _gamePath;
+	Common::String _gameid;
+	Common::String _engineid;
+	Common::String _extra;
+	Common::String _platform;
+	Common::String _language;
 
 public:
-	static void generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language);
+	IntegrityDialog(Common::String endpoint, Common::String gameConfig);
+	~IntegrityDialog();
+
+	void sendJSON();
+	static Common::JSONValue *generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language);
 
 private:
+	void checksumResponseCallback(const Common::JSONValue *r);
+	void errorCallback(const Networking::ErrorResponse &error);
 	static Common::Array<Common::StringArray> generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums);
 };
 


Commit: d9c545bb9d8c27d50cfdd0f3028462c43017d867
    https://github.com/scummvm/scummvm/commit/d9c545bb9d8c27d50cfdd0f3028462c43017d867
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:42+02:00

Commit Message:
GUI: Fix JSON connection

Changed paths:
    gui/integrity-dialog.cpp


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index 5ceaa122e35..33a3275a868 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -141,7 +141,7 @@ Common::JSONValue *IntegrityDialog::generateJSONRequest(Common::Path gamePath, C
 }
 
 void IntegrityDialog::checksumResponseCallback(const Common::JSONValue *r) {
-	debug("Response recieved!");
+	debug(r->stringify().c_str());
 }
 
 void IntegrityDialog::errorCallback(const Networking::ErrorResponse &error) {
@@ -149,13 +149,14 @@ void IntegrityDialog::errorCallback(const Networking::ErrorResponse &error) {
 }
 
 void IntegrityDialog::sendJSON() {
-	Networking::PostRequest conn(_endpoint,
+	auto conn = new Networking::PostRequest(_endpoint,
 		new Common::Callback<IntegrityDialog, const Common::JSONValue *>(this, &IntegrityDialog::checksumResponseCallback),
 		new Common::Callback<IntegrityDialog, const Networking::ErrorResponse &>(this, &IntegrityDialog::errorCallback));
 
 	Common::JSONValue *json = generateJSONRequest(Common::Path(_gamePath), _gameid, _engineid, _extra, _platform, _language);
-	conn.setJSONData(json);
-	conn.start();
+	conn->setJSONData(json);
+	conn->setContentType("application/json");
+	conn->start();
 	delete json;
 }
 


Commit: 71121e18ec1023284410416f547f37d67013b00a
    https://github.com/scummvm/scummvm/commit/71121e18ec1023284410416f547f37d67013b00a
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:42+02:00

Commit Message:
GUI: Add Checkintegrity button to GameOptions_Path

Changed paths:
    gui/themes/common/highres_layout.stx
    gui/themes/common/lowres_layout.stx
    gui/themes/default.inc
    gui/themes/scummclassic/classic_layout.stx
    gui/themes/scummclassic/classic_layout_lowres.stx


diff --git a/gui/themes/common/highres_layout.stx b/gui/themes/common/highres_layout.stx
index 7b2a91e1ade..bfba18abe4f 100644
--- a/gui/themes/common/highres_layout.stx
+++ b/gui/themes/common/highres_layout.stx
@@ -1827,6 +1827,10 @@
 						height = 'Globals.Line.Height'
 				/>
 			</layout>
+			<space size='16'/>
+			<widget name = 'Checkintegrity'
+					type = 'Button'
+			/>
 		</layout>
 	</dialog>
 
diff --git a/gui/themes/common/lowres_layout.stx b/gui/themes/common/lowres_layout.stx
index 3ff90b2f8bd..d573400c4e6 100644
--- a/gui/themes/common/lowres_layout.stx
+++ b/gui/themes/common/lowres_layout.stx
@@ -1666,6 +1666,10 @@
 						height = 'Globals.Line.Height'
 				/>
 			</layout>
+			<space size='8'/>
+			<widget name = 'Checkintegrity'
+					type = 'Button'
+			/>
 		</layout>
 	</dialog>
 
diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index 6e9c5c0f822..d6eebf3193f 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -2808,6 +2808,10 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
 "height='Globals.Line.Height' "
 "/>"
 "</layout>"
+"<space size='16'/>"
+"<widget name='Checkintegrity' "
+"type='Button' "
+"/>"
 "</layout>"
 "</dialog>"
 "<dialog name='GlobalMenu' overlays='screen_center'>"
@@ -5162,6 +5166,10 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
 "height='Globals.Line.Height' "
 "/>"
 "</layout>"
+"<space size='8'/>"
+"<widget name='Checkintegrity' "
+"type='Button' "
+"/>"
 "</layout>"
 "</dialog>"
 "<dialog name='GlobalMenu' overlays='screen_center'>"
diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx
index 3916d6fbfaf..06a96083f79 100644
--- a/gui/themes/scummclassic/classic_layout.stx
+++ b/gui/themes/scummclassic/classic_layout.stx
@@ -1474,6 +1474,10 @@
 						height = 'Globals.Line.Height'
 				/>
 			</layout>
+			<space size='16'/>
+			<widget name = 'Checkintegrity'
+					type = 'Button'
+			/>
 		</layout>
 	</dialog>
 
diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx
index 35d8903da74..ce3b4c15f72 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -1495,6 +1495,10 @@
 						height = 'Globals.Line.Height'
 				/>
 			</layout>
+			<space size='8'/>
+			<widget name = 'Checkintegrity'
+					type = 'Button'
+			/>
 		</layout>
 	</dialog>
 


Commit: c8a2fc28ea29408aed59159bd8703270e50eed21
    https://github.com/scummvm/scummvm/commit/c8a2fc28ea29408aed59159bd8703270e50eed21
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:42+02:00

Commit Message:
GUI: Update Checkintegrity button, endpoint

 - Endpoint is a localhost url

Changed paths:
    gui/editgamedialog.cpp


diff --git a/gui/editgamedialog.cpp b/gui/editgamedialog.cpp
index 2b609a0027a..669ab1531bc 100644
--- a/gui/editgamedialog.cpp
+++ b/gui/editgamedialog.cpp
@@ -285,7 +285,7 @@ EditGameDialog::EditGameDialog(const Common::String &domain)
 	// in the small version of the GUI.
 
 	// GUI: Check integrity button
-	_checkIntegrityButton = new ButtonWidget(tab, 350, 350, 50, 50, _("Check Integrity"), _("Perform integrity check for all game files"), kCmdCheckIntegrity);
+	_checkIntegrityButton = new ButtonWidget(tab, "GameOptions_Paths.Checkintegrity", _("Check Integrity"), _("Perform integrity check for all game files"), kCmdCheckIntegrity);
 
 	// GUI:  Button + Label for the game path
 	if (!g_gui.useLowResGUI())
@@ -620,7 +620,7 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
 		break;
 
 	case kCmdCheckIntegrity:
-		IntegrityDialog("https://example.com/api", _domain).sendJSON();
+		IntegrityDialog("http://localhost:8000/api/validate", _domain).sendJSON();
 		break;
 
 	case kOKCmd:


Commit: 2d3db55e21d3ca938c10f1fac186e9d99166814f
    https://github.com/scummvm/scummvm/commit/2d3db55e21d3ca938c10f1fac186e9d99166814f
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:42+02:00

Commit Message:
GUI: Add percentage bar for checksum calculation

Based on file size

Changed paths:
    gui/integrity-dialog.cpp
    gui/integrity-dialog.h


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index 33a3275a868..cebbea2e240 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -27,6 +27,9 @@
 #include "common/file.h"
 #include "common/md5.h"
 
+#include "gui/message.h"
+#include "gui/widget.h"
+
 namespace GUI {
 
 IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String gameConfig) : Dialog("GameOptions_IntegrityDialog") {
@@ -37,11 +40,54 @@ IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String gameCon
 	_extra = ConfMan.get("extra", gameConfig);
 	_platform = ConfMan.get("platform", gameConfig);
 	_language = ConfMan.get("language", gameConfig);
+
+	calculateTotalSize(_gamePath);
+	_calculatedSize = 0;
+	_progressPercentage = 0;
+
+	MessageDialog alert(Common::U32String("Verifying file integrity may take a long time to complete.\nAre you sure you want to continue?"), "OK", "Cancel");
+	alert.runModal();
+
+	_progressBar = new SliderWidget(this, "GameOptions_IntegrityDialog.ProgressBar");
+	_progressBar->setMinValue(0);
+	_progressBar->setMaxValue(100);
+	_progressBar->setValue(_progressPercentage);
+	_progressBar->setEnabled(false);
 }
 
 IntegrityDialog::~IntegrityDialog() {
 }
 
+void IntegrityDialog::calculateTotalSize(Common::Path gamePath) {
+	const Common::FSNode dir(gamePath);
+
+	if (!dir.exists() || !dir.isDirectory())
+		return;
+
+	Common::FSList fileList;
+	if (!dir.getChildren(fileList, Common::FSNode::kListAll))
+		return;
+
+	if (fileList.empty())
+		return;
+
+	// Process the files and subdirectories in the current directory recursively
+	for (Common::FSList::const_iterator it = fileList.begin(); it != fileList.end(); it++) {
+		const Common::FSNode &entry = *it;
+
+		if (entry.isDirectory())
+			calculateTotalSize(entry.getPath());
+		else {
+			const Common::Path filename(entry.getPath());
+			Common::File file;
+			if (!file.open(entry))
+				continue;
+
+			_totalSize += file.size();
+		}
+	}
+}
+
 Common::Array<Common::StringArray> IntegrityDialog::generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums) {
 	const Common::FSNode dir(gamePath);
 
@@ -77,6 +123,9 @@ Common::Array<Common::StringArray> IntegrityDialog::generateChecksums(Common::Pa
 			file.seek(-5000, SEEK_END);
 			fileChecksum.push_back(Common::computeStreamMD5AsString(file).c_str());
 
+			_calculatedSize += file.size();
+			_progressPercentage = _calculatedSize / _totalSize;
+
 			file.close();
 			fileChecksums.push_back(fileChecksum);
 		}
diff --git a/gui/integrity-dialog.h b/gui/integrity-dialog.h
index 1bdadc67654..8547cf3af86 100644
--- a/gui/integrity-dialog.h
+++ b/gui/integrity-dialog.h
@@ -29,29 +29,38 @@
 #include "common/str.h"
 
 #include "gui/dialog.h"
+#include "gui/widget.h"
 
 namespace GUI {
 
 class IntegrityDialog : Dialog {
 	Common::String _endpoint;
-	Common::String _gamePath;
+	Common::Path _gamePath;
 	Common::String _gameid;
 	Common::String _engineid;
 	Common::String _extra;
 	Common::String _platform;
 	Common::String _language;
 
+	int _totalSize;
+	int _calculatedSize;
+	int _progressPercentage;
+
+	SliderWidget *_progressBar;
+
 public:
 	IntegrityDialog(Common::String endpoint, Common::String gameConfig);
 	~IntegrityDialog();
 
 	void sendJSON();
-	static Common::JSONValue *generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language);
 
 private:
+	void calculateTotalSize(Common::Path gamePath);
+
 	void checksumResponseCallback(const Common::JSONValue *r);
 	void errorCallback(const Networking::ErrorResponse &error);
-	static Common::Array<Common::StringArray> generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums);
+	Common::Array<Common::StringArray> generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums);
+	Common::JSONValue *generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language);
 };
 
 } // End of namespace GUI


Commit: e9622b15ae99bf3419680b70ea3b94744f8b02cb
    https://github.com/scummvm/scummvm/commit/e9622b15ae99bf3419680b70ea3b94744f8b02cb
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:42+02:00

Commit Message:
GUI: Add parseJSON() to IntegrityDialog

Changed paths:
    gui/integrity-dialog.cpp
    gui/integrity-dialog.h


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index cebbea2e240..441443f009f 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -45,6 +45,9 @@ IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String gameCon
 	_calculatedSize = 0;
 	_progressPercentage = 0;
 
+	_error = false;
+	_results = new Common::Array<int>(5, 0);
+
 	MessageDialog alert(Common::U32String("Verifying file integrity may take a long time to complete.\nAre you sure you want to continue?"), "OK", "Cancel");
 	alert.runModal();
 
@@ -53,6 +56,8 @@ IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String gameCon
 	_progressBar->setMaxValue(100);
 	_progressBar->setValue(_progressPercentage);
 	_progressBar->setEnabled(false);
+
+	sendJSON();
 }
 
 IntegrityDialog::~IntegrityDialog() {
@@ -191,6 +196,7 @@ Common::JSONValue *IntegrityDialog::generateJSONRequest(Common::Path gamePath, C
 
 void IntegrityDialog::checksumResponseCallback(const Common::JSONValue *r) {
 	debug(r->stringify().c_str());
+	parseJSON(r);
 }
 
 void IntegrityDialog::errorCallback(const Networking::ErrorResponse &error) {
@@ -209,4 +215,26 @@ void IntegrityDialog::sendJSON() {
 	delete json;
 }
 
+void IntegrityDialog::parseJSON(const Common::JSONValue *response) {
+	Common::JSONObject responseObject = response->asObject();
+	_error = (responseObject.getVal("error"));
+	debug("Error is %d", _error);
+
+	for (Common::JSONValue *fileJSON : responseObject.getVal("files")->asArray()) {
+		Common::String status = fileJSON->asObject().getVal("status")->asString();
+		debug(status.c_str());
+
+		if (status == "ok")
+			(*_results)[OK]++;
+		else if (status == "missing")
+			(*_results)[MISSING]++;
+		else if (status == "checksum_mismatch")
+			(*_results)[CHECKSUM_MISMATCH]++;
+		else if (status == "size_mismatch")
+			(*_results)[SIZE_MISMATCH]++;
+		else if (status == "unknown")
+			(*_results)[UNKNOWN]++;
+	}
+}
+
 } // End of namespace GUI
diff --git a/gui/integrity-dialog.h b/gui/integrity-dialog.h
index 8547cf3af86..05c3c94734e 100644
--- a/gui/integrity-dialog.h
+++ b/gui/integrity-dialog.h
@@ -33,6 +33,14 @@
 
 namespace GUI {
 
+enum {
+	OK = 0,
+	MISSING = 1,
+	CHECKSUM_MISMATCH = 2,
+	SIZE_MISMATCH = 3,
+	UNKNOWN = 4
+};
+
 class IntegrityDialog : Dialog {
 	Common::String _endpoint;
 	Common::Path _gamePath;
@@ -46,6 +54,9 @@ class IntegrityDialog : Dialog {
 	int _calculatedSize;
 	int _progressPercentage;
 
+	bool _error;
+	Common::Array<int> *_results;
+
 	SliderWidget *_progressBar;
 
 public:
@@ -61,6 +72,8 @@ private:
 	void errorCallback(const Networking::ErrorResponse &error);
 	Common::Array<Common::StringArray> generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums);
 	Common::JSONValue *generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language);
+
+	void parseJSON(const Common::JSONValue *response);
 };
 
 } // End of namespace GUI


Commit: 1c423d5c06d4fec971437a440f6da13e57d90c05
    https://github.com/scummvm/scummvm/commit/1c423d5c06d4fec971437a440f6da13e57d90c05
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:42+02:00

Commit Message:
GUI: Add dialog for calculation progress, results

 - Display all OK / mismatched files
 - If fileset is unknown, add it to the db and show message with email
   body

Changed paths:
    gui/integrity-dialog.cpp
    gui/integrity-dialog.h
    gui/themes/common/highres_layout.stx


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index 441443f009f..32d6eddcbd3 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -26,43 +26,181 @@
 #include "common/debug.h"
 #include "common/file.h"
 #include "common/md5.h"
+#include "common/translation.h"
 
+#include "gui/gui-manager.h"
+#include "gui/launcher.h"
 #include "gui/message.h"
 #include "gui/widget.h"
 
 namespace GUI {
 
-IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String gameConfig) : Dialog("GameOptions_IntegrityDialog") {
-	_endpoint = endpoint;
-	_gamePath = ConfMan.get("path", gameConfig);
-	_gameid = ConfMan.get("gameid", gameConfig);
-	_engineid = ConfMan.get("engineid", gameConfig);
-	_extra = ConfMan.get("extra", gameConfig);
-	_platform = ConfMan.get("platform", gameConfig);
-	_language = ConfMan.get("language", gameConfig);
+enum {
+	kCleanupCmd = 'DlCL',
+};
+
+struct DialogState {
+	IntegrityDialog *dialog;
+	IconProcessState state;
+
+	int totalSize;
+	int calculatedSize;
+
+	Common::String endpoint;
+	Common::Path gamePath;
+	Common::String gameid;
+	Common::String engineid;
+	Common::String extra;
+	Common::String platform;
+	Common::String language;
+
+	DialogState() {
+		state = kChecksumStateNone;
+		totalSize = calculatedSize = 0;
+		dialog = nullptr;
+	}
+} static *g_state;
 
-	calculateTotalSize(_gamePath);
-	_calculatedSize = 0;
-	_progressPercentage = 0;
+uint32 getDownloadingProgress() {
+	if (!g_state || g_state->totalSize == 0)
+		return 0;
 
-	_error = false;
-	_results = new Common::Array<int>(5, 0);
+	uint32 progress = (uint32)(100 * ((double)g_state->calculatedSize / (double)g_state->totalSize));
 
-	MessageDialog alert(Common::U32String("Verifying file integrity may take a long time to complete.\nAre you sure you want to continue?"), "OK", "Cancel");
-	alert.runModal();
+	return progress;
+}
+
+IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String domain) : Dialog("GameOptions_IntegrityDialog"), _close(false) {
 
+	_backgroundType = GUI::ThemeEngine::kDialogBackgroundPlain;
+
+	_statusText = new StaticTextWidget(this, "GameOptions_IntegrityDialog.StatusText", Common::U32String::format(_("Calculating file checksums...")));
+	_errorText = new StaticTextWidget(this, "GameOptions_IntegrityDialog.ErrorText", Common::U32String(""));
+
+	uint32 progress = getDownloadingProgress();
 	_progressBar = new SliderWidget(this, "GameOptions_IntegrityDialog.ProgressBar");
 	_progressBar->setMinValue(0);
 	_progressBar->setMaxValue(100);
-	_progressBar->setValue(_progressPercentage);
+	_progressBar->setValue(progress);
 	_progressBar->setEnabled(false);
+	_percentLabel = new StaticTextWidget(this, "GameOptions_IntegrityDialog.PercentText", Common::String::format("%u %%", progress));
+	_cancelButton = new ButtonWidget(this, "GameOptions_IntegrityDialog.MainButton", _("Cancel"), Common::U32String(), kCleanupCmd);
+
+	MessageDialog alert(Common::U32String("Verifying file integrity may take a long time to complete.\nAre you sure you want to continue?"), "OK", "Cancel");
+	int result = alert.runModal();
+	if (result == 1)
+		return;
+
+	if (!g_state) {
+		g_state = new DialogState();
+		g_state->dialog = this;
+
+		setState(kChecksumStateCalculating);
+		refreshWidgets();
+
+		g_state->endpoint = endpoint;
+		g_state->gamePath = Common::Path(ConfMan.get("path", domain));
+		g_state->gameid = ConfMan.get("gameid", domain);
+		g_state->engineid = ConfMan.get("engineid", domain);
+		g_state->extra = ConfMan.get("extra", domain);
+		g_state->platform = ConfMan.get("platform", domain);
+		g_state->language = ConfMan.get("language", domain);
+		calculateTotalSize(g_state->gamePath);
+
+		sendJSON();
+	} else {
+		g_state->dialog = this;
 
-	sendJSON();
+		setState(g_state->state);
+		refreshWidgets();
+	}
 }
 
 IntegrityDialog::~IntegrityDialog() {
 }
 
+void IntegrityDialog::open() {
+	Dialog::open();
+	reflowLayout();
+	g_gui.scheduleTopDialogRedraw();
+}
+
+void IntegrityDialog::close() {
+	if (g_state)
+		g_state->dialog = nullptr;
+
+	Dialog::close();
+}
+
+void IntegrityDialog::setState(IconProcessState state) {
+	g_state->state = state;
+
+	switch (state) {
+	case kChecksumStateNone:
+	case kChecksumStateCalculating:
+		_statusText->setLabel(Common::U32String::format(_("Calculating file checksums...")));
+		_cancelButton->setLabel(_("Cancel"));
+		_cancelButton->setCmd(kCleanupCmd);
+		break;
+
+	case kChecksumComplete:
+		_statusText->setLabel(Common::U32String::format(_("Calculation complete")));
+		_cancelButton->setVisible(false);
+		_cancelButton->setLabel(_("Cancel"));
+		_cancelButton->setCmd(kCleanupCmd);
+
+		break;
+	}
+}
+
+void IntegrityDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
+	switch (cmd) {
+	case kCleanupCmd: {
+		delete g_state;
+		g_state = nullptr;
+
+		close();
+		break;
+	}
+	default:
+		Dialog::handleCommand(sender, cmd, data);
+	}
+}
+
+void IntegrityDialog::handleTickle() {
+	if (_close) {
+		close();
+		_close = false;
+		return;
+	}
+
+	int32 progress = getDownloadingProgress();
+	if (_progressBar->getValue() != progress) {
+		refreshWidgets();
+		g_gui.scheduleTopDialogRedraw();
+	}
+
+	Dialog::handleTickle();
+}
+
+void IntegrityDialog::reflowLayout() {
+	Dialog::reflowLayout();
+	refreshWidgets();
+}
+
+void IntegrityDialog::refreshWidgets() {
+	uint32 progress = getDownloadingProgress();
+	_percentLabel->setLabel(Common::String::format("%u %%", progress));
+	_progressBar->setValue(progress);
+}
+
+void IntegrityDialog::setError(Common::U32String &msg) {
+	_errorText->setLabel(msg);
+
+	_cancelButton->setLabel(_("Close"));
+	_cancelButton->setCmd(kCleanupCmd);
+}
+
 void IntegrityDialog::calculateTotalSize(Common::Path gamePath) {
 	const Common::FSNode dir(gamePath);
 
@@ -88,7 +226,7 @@ void IntegrityDialog::calculateTotalSize(Common::Path gamePath) {
 			if (!file.open(entry))
 				continue;
 
-			_totalSize += file.size();
+			g_state->totalSize += file.size();
 		}
 	}
 }
@@ -128,8 +266,7 @@ Common::Array<Common::StringArray> IntegrityDialog::generateChecksums(Common::Pa
 			file.seek(-5000, SEEK_END);
 			fileChecksum.push_back(Common::computeStreamMD5AsString(file).c_str());
 
-			_calculatedSize += file.size();
-			_progressPercentage = _calculatedSize / _totalSize;
+			g_state->calculatedSize += file.size();
 
 			file.close();
 			fileChecksums.push_back(fileChecksum);
@@ -196,7 +333,9 @@ Common::JSONValue *IntegrityDialog::generateJSONRequest(Common::Path gamePath, C
 
 void IntegrityDialog::checksumResponseCallback(const Common::JSONValue *r) {
 	debug(r->stringify().c_str());
-	parseJSON(r);
+	Common::String messageText = IntegrityDialog::parseJSON(r);
+	MessageDialog result(messageText);
+	result.reflowLayout();
 }
 
 void IntegrityDialog::errorCallback(const Networking::ErrorResponse &error) {
@@ -204,37 +343,46 @@ void IntegrityDialog::errorCallback(const Networking::ErrorResponse &error) {
 }
 
 void IntegrityDialog::sendJSON() {
-	auto conn = new Networking::PostRequest(_endpoint,
+	auto conn = new Networking::PostRequest(g_state->endpoint,
 		new Common::Callback<IntegrityDialog, const Common::JSONValue *>(this, &IntegrityDialog::checksumResponseCallback),
 		new Common::Callback<IntegrityDialog, const Networking::ErrorResponse &>(this, &IntegrityDialog::errorCallback));
 
-	Common::JSONValue *json = generateJSONRequest(Common::Path(_gamePath), _gameid, _engineid, _extra, _platform, _language);
+	Common::JSONValue *json = generateJSONRequest(
+		g_state->gamePath, g_state->gameid, g_state->engineid, g_state->extra, g_state->platform, g_state->language);
 	conn->setJSONData(json);
 	conn->setContentType("application/json");
 	conn->start();
 	delete json;
 }
 
-void IntegrityDialog::parseJSON(const Common::JSONValue *response) {
+Common::String IntegrityDialog::parseJSON(const Common::JSONValue *response) {
+	Common::String messageText;
+
 	Common::JSONObject responseObject = response->asObject();
-	_error = (responseObject.getVal("error"));
-	debug("Error is %d", _error);
+	int responeError = responseObject.getVal("error")->asIntegerNumber();
+
+	if (responeError == -1) { // Unknown variant
+		long long fileset = responseObject.getVal("fileset")->asIntegerNumber();
+		messageText =
+			Common::String::format("Your set of game files seems to be unknown to us. If you are sure that this is a valid unknown variant, please send the following e-mail to integrity at scummvm.org \n\
+		The game of fileset %lld seems to be an unknown game variant. \n\
+		The details of the game : %s, %s, %s, %s, %s",
+								   fileset, g_state->engineid.c_str(), g_state->gameid.c_str(), g_state->platform.c_str(), g_state->language.c_str(), g_state->extra.c_str());
+
+		return messageText;
+	}
 
 	for (Common::JSONValue *fileJSON : responseObject.getVal("files")->asArray()) {
+		Common::String name = fileJSON->asObject().getVal("name")->asString();
 		Common::String status = fileJSON->asObject().getVal("status")->asString();
 		debug(status.c_str());
 
-		if (status == "ok")
-			(*_results)[OK]++;
-		else if (status == "missing")
-			(*_results)[MISSING]++;
-		else if (status == "checksum_mismatch")
-			(*_results)[CHECKSUM_MISMATCH]++;
-		else if (status == "size_mismatch")
-			(*_results)[SIZE_MISMATCH]++;
-		else if (status == "unknown")
-			(*_results)[UNKNOWN]++;
+		messageText += Common::String::format("%s %s\n", name.c_str(), status.c_str());
 	}
+	if (messageText == "")
+		messageText += "Files all OK";
+
+	return messageText;
 }
 
 } // End of namespace GUI
diff --git a/gui/integrity-dialog.h b/gui/integrity-dialog.h
index 05c3c94734e..cc4220725d8 100644
--- a/gui/integrity-dialog.h
+++ b/gui/integrity-dialog.h
@@ -41,39 +41,47 @@ enum {
 	UNKNOWN = 4
 };
 
+enum IconProcessState {
+	kChecksumStateNone,
+	kChecksumStateCalculating,
+	kChecksumComplete
+};
+
 class IntegrityDialog : Dialog {
-	Common::String _endpoint;
-	Common::Path _gamePath;
-	Common::String _gameid;
-	Common::String _engineid;
-	Common::String _extra;
-	Common::String _platform;
-	Common::String _language;
+	StaticTextWidget *_statusText;
+	StaticTextWidget *_errorText;
+	StaticTextWidget *_percentLabel;
+	SliderWidget *_progressBar;
+	ButtonWidget *_cancelButton;
 
-	int _totalSize;
-	int _calculatedSize;
-	int _progressPercentage;
+	bool _close;
 
-	bool _error;
-	Common::Array<int> *_results;
-
-	SliderWidget *_progressBar;
+	void refreshWidgets();
 
 public:
 	IntegrityDialog(Common::String endpoint, Common::String gameConfig);
 	~IntegrityDialog();
 
 	void sendJSON();
+	void checksumResponseCallback(const Common::JSONValue *r);
+	void errorCallback(const Networking::ErrorResponse &error);
 
-private:
 	void calculateTotalSize(Common::Path gamePath);
 
-	void checksumResponseCallback(const Common::JSONValue *r);
-	void errorCallback(const Networking::ErrorResponse &error);
-	Common::Array<Common::StringArray> generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums);
-	Common::JSONValue *generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language);
+	static Common::Array<Common::StringArray> generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums);
+	static Common::JSONValue *generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language);
+	static Common::String parseJSON(const Common::JSONValue *response);
 
-	void parseJSON(const Common::JSONValue *response);
+	void open() override;
+	void close() override;
+	void handleCommand(CommandSender *sender, uint32 cmd, uint32 data) override;
+	void handleTickle() override;
+	void reflowLayout() override;
+
+	void setError(Common::U32String &msg);
+
+private:
+	void setState(IconProcessState state);
 };
 
 } // End of namespace GUI
diff --git a/gui/themes/common/highres_layout.stx b/gui/themes/common/highres_layout.stx
index bfba18abe4f..937686c6edb 100644
--- a/gui/themes/common/highres_layout.stx
+++ b/gui/themes/common/highres_layout.stx
@@ -1834,6 +1834,31 @@
 		</layout>
 	</dialog>
 
+	<dialog name = 'GameOptions_IntegrityDialog' overlays = 'Dialog.GameOptions' shading = 'dim'>
+		<layout type = 'vertical' padding = '16, 16, 16, 8' spacing = '8'>
+			<widget name = 'StatusText'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'ErrorText'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'ProgressBar'
+					height = 'Globals.Button.Height'
+			/>
+			<space size = '1'/>
+			<widget name = 'PercentText'
+					height = 'Globals.Line.Height'
+					textalign = 'center'
+			/>
+			<space/>
+			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10'>
+				<widget name = 'MainButton'
+						type = 'Button'
+				/>
+			</layout>
+		</layout>
+	</dialog>
+
 	<dialog name = 'GlobalMenu' overlays = 'screen_center'>
 		<layout type = 'vertical' padding = '16, 16, 16, 16' align = 'center'>
 			<widget name = 'Logo'


Commit: 70eb3d654fef24a81f3a4019582ce4642c575c38
    https://github.com/scummvm/scummvm/commit/70eb3d654fef24a81f3a4019582ce4642c575c38
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:42+02:00

Commit Message:
GUI: Update integrity dialog message text

Changed paths:
    gui/editgamedialog.cpp
    gui/integrity-dialog.cpp


diff --git a/gui/editgamedialog.cpp b/gui/editgamedialog.cpp
index 669ab1531bc..7c57ba3d1f0 100644
--- a/gui/editgamedialog.cpp
+++ b/gui/editgamedialog.cpp
@@ -619,9 +619,10 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
 		_savePathWidget->setLabel(Common::Path());
 		break;
 
-	case kCmdCheckIntegrity:
-		IntegrityDialog("http://localhost:8000/api/validate", _domain).sendJSON();
+	case kCmdCheckIntegrity: {
+		IntegrityDialog wizard("http://localhost:8000/api/validate", _domain);
 		break;
+	}
 
 	case kOKCmd:
 	{
diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index 32d6eddcbd3..2a05871feed 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -372,10 +372,22 @@ Common::String IntegrityDialog::parseJSON(const Common::JSONValue *response) {
 		return messageText;
 	}
 
+	Common::Array<int> results = Common::Array<int>(5, 0);
 	for (Common::JSONValue *fileJSON : responseObject.getVal("files")->asArray()) {
 		Common::String name = fileJSON->asObject().getVal("name")->asString();
 		Common::String status = fileJSON->asObject().getVal("status")->asString();
-		debug(status.c_str());
+
+		if (status == "ok") {
+			results[OK]++;
+			continue;
+		} else if (status == "missing")
+			results[MISSING]++;
+		else if (status == "checksum_mismatch")
+			results[CHECKSUM_MISMATCH]++;
+		else if (status == "size_mismatch")
+			results[SIZE_MISMATCH]++;
+		else if (status == "unknown")
+			results[UNKNOWN]++;
 
 		messageText += Common::String::format("%s %s\n", name.c_str(), status.c_str());
 	}


Commit: f7919980d5ea1107d01dacf0b0e30f2d47b199be
    https://github.com/scummvm/scummvm/commit/f7919980d5ea1107d01dacf0b0e30f2d47b199be
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:42+02:00

Commit Message:
GUI: Update file validation endpoint

Changed paths:
    gui/editgamedialog.cpp


diff --git a/gui/editgamedialog.cpp b/gui/editgamedialog.cpp
index 7c57ba3d1f0..81c22ffa2c6 100644
--- a/gui/editgamedialog.cpp
+++ b/gui/editgamedialog.cpp
@@ -620,7 +620,7 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
 		break;
 
 	case kCmdCheckIntegrity: {
-		IntegrityDialog wizard("http://localhost:8000/api/validate", _domain);
+		IntegrityDialog wizard("http://gamesdb.sev.zone/endpoints/validate.php", _domain);
 		break;
 	}
 


Commit: a1213ecb46dbb2edc3819704c030da8e0c0bc4de
    https://github.com/scummvm/scummvm/commit/a1213ecb46dbb2edc3819704c030da8e0c0bc4de
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:42+02:00

Commit Message:
GUI: Calculate checksums of mac files correctly

Changed paths:
    gui/integrity-dialog.cpp


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index 2a05871feed..c152ba973da 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -25,6 +25,7 @@
 #include "common/config-manager.h"
 #include "common/debug.h"
 #include "common/file.h"
+#include "common/macresman.h"
 #include "common/md5.h"
 #include "common/translation.h"
 
@@ -221,7 +222,6 @@ void IntegrityDialog::calculateTotalSize(Common::Path gamePath) {
 		if (entry.isDirectory())
 			calculateTotalSize(entry.getPath());
 		else {
-			const Common::Path filename(entry.getPath());
 			Common::File file;
 			if (!file.open(entry))
 				continue;
@@ -252,6 +252,26 @@ Common::Array<Common::StringArray> IntegrityDialog::generateChecksums(Common::Pa
 			generateChecksums(entry.getPath(), fileChecksums);
 		else {
 			const Common::Path filename(entry.getPath());
+			auto macFile = Common::MacResManager();
+			if (macFile.openFileOrDataFork(filename)) {
+				auto originalStream = macFile.openFileOrDataFork(filename);
+				auto fileStream = originalStream;
+
+				Common::Array<Common::String> fileChecksum = {filename.toString()};
+				// Various checksizes
+				for (auto size : {0, 5000, 1024 * 1024}) {
+					fileChecksum.push_back(Common::computeStreamMD5AsString(*(fileStream), size).c_str());
+					fileStream->seek(0);
+				}
+				// Tail checksums with checksize 5000
+				fileStream->seek(-5000, SEEK_END);
+				fileChecksum.push_back(Common::computeStreamMD5AsString(*(fileStream)).c_str());
+
+				g_state->calculatedSize += fileStream->size();
+
+				fileChecksums.push_back(fileChecksum);
+			}
+
 			Common::File file;
 			if (!file.open(entry))
 				continue;


Commit: 479ae47af133297e4090413cfd402ccf9682bff9
    https://github.com/scummvm/scummvm/commit/479ae47af133297e4090413cfd402ccf9682bff9
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:42+02:00

Commit Message:
GUI: Add integrity-dialog.cpp to POTFILES

Changed paths:
    po/POTFILES


diff --git a/po/POTFILES b/po/POTFILES
index 9ef71c3d044..679d765d6e6 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -9,6 +9,7 @@ gui/downloadpacksdialog.cpp
 gui/dump-all-dialogs.cpp
 gui/editgamedialog.cpp
 gui/editrecorddialog.cpp
+gui/integrity-dialog.cpp
 gui/filebrowser-dialog.cpp
 gui/fluidsynth-dialog.cpp
 gui/gui-manager.cpp


Commit: 17e695e8bf21ea66a33614b4f80370d68cf20df8
    https://github.com/scummvm/scummvm/commit/17e695e8bf21ea66a33614b4f80370d68cf20df8
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:42+02:00

Commit Message:
GUI: Update translatable and debug strings

Changed paths:
    gui/integrity-dialog.cpp


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index c152ba973da..6d62a0fbcd8 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -318,10 +318,10 @@ Common::JSONValue *IntegrityDialog::generateJSONRequest(Common::Path gamePath, C
 		Common::File tempFile;
 		if (!tempFile.open(tempNode))
 			continue;
-		long long fileSize = tempFile.size();
+		uint64 fileSize = tempFile.size();
 		tempFile.close();
 
-		file.setVal("size", new Common::JSONValue(fileSize));
+		file.setVal("size", new Common::JSONValue((long long)fileSize));
 
 		Common::JSONArray checksums;
 		Common::StringArray checkcodes = {"md5", "md5-5000", "md5-1M", "md5-t-5000"};
@@ -352,14 +352,14 @@ Common::JSONValue *IntegrityDialog::generateJSONRequest(Common::Path gamePath, C
 }
 
 void IntegrityDialog::checksumResponseCallback(const Common::JSONValue *r) {
-	debug(r->stringify().c_str());
+	debug(3, "JSON Response: %s", r->stringify().c_str());
 	Common::String messageText = IntegrityDialog::parseJSON(r);
 	MessageDialog result(messageText);
 	result.reflowLayout();
 }
 
 void IntegrityDialog::errorCallback(const Networking::ErrorResponse &error) {
-	debug("ERROR %ld: %s", error.httpResponseCode, error.response.c_str());
+	warning("ERROR %ld: %s", error.httpResponseCode, error.response.c_str());
 }
 
 void IntegrityDialog::sendJSON() {
@@ -384,10 +384,10 @@ Common::String IntegrityDialog::parseJSON(const Common::JSONValue *response) {
 	if (responeError == -1) { // Unknown variant
 		long long fileset = responseObject.getVal("fileset")->asIntegerNumber();
 		messageText =
-			Common::String::format("Your set of game files seems to be unknown to us. If you are sure that this is a valid unknown variant, please send the following e-mail to integrity at scummvm.org \n\
+			_(Common::String::format("Your set of game files seems to be unknown to us. If you are sure that this is a valid unknown variant, please send the following e-mail to integrity at scummvm.org \n\
 		The game of fileset %lld seems to be an unknown game variant. \n\
 		The details of the game : %s, %s, %s, %s, %s",
-								   fileset, g_state->engineid.c_str(), g_state->gameid.c_str(), g_state->platform.c_str(), g_state->language.c_str(), g_state->extra.c_str());
+								   fileset, g_state->engineid.c_str(), g_state->gameid.c_str(), g_state->platform.c_str(), g_state->language.c_str(), g_state->extra.c_str()));
 
 		return messageText;
 	}
@@ -412,7 +412,7 @@ Common::String IntegrityDialog::parseJSON(const Common::JSONValue *response) {
 		messageText += Common::String::format("%s %s\n", name.c_str(), status.c_str());
 	}
 	if (messageText == "")
-		messageText += "Files all OK";
+		messageText += _("Files all OK");
 
 	return messageText;
 }


Commit: b4b86bad7dacc8bef2f21c7978bac79f6e8d208d
    https://github.com/scummvm/scummvm/commit/b4b86bad7dacc8bef2f21c7978bac79f6e8d208d
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:43+02:00

Commit Message:
GUI: Add button to copy email to clipboard

Copies message body to clipboard for unknown filesets containing fileset
id and game details

Changed paths:
    gui/integrity-dialog.cpp
    gui/integrity-dialog.h


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index 6d62a0fbcd8..5d2cce346a0 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -40,6 +40,19 @@ enum {
 	kCleanupCmd = 'DlCL',
 };
 
+struct ResultFormat {
+	bool unknown;
+	Common::String messageText;
+	Common::String emailText;
+
+	ResultFormat() {
+		unknown = 0;
+		messageText = "";
+		emailText = "";
+	}
+
+} static *g_result;
+
 struct DialogState {
 	IntegrityDialog *dialog;
 	IconProcessState state;
@@ -353,9 +366,17 @@ Common::JSONValue *IntegrityDialog::generateJSONRequest(Common::Path gamePath, C
 
 void IntegrityDialog::checksumResponseCallback(const Common::JSONValue *r) {
 	debug(3, "JSON Response: %s", r->stringify().c_str());
-	Common::String messageText = IntegrityDialog::parseJSON(r);
-	MessageDialog result(messageText);
-	result.reflowLayout();
+	IntegrityDialog::parseJSON(r);
+
+	if (!g_result->unknown) {
+		MessageDialog resultDialog(g_result->messageText);
+		resultDialog.runModal();
+	} else {
+		MessageDialog resultDialog(g_result->messageText, "OK", "Copy message to Clipboard");
+		bool copy = resultDialog.runModal();
+		if (copy == 1)
+			g_system->setTextInClipboard(g_result->emailText);
+	}
 }
 
 void IntegrityDialog::errorCallback(const Networking::ErrorResponse &error) {
@@ -363,6 +384,8 @@ void IntegrityDialog::errorCallback(const Networking::ErrorResponse &error) {
 }
 
 void IntegrityDialog::sendJSON() {
+	g_result = new ResultFormat();
+
 	auto conn = new Networking::PostRequest(g_state->endpoint,
 		new Common::Callback<IntegrityDialog, const Common::JSONValue *>(this, &IntegrityDialog::checksumResponseCallback),
 		new Common::Callback<IntegrityDialog, const Networking::ErrorResponse &>(this, &IntegrityDialog::errorCallback));
@@ -375,21 +398,27 @@ void IntegrityDialog::sendJSON() {
 	delete json;
 }
 
-Common::String IntegrityDialog::parseJSON(const Common::JSONValue *response) {
-	Common::String messageText;
-
+void IntegrityDialog::parseJSON(const Common::JSONValue *response) {
 	Common::JSONObject responseObject = response->asObject();
 	int responeError = responseObject.getVal("error")->asIntegerNumber();
 
+	Common::String messageText;
 	if (responeError == -1) { // Unknown variant
 		long long fileset = responseObject.getVal("fileset")->asIntegerNumber();
-		messageText =
-			_(Common::String::format("Your set of game files seems to be unknown to us. If you are sure that this is a valid unknown variant, please send the following e-mail to integrity at scummvm.org \n\
-		The game of fileset %lld seems to be an unknown game variant. \n\
+
+		Common::String emailText =
+			Common::String::format("The game of fileset %lld seems to be an unknown game variant. \n\
 		The details of the game : %s, %s, %s, %s, %s",
-								   fileset, g_state->engineid.c_str(), g_state->gameid.c_str(), g_state->platform.c_str(), g_state->language.c_str(), g_state->extra.c_str()));
+								   fileset, g_state->engineid.c_str(), g_state->gameid.c_str(), g_state->platform.c_str(), g_state->language.c_str(), g_state->extra.c_str());
+
+		messageText =
+			_(Common::String::format("Your set of game files seems to be unknown to us. \
+			If you are sure that this is a valid unknown variant, please send the following e-mail to integrity at scummvm.org \n%s",
+									 emailText.c_str()));
 
-		return messageText;
+		g_result->messageText += messageText;
+		g_result->emailText += emailText;
+		return;
 	}
 
 	Common::Array<int> results = Common::Array<int>(5, 0);
@@ -414,7 +443,7 @@ Common::String IntegrityDialog::parseJSON(const Common::JSONValue *response) {
 	if (messageText == "")
 		messageText += _("Files all OK");
 
-	return messageText;
+	g_result->messageText += messageText;
 }
 
 } // End of namespace GUI
diff --git a/gui/integrity-dialog.h b/gui/integrity-dialog.h
index cc4220725d8..1c0ed44499d 100644
--- a/gui/integrity-dialog.h
+++ b/gui/integrity-dialog.h
@@ -70,7 +70,7 @@ public:
 
 	static Common::Array<Common::StringArray> generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums);
 	static Common::JSONValue *generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language);
-	static Common::String parseJSON(const Common::JSONValue *response);
+	static void parseJSON(const Common::JSONValue *response);
 
 	void open() override;
 	void close() override;


Commit: d98e371ad6370c9c5714b258d2202996cc350fe8
    https://github.com/scummvm/scummvm/commit/d98e371ad6370c9c5714b258d2202996cc350fe8
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:43+02:00

Commit Message:
GUI: Update integrityDialog to not use pop-ups

Changed paths:
  A response.json
    gui/editgamedialog.cpp
    gui/integrity-dialog.cpp
    gui/integrity-dialog.h
    gui/themes/common/highres_layout.stx


diff --git a/gui/editgamedialog.cpp b/gui/editgamedialog.cpp
index 81c22ffa2c6..f9b203148f7 100644
--- a/gui/editgamedialog.cpp
+++ b/gui/editgamedialog.cpp
@@ -621,6 +621,7 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
 
 	case kCmdCheckIntegrity: {
 		IntegrityDialog wizard("http://gamesdb.sev.zone/endpoints/validate.php", _domain);
+		wizard.runModal();
 		break;
 	}
 
diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index 5d2cce346a0..f8a99401b9e 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -84,7 +84,7 @@ uint32 getDownloadingProgress() {
 	return progress;
 }
 
-IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String domain) : Dialog("GameOptions_IntegrityDialog"), _close(false) {
+IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String domain) : Dialog("GameOptions_IntegrityDialog"), CommandSender(this), _close(false) {
 
 	_backgroundType = GUI::ThemeEngine::kDialogBackgroundPlain;
 
@@ -98,13 +98,9 @@ IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String domain)
 	_progressBar->setValue(progress);
 	_progressBar->setEnabled(false);
 	_percentLabel = new StaticTextWidget(this, "GameOptions_IntegrityDialog.PercentText", Common::String::format("%u %%", progress));
+	_calcSizeLabel = new StaticTextWidget(this, "GameOptions_IntegrityDialog.DownloadSize", Common::U32String());
 	_cancelButton = new ButtonWidget(this, "GameOptions_IntegrityDialog.MainButton", _("Cancel"), Common::U32String(), kCleanupCmd);
 
-	MessageDialog alert(Common::U32String("Verifying file integrity may take a long time to complete.\nAre you sure you want to continue?"), "OK", "Cancel");
-	int result = alert.runModal();
-	if (result == 1)
-		return;
-
 	if (!g_state) {
 		g_state = new DialogState();
 		g_state->dialog = this;
@@ -202,9 +198,17 @@ void IntegrityDialog::reflowLayout() {
 	refreshWidgets();
 }
 
+Common::U32String IntegrityDialog::getSizeLabelText() {
+	const char *calculatedUnits, *totalUnits;
+	Common::String calculated = Common::getHumanReadableBytes(g_state->calculatedSize, calculatedUnits);
+	Common::String total = Common::getHumanReadableBytes(g_state->totalSize, totalUnits);
+	return Common::U32String::format(_("Calculated %s %S / %s %S"), calculated.c_str(), _(calculatedUnits).c_str(), total.c_str(), _(totalUnits).c_str());
+}
+
 void IntegrityDialog::refreshWidgets() {
 	uint32 progress = getDownloadingProgress();
 	_percentLabel->setLabel(Common::String::format("%u %%", progress));
+	_calcSizeLabel->setLabel(getSizeLabelText());
 	_progressBar->setValue(progress);
 }
 
@@ -306,6 +310,7 @@ Common::Array<Common::StringArray> IntegrityDialog::generateChecksums(Common::Pa
 		}
 	}
 
+	setState(kChecksumComplete);
 	return fileChecksums;
 }
 
@@ -368,15 +373,16 @@ void IntegrityDialog::checksumResponseCallback(const Common::JSONValue *r) {
 	debug(3, "JSON Response: %s", r->stringify().c_str());
 	IntegrityDialog::parseJSON(r);
 
-	if (!g_result->unknown) {
-		MessageDialog resultDialog(g_result->messageText);
-		resultDialog.runModal();
-	} else {
-		MessageDialog resultDialog(g_result->messageText, "OK", "Copy message to Clipboard");
-		bool copy = resultDialog.runModal();
-		if (copy == 1)
-			g_system->setTextInClipboard(g_result->emailText);
-	}
+	debug(g_result->messageText.c_str());
+	// if (!g_result->unknown) {
+	// 	MessageDialog resultDialog(g_result->messageText);
+	// 	resultDialog.runModal();
+	// } else {
+	// 	MessageDialog resultDialog(g_result->messageText, "OK", "Copy message to Clipboard");
+	// 	bool copy = resultDialog.runModal();
+	// 	if (copy == 1)
+	// 		g_system->setTextInClipboard(g_result->emailText);
+	// }
 }
 
 void IntegrityDialog::errorCallback(const Networking::ErrorResponse &error) {
diff --git a/gui/integrity-dialog.h b/gui/integrity-dialog.h
index 1c0ed44499d..af76445a8f0 100644
--- a/gui/integrity-dialog.h
+++ b/gui/integrity-dialog.h
@@ -47,15 +47,17 @@ enum IconProcessState {
 	kChecksumComplete
 };
 
-class IntegrityDialog : Dialog {
+class IntegrityDialog : public Dialog, public CommandSender {
 	StaticTextWidget *_statusText;
 	StaticTextWidget *_errorText;
 	StaticTextWidget *_percentLabel;
+	StaticTextWidget *_calcSizeLabel;
 	SliderWidget *_progressBar;
 	ButtonWidget *_cancelButton;
 
 	bool _close;
 
+	Common::U32String getSizeLabelText();
 	void refreshWidgets();
 
 public:
@@ -68,9 +70,9 @@ public:
 
 	void calculateTotalSize(Common::Path gamePath);
 
-	static Common::Array<Common::StringArray> generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums);
-	static Common::JSONValue *generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language);
-	static void parseJSON(const Common::JSONValue *response);
+	Common::Array<Common::StringArray> generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums);
+	Common::JSONValue *generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language);
+	void parseJSON(const Common::JSONValue *response);
 
 	void open() override;
 	void close() override;
diff --git a/gui/themes/common/highres_layout.stx b/gui/themes/common/highres_layout.stx
index 937686c6edb..017900f6acb 100644
--- a/gui/themes/common/highres_layout.stx
+++ b/gui/themes/common/highres_layout.stx
@@ -1850,6 +1850,9 @@
 					height = 'Globals.Line.Height'
 					textalign = 'center'
 			/>
+			<widget name = 'DownloadSize'
+					height = 'Globals.Line.Height'
+			/>
 			<space/>
 			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10'>
 				<widget name = 'MainButton'
diff --git a/response.json b/response.json
new file mode 100644
index 00000000000..f1336cd2f8d
--- /dev/null
+++ b/response.json
@@ -0,0 +1,17 @@
+{
+	"files": [
+		{
+			"status": "ok",
+			"name": "Packet.001"
+		},
+		{
+			"status": "ok",
+			"name": "drascula.doc"
+		},
+		{
+			"status": "size_mismatch",
+			"name": "readme.txt"
+		}
+	],
+	"error": 1
+}


Commit: 54d58463dcf491d7fb337f4bd1f4a8f5e04b266e
    https://github.com/scummvm/scummvm/commit/54d58463dcf491d7fb337f4bd1f4a8f5e04b266e
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:43+02:00

Commit Message:
GUI: Display results in IntegrityDialog

 - Create percentEncodeString for escaping URL strings

Changed paths:
    common/str.cpp
    common/str.h
    gui/integrity-dialog.cpp
    gui/integrity-dialog.h
    gui/themes/common/highres_layout.stx


diff --git a/common/str.cpp b/common/str.cpp
index 74e3ca368fa..b4b2cf9e164 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -821,6 +821,21 @@ String toPrintable(const String &in, bool keepNewLines) {
 	return res;
 }
 
+String percentEncodeString(const String &src) {
+	String res;
+
+	for (uint i = 0; i < src.size(); i++) {
+		char c = src[i];
+		if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') ||
+			c == '~' || c == '-' || c == '.' || c == '_')
+			res += c;
+		else
+			res += Common::String::format("%%%02X", c);
+
+		return res;
+	}
+}
+
 } // End of namespace Common
 
 // Portable implementation of stricmp / strcasecmp / strcmpi.
diff --git a/common/str.h b/common/str.h
index da6ce746189..6893d21076d 100644
--- a/common/str.h
+++ b/common/str.h
@@ -474,6 +474,11 @@ size_t strnlen(const char *src, size_t maxSize);
  */
 String toPrintable(const String &src, bool keepNewLines = true);
 
+/**
+ * Converts string with special URL characters to URL encoded (percent encoded) strings
+ */
+String percentEncodeString(const String &src);
+
 /** @} */
 
 } // End of namespace Common
diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index f8a99401b9e..74645b13e52 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -37,25 +37,29 @@
 namespace GUI {
 
 enum {
-	kCleanupCmd = 'DlCL',
+	kResponseCmd = 'IDRC',
+	kCopyEmailCmd = 'IDCE',
+	kCleanupCmd = 'IDCl'
 };
 
 struct ResultFormat {
-	bool unknown;
+	bool error;
 	Common::String messageText;
 	Common::String emailText;
+	Common::String errorText;
 
 	ResultFormat() {
-		unknown = 0;
+		error = 0;
 		messageText = "";
 		emailText = "";
+		errorText = "";
 	}
 
 } static *g_result;
 
 struct DialogState {
 	IntegrityDialog *dialog;
-	IconProcessState state;
+	ProcessState state;
 
 	int totalSize;
 	int calculatedSize;
@@ -75,7 +79,7 @@ struct DialogState {
 	}
 } static *g_state;
 
-uint32 getDownloadingProgress() {
+uint32 getCalculationProgress() {
 	if (!g_state || g_state->totalSize == 0)
 		return 0;
 
@@ -88,10 +92,14 @@ IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String domain)
 
 	_backgroundType = GUI::ThemeEngine::kDialogBackgroundPlain;
 
+	Common::U32String warningMessage = _(
+		"Verifying file integrity may take a long time to complete. Please wait...\n");
+	_warningText = new StaticTextWidget(this, "GameOptions_IntegrityDialog.WarningText", warningMessage);
+
 	_statusText = new StaticTextWidget(this, "GameOptions_IntegrityDialog.StatusText", Common::U32String::format(_("Calculating file checksums...")));
 	_errorText = new StaticTextWidget(this, "GameOptions_IntegrityDialog.ErrorText", Common::U32String(""));
 
-	uint32 progress = getDownloadingProgress();
+	uint32 progress = getCalculationProgress();
 	_progressBar = new SliderWidget(this, "GameOptions_IntegrityDialog.ProgressBar");
 	_progressBar->setMinValue(0);
 	_progressBar->setMaxValue(100);
@@ -101,6 +109,9 @@ IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String domain)
 	_calcSizeLabel = new StaticTextWidget(this, "GameOptions_IntegrityDialog.DownloadSize", Common::U32String());
 	_cancelButton = new ButtonWidget(this, "GameOptions_IntegrityDialog.MainButton", _("Cancel"), Common::U32String(), kCleanupCmd);
 
+	_copyEmailButton = new ButtonWidget(this, "GameOptions_IntegrityDialog.CopyButton", _("Copy Email to Clipboard"), Common::U32String(), kCopyEmailCmd);
+	_copyEmailButton->setVisible(false);
+
 	if (!g_state) {
 		g_state = new DialogState();
 		g_state->dialog = this;
@@ -142,7 +153,7 @@ void IntegrityDialog::close() {
 	Dialog::close();
 }
 
-void IntegrityDialog::setState(IconProcessState state) {
+void IntegrityDialog::setState(ProcessState state) {
 	g_state->state = state;
 
 	switch (state) {
@@ -155,23 +166,52 @@ void IntegrityDialog::setState(IconProcessState state) {
 
 	case kChecksumComplete:
 		_statusText->setLabel(Common::U32String::format(_("Calculation complete")));
-		_cancelButton->setVisible(false);
-		_cancelButton->setLabel(_("Cancel"));
+		_cancelButton->setVisible(true);
+		_cancelButton->setLabel(_("OK"));
 		_cancelButton->setCmd(kCleanupCmd);
 
+		// Hide all other elements
+		_statusText->setVisible(false);
+		_errorText->setVisible(false);
+		_percentLabel->setVisible(false);
+		_calcSizeLabel->setVisible(false);
+		_progressBar->setVisible(false);
+
+		break;
+
+	case kResponseReceived:
+		// Display results in _warningText
+		if (g_result->messageText != "")
+			_warningText->setLabel(g_result->messageText);
+		else
+			_warningText->setLabel(g_result->errorText);
+
+		_copyEmailButton->setVisible(true);
+		_copyEmailButton->setCmd(kCopyEmailCmd);
+
 		break;
 	}
 }
 
 void IntegrityDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
 	switch (cmd) {
+	case kResponseReceived:
+		setState(kResponseReceived);
+		break;
 	case kCleanupCmd: {
 		delete g_state;
 		g_state = nullptr;
 
+		delete g_result;
+		g_result = nullptr;
+
 		close();
 		break;
 	}
+	case kCopyEmailCmd: {
+		g_system->setTextInClipboard(g_result->emailText);
+		break;
+	}
 	default:
 		Dialog::handleCommand(sender, cmd, data);
 	}
@@ -184,7 +224,7 @@ void IntegrityDialog::handleTickle() {
 		return;
 	}
 
-	int32 progress = getDownloadingProgress();
+	int32 progress = getCalculationProgress();
 	if (_progressBar->getValue() != progress) {
 		refreshWidgets();
 		g_gui.scheduleTopDialogRedraw();
@@ -206,7 +246,7 @@ Common::U32String IntegrityDialog::getSizeLabelText() {
 }
 
 void IntegrityDialog::refreshWidgets() {
-	uint32 progress = getDownloadingProgress();
+	uint32 progress = getCalculationProgress();
 	_percentLabel->setLabel(Common::String::format("%u %%", progress));
 	_calcSizeLabel->setLabel(getSizeLabelText());
 	_progressBar->setValue(progress);
@@ -373,20 +413,16 @@ void IntegrityDialog::checksumResponseCallback(const Common::JSONValue *r) {
 	debug(3, "JSON Response: %s", r->stringify().c_str());
 	IntegrityDialog::parseJSON(r);
 
-	debug(g_result->messageText.c_str());
-	// if (!g_result->unknown) {
-	// 	MessageDialog resultDialog(g_result->messageText);
-	// 	resultDialog.runModal();
-	// } else {
-	// 	MessageDialog resultDialog(g_result->messageText, "OK", "Copy message to Clipboard");
-	// 	bool copy = resultDialog.runModal();
-	// 	if (copy == 1)
-	// 		g_system->setTextInClipboard(g_result->emailText);
-	// }
+	if (g_state->dialog)
+		g_state->dialog->sendCommand(kResponseReceived, 0);
 }
 
 void IntegrityDialog::errorCallback(const Networking::ErrorResponse &error) {
 	warning("ERROR %ld: %s", error.httpResponseCode, error.response.c_str());
+	g_result->errorText = Common::String::format("ERROR %ld: %s", error.httpResponseCode, error.response.c_str());
+
+	if (g_state->dialog)
+		g_state->dialog->sendCommand(kResponseCmd, 0);
 }
 
 void IntegrityDialog::sendJSON() {
@@ -423,7 +459,7 @@ void IntegrityDialog::parseJSON(const Common::JSONValue *response) {
 									 emailText.c_str()));
 
 		g_result->messageText += messageText;
-		g_result->emailText += emailText;
+		g_result->emailText += Common::percentEncodeString(emailText);
 		return;
 	}
 
@@ -448,6 +484,13 @@ void IntegrityDialog::parseJSON(const Common::JSONValue *response) {
 	}
 	if (messageText == "")
 		messageText += _("Files all OK");
+	else {
+		Common::String resultSummary = "\n\nTotal: ";
+		resultSummary += Common::String::format("%d OK, %d missing, %d mismatch, %d unknown files",
+												results[OK], results[MISSING], results[SIZE_MISMATCH] + results[CHECKSUM_MISMATCH], results[UNKNOWN]);
+
+		messageText += resultSummary;
+	}
 
 	g_result->messageText += messageText;
 }
diff --git a/gui/integrity-dialog.h b/gui/integrity-dialog.h
index af76445a8f0..756d2b2511c 100644
--- a/gui/integrity-dialog.h
+++ b/gui/integrity-dialog.h
@@ -41,19 +41,23 @@ enum {
 	UNKNOWN = 4
 };
 
-enum IconProcessState {
+enum ProcessState {
 	kChecksumStateNone,
 	kChecksumStateCalculating,
-	kChecksumComplete
+	kChecksumComplete,
+	kResponseReceived
 };
 
 class IntegrityDialog : public Dialog, public CommandSender {
+	StaticTextWidget *_warningText;
+
 	StaticTextWidget *_statusText;
 	StaticTextWidget *_errorText;
 	StaticTextWidget *_percentLabel;
 	StaticTextWidget *_calcSizeLabel;
 	SliderWidget *_progressBar;
 	ButtonWidget *_cancelButton;
+	ButtonWidget *_copyEmailButton;
 
 	bool _close;
 
@@ -83,7 +87,7 @@ public:
 	void setError(Common::U32String &msg);
 
 private:
-	void setState(IconProcessState state);
+	void setState(ProcessState state);
 };
 
 } // End of namespace GUI
diff --git a/gui/themes/common/highres_layout.stx b/gui/themes/common/highres_layout.stx
index 017900f6acb..a6a15e083a5 100644
--- a/gui/themes/common/highres_layout.stx
+++ b/gui/themes/common/highres_layout.stx
@@ -1836,6 +1836,9 @@
 
 	<dialog name = 'GameOptions_IntegrityDialog' overlays = 'Dialog.GameOptions' shading = 'dim'>
 		<layout type = 'vertical' padding = '16, 16, 16, 8' spacing = '8'>
+			<widget name = 'WarningText'
+					height = 'Globals.Line.Height'
+			/>
 			<widget name = 'StatusText'
 					height = 'Globals.Line.Height'
 			/>
@@ -1858,6 +1861,9 @@
 				<widget name = 'MainButton'
 						type = 'Button'
 				/>
+				<widget name = 'CopyButton'
+						type = 'Button'
+				/>
 			</layout>
 		</layout>
 	</dialog>


Commit: bb46b4fc442057d141aabe94eec2d6a3f38d4766
    https://github.com/scummvm/scummvm/commit/bb46b4fc442057d141aabe94eec2d6a3f38d4766
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:43+02:00

Commit Message:
GUI: Display results in scrollable ListWidget

Changed paths:
    gui/integrity-dialog.cpp
    gui/integrity-dialog.h
    gui/themes/common/highres_layout.stx


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index 74645b13e52..c5be3ba8f3b 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -44,13 +44,13 @@ enum {
 
 struct ResultFormat {
 	bool error;
-	Common::String messageText;
+	Common::U32StringArray messageText;
 	Common::String emailText;
 	Common::String errorText;
 
 	ResultFormat() {
 		error = 0;
-		messageText = "";
+		messageText = Common::U32StringArray();
 		emailText = "";
 		errorText = "";
 	}
@@ -95,6 +95,10 @@ IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String domain)
 	Common::U32String warningMessage = _(
 		"Verifying file integrity may take a long time to complete. Please wait...\n");
 	_warningText = new StaticTextWidget(this, "GameOptions_IntegrityDialog.WarningText", warningMessage);
+	_resultsText = new ListWidget(this, "GameOptions_IntegrityDialog.ResultsText");
+	_resultsText->setNumberingMode(kListNumberingOff);
+	_resultsText->setList({Common::U32String()});
+	_resultsText->setVisible(false);
 
 	_statusText = new StaticTextWidget(this, "GameOptions_IntegrityDialog.StatusText", Common::U32String::format(_("Calculating file checksums...")));
 	_errorText = new StaticTextWidget(this, "GameOptions_IntegrityDialog.ErrorText", Common::U32String(""));
@@ -170,7 +174,8 @@ void IntegrityDialog::setState(ProcessState state) {
 		_cancelButton->setLabel(_("OK"));
 		_cancelButton->setCmd(kCleanupCmd);
 
-		// Hide all other elements
+		// Hide all elements
+		_warningText->setVisible(false);
 		_statusText->setVisible(false);
 		_errorText->setVisible(false);
 		_percentLabel->setVisible(false);
@@ -180,14 +185,17 @@ void IntegrityDialog::setState(ProcessState state) {
 		break;
 
 	case kResponseReceived:
-		// Display results in _warningText
-		if (g_result->messageText != "")
-			_warningText->setLabel(g_result->messageText);
-		else
-			_warningText->setLabel(g_result->errorText);
+		if (g_result->messageText.size() != 0) {
+			_resultsText->setList(g_result->messageText);
+		} else
+			_resultsText->setList(Common::U32StringArray({g_result->errorText}));
+
+		if (g_result->error) {
+			_copyEmailButton->setVisible(true);
+			_copyEmailButton->setCmd(kCopyEmailCmd);
+		}
 
-		_copyEmailButton->setVisible(true);
-		_copyEmailButton->setCmd(kCopyEmailCmd);
+		_resultsText->setVisible(true);
 
 		break;
 	}
@@ -442,24 +450,32 @@ void IntegrityDialog::sendJSON() {
 
 void IntegrityDialog::parseJSON(const Common::JSONValue *response) {
 	Common::JSONObject responseObject = response->asObject();
-	int responeError = responseObject.getVal("error")->asIntegerNumber();
+	int responseError = responseObject.getVal("error")->asIntegerNumber();
+
+	Common::U32StringArray messageText = {Common::U32String("Results")};
+	if (responseError == -1) { // Unknown variant
+		g_result->error = true;
 
-	Common::String messageText;
-	if (responeError == -1) { // Unknown variant
 		long long fileset = responseObject.getVal("fileset")->asIntegerNumber();
 
 		Common::String emailText =
-			Common::String::format("The game of fileset %lld seems to be an unknown game variant. \n\
+			Common::U32String::format("The game of fileset %lld seems to be an unknown game variant. \n\
 		The details of the game : %s, %s, %s, %s, %s",
-								   fileset, g_state->engineid.c_str(), g_state->gameid.c_str(), g_state->platform.c_str(), g_state->language.c_str(), g_state->extra.c_str());
+									  fileset, g_state->engineid.c_str(), g_state->gameid.c_str(), g_state->platform.c_str(), g_state->language.c_str(), g_state->extra.c_str());
 
-		messageText =
-			_(Common::String::format("Your set of game files seems to be unknown to us. \
+		messageText.push_back(
+			_(Common::U32String::format("Your set of game files seems to be unknown to us. \
 			If you are sure that this is a valid unknown variant, please send the following e-mail to integrity at scummvm.org \n%s",
-									 emailText.c_str()));
+										emailText.c_str())));
 
-		g_result->messageText += messageText;
-		g_result->emailText += Common::percentEncodeString(emailText);
+		g_result->messageText = messageText;
+		g_result->emailText = Common::percentEncodeString(emailText);
+		return;
+
+	} else if (responseError == 2) { // Fileset is empty
+		messageText.push_back(_("The game doesn't seem to have any files. Are you sure the path is correct?"));
+
+		g_result->messageText = messageText;
 		return;
 	}
 
@@ -480,19 +496,22 @@ void IntegrityDialog::parseJSON(const Common::JSONValue *response) {
 		else if (status == "unknown")
 			results[UNKNOWN]++;
 
-		messageText += Common::String::format("%s %s\n", name.c_str(), status.c_str());
+		messageText.push_back(Common::String::format("%s %s\n", name.c_str(), status.c_str()));
 	}
-	if (messageText == "")
-		messageText += _("Files all OK");
+
+	if (messageText.size() == 0)
+		messageText.push_back(_("Files all OK"));
 	else {
+		g_result->error = true;
+
 		Common::String resultSummary = "\n\nTotal: ";
-		resultSummary += Common::String::format("%d OK, %d missing, %d mismatch, %d unknown files",
-												results[OK], results[MISSING], results[SIZE_MISMATCH] + results[CHECKSUM_MISMATCH], results[UNKNOWN]);
+		resultSummary += Common::U32String::format("%d OK, %d missing, %d mismatch, %d unknown files",
+												   results[OK], results[MISSING], results[SIZE_MISMATCH] + results[CHECKSUM_MISMATCH], results[UNKNOWN]);
 
-		messageText += resultSummary;
+		messageText.push_back(resultSummary);
 	}
 
-	g_result->messageText += messageText;
+	g_result->messageText = messageText;
 }
 
 } // End of namespace GUI
diff --git a/gui/integrity-dialog.h b/gui/integrity-dialog.h
index 756d2b2511c..7fc4326a9b7 100644
--- a/gui/integrity-dialog.h
+++ b/gui/integrity-dialog.h
@@ -30,6 +30,7 @@
 
 #include "gui/dialog.h"
 #include "gui/widget.h"
+#include "gui/widgets/list.h"
 
 namespace GUI {
 
@@ -50,6 +51,7 @@ enum ProcessState {
 
 class IntegrityDialog : public Dialog, public CommandSender {
 	StaticTextWidget *_warningText;
+	ListWidget *_resultsText;
 
 	StaticTextWidget *_statusText;
 	StaticTextWidget *_errorText;
diff --git a/gui/themes/common/highres_layout.stx b/gui/themes/common/highres_layout.stx
index a6a15e083a5..604fd6a52dc 100644
--- a/gui/themes/common/highres_layout.stx
+++ b/gui/themes/common/highres_layout.stx
@@ -1839,6 +1839,9 @@
 			<widget name = 'WarningText'
 					height = 'Globals.Line.Height'
 			/>
+			<widget name = 'ResultsText'
+					height = '250'
+			/>
 			<widget name = 'StatusText'
 					height = 'Globals.Line.Height'
 			/>


Commit: b039adeb1f8724ca81f7b38881773aa17db7dd1f
    https://github.com/scummvm/scummvm/commit/b039adeb1f8724ca81f7b38881773aa17db7dd1f
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:43+02:00

Commit Message:
GUI: Update email formatting in integrity dialog

Changed paths:
    gui/integrity-dialog.cpp


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index c5be3ba8f3b..1b4845dccc4 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -46,12 +46,14 @@ struct ResultFormat {
 	bool error;
 	Common::U32StringArray messageText;
 	Common::String emailText;
+	Common::String emailLink;
 	Common::String errorText;
 
 	ResultFormat() {
 		error = 0;
 		messageText = Common::U32StringArray();
 		emailText = "";
+		emailLink = "";
 		errorText = "";
 	}
 
@@ -456,20 +458,37 @@ void IntegrityDialog::parseJSON(const Common::JSONValue *response) {
 	if (responseError == -1) { // Unknown variant
 		g_result->error = true;
 
-		long long fileset = responseObject.getVal("fileset")->asIntegerNumber();
+		Common::String fileset = responseObject.getVal("fileset")->asString();
 
 		Common::String emailText =
-			Common::U32String::format("The game of fileset %lld seems to be an unknown game variant. \n\
-		The details of the game : %s, %s, %s, %s, %s",
-									  fileset, g_state->engineid.c_str(), g_state->gameid.c_str(), g_state->platform.c_str(), g_state->language.c_str(), g_state->extra.c_str());
-
-		messageText.push_back(
-			_(Common::U32String::format("Your set of game files seems to be unknown to us. \
-			If you are sure that this is a valid unknown variant, please send the following e-mail to integrity at scummvm.org \n%s",
-										emailText.c_str())));
+			Common::String::format("To: integrity at scummvm.org\
+\
+Subject: Unknown game variant fileset %s\
+\
+Fileset %s is a new or unknown fileset, the game details are:\
+%s %s %s\
+\
+Here describe the details of your release:\
+",
+								   fileset.c_str(), fileset.c_str(), g_state->gameid.c_str(), g_state->platform.c_str(), g_state->language.c_str());
+
+		Common::String emailLink = Common::String::format("mailto:integrity at scummvm.org?subject=Subject: Unknown game variant fileset %s&body=%s!", fileset.c_str(), emailText.c_str());
+
+		messageText.push_back(_("Your set of game files seems to be unknown to us."));
+		messageText.push_back(_("If you are sure that this is a valid unknown variant, please send the following e-mail to integrity at scummvm.org"));
+		messageText.push_back(_(""));
+		messageText.push_back(Common::U32String("To: integrity at scummvm.org"));
+		messageText.push_back(_(""));
+		messageText.push_back(Common::U32String::format("Subject: Unknown game variant fileset %s", fileset.c_str()));
+		messageText.push_back(_(""));
+		messageText.push_back(Common::U32String::format("Fileset %s is a new or unknown fileset, the game details are:", fileset.c_str()));
+		messageText.push_back(Common::U32String::format("%s %s %s", g_state->gameid.c_str(), g_state->platform.c_str(), g_state->language.c_str()));
+		messageText.push_back(_(""));
+		messageText.push_back(Common::U32String("Here describe the details of your release:"));
 
 		g_result->messageText = messageText;
-		g_result->emailText = Common::percentEncodeString(emailText);
+		g_result->emailText = emailText;
+		g_result->emailLink = emailLink;
 		return;
 
 	} else if (responseError == 2) { // Fileset is empty
@@ -493,7 +512,7 @@ void IntegrityDialog::parseJSON(const Common::JSONValue *response) {
 			results[CHECKSUM_MISMATCH]++;
 		else if (status == "size_mismatch")
 			results[SIZE_MISMATCH]++;
-		else if (status == "unknown")
+		else if (status == "unknown_file")
 			results[UNKNOWN]++;
 
 		messageText.push_back(Common::String::format("%s %s\n", name.c_str(), status.c_str()));


Commit: 6dc195020744061d707088c29fd5835f2b65a314
    https://github.com/scummvm/scummvm/commit/6dc195020744061d707088c29fd5835f2b65a314
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:43+02:00

Commit Message:
COMMON: Fix percentEncodeString()

Changed paths:
    common/str.cpp


diff --git a/common/str.cpp b/common/str.cpp
index b4b2cf9e164..122989a30f1 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -831,9 +831,9 @@ String percentEncodeString(const String &src) {
 			res += c;
 		else
 			res += Common::String::format("%%%02X", c);
-
-		return res;
 	}
+
+	return res;
 }
 
 } // End of namespace Common


Commit: d9fb4421f22e790cb216982f8428f4cdadb92d5d
    https://github.com/scummvm/scummvm/commit/d9fb4421f22e790cb216982f8428f4cdadb92d5d
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:43+02:00

Commit Message:
GUI: Fix relativePath in integrity JSON request

Also, results size is reduced

Changed paths:
    gui/integrity-dialog.cpp
    gui/themes/common/highres_layout.stx


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index 1b4845dccc4..ff0261068cb 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -192,7 +192,7 @@ void IntegrityDialog::setState(ProcessState state) {
 		} else
 			_resultsText->setList(Common::U32StringArray({g_result->errorText}));
 
-		if (g_result->error) {
+		if (g_result->error != 0) {
 			_copyEmailButton->setVisible(true);
 			_copyEmailButton->setCmd(kCopyEmailCmd);
 		}
diff --git a/gui/themes/common/highres_layout.stx b/gui/themes/common/highres_layout.stx
index 604fd6a52dc..33cef4ba4cc 100644
--- a/gui/themes/common/highres_layout.stx
+++ b/gui/themes/common/highres_layout.stx
@@ -1836,12 +1836,12 @@
 
 	<dialog name = 'GameOptions_IntegrityDialog' overlays = 'Dialog.GameOptions' shading = 'dim'>
 		<layout type = 'vertical' padding = '16, 16, 16, 8' spacing = '8'>
+			<widget name = 'ResultsText'
+					height = '150'
+			/>
 			<widget name = 'WarningText'
 					height = 'Globals.Line.Height'
 			/>
-			<widget name = 'ResultsText'
-					height = '250'
-			/>
 			<widget name = 'StatusText'
 					height = 'Globals.Line.Height'
 			/>


Commit: 10211e6a2ea42655e99aaff0d5a9f536919a3067
    https://github.com/scummvm/scummvm/commit/10211e6a2ea42655e99aaff0d5a9f536919a3067
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:43+02:00

Commit Message:
GUI: Update identifiers to avoid namespace clashes

Changed paths:
    gui/integrity-dialog.cpp


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index ff0261068cb..9d717c06454 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -59,7 +59,7 @@ struct ResultFormat {
 
 } static *g_result;
 
-struct DialogState {
+struct ChecksumDialogState {
 	IntegrityDialog *dialog;
 	ProcessState state;
 
@@ -74,18 +74,18 @@ struct DialogState {
 	Common::String platform;
 	Common::String language;
 
-	DialogState() {
+	ChecksumDialogState() {
 		state = kChecksumStateNone;
 		totalSize = calculatedSize = 0;
 		dialog = nullptr;
 	}
-} static *g_state;
+} static *g_checksum_state;
 
 uint32 getCalculationProgress() {
-	if (!g_state || g_state->totalSize == 0)
+	if (!g_checksum_state || g_checksum_state->totalSize == 0)
 		return 0;
 
-	uint32 progress = (uint32)(100 * ((double)g_state->calculatedSize / (double)g_state->totalSize));
+	uint32 progress = (uint32)(100 * ((double)g_checksum_state->calculatedSize / (double)g_checksum_state->totalSize));
 
 	return progress;
 }
@@ -118,27 +118,27 @@ IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String domain)
 	_copyEmailButton = new ButtonWidget(this, "GameOptions_IntegrityDialog.CopyButton", _("Copy Email to Clipboard"), Common::U32String(), kCopyEmailCmd);
 	_copyEmailButton->setVisible(false);
 
-	if (!g_state) {
-		g_state = new DialogState();
-		g_state->dialog = this;
+	if (!g_checksum_state) {
+		g_checksum_state = new ChecksumDialogState();
+		g_checksum_state->dialog = this;
 
 		setState(kChecksumStateCalculating);
 		refreshWidgets();
 
-		g_state->endpoint = endpoint;
-		g_state->gamePath = Common::Path(ConfMan.get("path", domain));
-		g_state->gameid = ConfMan.get("gameid", domain);
-		g_state->engineid = ConfMan.get("engineid", domain);
-		g_state->extra = ConfMan.get("extra", domain);
-		g_state->platform = ConfMan.get("platform", domain);
-		g_state->language = ConfMan.get("language", domain);
-		calculateTotalSize(g_state->gamePath);
+		g_checksum_state->endpoint = endpoint;
+		g_checksum_state->gamePath = Common::Path(ConfMan.get("path", domain));
+		g_checksum_state->gameid = ConfMan.get("gameid", domain);
+		g_checksum_state->engineid = ConfMan.get("engineid", domain);
+		g_checksum_state->extra = ConfMan.get("extra", domain);
+		g_checksum_state->platform = ConfMan.get("platform", domain);
+		g_checksum_state->language = ConfMan.get("language", domain);
+		calculateTotalSize(g_checksum_state->gamePath);
 
 		sendJSON();
 	} else {
-		g_state->dialog = this;
+		g_checksum_state->dialog = this;
 
-		setState(g_state->state);
+		setState(g_checksum_state->state);
 		refreshWidgets();
 	}
 }
@@ -153,14 +153,14 @@ void IntegrityDialog::open() {
 }
 
 void IntegrityDialog::close() {
-	if (g_state)
-		g_state->dialog = nullptr;
+	if (g_checksum_state)
+		g_checksum_state->dialog = nullptr;
 
 	Dialog::close();
 }
 
 void IntegrityDialog::setState(ProcessState state) {
-	g_state->state = state;
+	g_checksum_state->state = state;
 
 	switch (state) {
 	case kChecksumStateNone:
@@ -209,8 +209,8 @@ void IntegrityDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 da
 		setState(kResponseReceived);
 		break;
 	case kCleanupCmd: {
-		delete g_state;
-		g_state = nullptr;
+		delete g_checksum_state;
+		g_checksum_state = nullptr;
 
 		delete g_result;
 		g_result = nullptr;
@@ -250,8 +250,8 @@ void IntegrityDialog::reflowLayout() {
 
 Common::U32String IntegrityDialog::getSizeLabelText() {
 	const char *calculatedUnits, *totalUnits;
-	Common::String calculated = Common::getHumanReadableBytes(g_state->calculatedSize, calculatedUnits);
-	Common::String total = Common::getHumanReadableBytes(g_state->totalSize, totalUnits);
+	Common::String calculated = Common::getHumanReadableBytes(g_checksum_state->calculatedSize, calculatedUnits);
+	Common::String total = Common::getHumanReadableBytes(g_checksum_state->totalSize, totalUnits);
 	return Common::U32String::format(_("Calculated %s %S / %s %S"), calculated.c_str(), _(calculatedUnits).c_str(), total.c_str(), _(totalUnits).c_str());
 }
 
@@ -293,7 +293,7 @@ void IntegrityDialog::calculateTotalSize(Common::Path gamePath) {
 			if (!file.open(entry))
 				continue;
 
-			g_state->totalSize += file.size();
+			g_checksum_state->totalSize += file.size();
 		}
 	}
 }
@@ -334,7 +334,7 @@ Common::Array<Common::StringArray> IntegrityDialog::generateChecksums(Common::Pa
 				fileStream->seek(-5000, SEEK_END);
 				fileChecksum.push_back(Common::computeStreamMD5AsString(*(fileStream)).c_str());
 
-				g_state->calculatedSize += fileStream->size();
+				g_checksum_state->calculatedSize += fileStream->size();
 
 				fileChecksums.push_back(fileChecksum);
 			}
@@ -353,7 +353,7 @@ Common::Array<Common::StringArray> IntegrityDialog::generateChecksums(Common::Pa
 			file.seek(-5000, SEEK_END);
 			fileChecksum.push_back(Common::computeStreamMD5AsString(file).c_str());
 
-			g_state->calculatedSize += file.size();
+			g_checksum_state->calculatedSize += file.size();
 
 			file.close();
 			fileChecksums.push_back(fileChecksum);
@@ -423,27 +423,27 @@ void IntegrityDialog::checksumResponseCallback(const Common::JSONValue *r) {
 	debug(3, "JSON Response: %s", r->stringify().c_str());
 	IntegrityDialog::parseJSON(r);
 
-	if (g_state->dialog)
-		g_state->dialog->sendCommand(kResponseReceived, 0);
+	if (g_checksum_state->dialog)
+		g_checksum_state->dialog->sendCommand(kResponseReceived, 0);
 }
 
 void IntegrityDialog::errorCallback(const Networking::ErrorResponse &error) {
 	warning("ERROR %ld: %s", error.httpResponseCode, error.response.c_str());
 	g_result->errorText = Common::String::format("ERROR %ld: %s", error.httpResponseCode, error.response.c_str());
 
-	if (g_state->dialog)
-		g_state->dialog->sendCommand(kResponseCmd, 0);
+	if (g_checksum_state->dialog)
+		g_checksum_state->dialog->sendCommand(kResponseCmd, 0);
 }
 
 void IntegrityDialog::sendJSON() {
 	g_result = new ResultFormat();
 
-	auto conn = new Networking::PostRequest(g_state->endpoint,
+	auto conn = new Networking::PostRequest(g_checksum_state->endpoint,
 		new Common::Callback<IntegrityDialog, const Common::JSONValue *>(this, &IntegrityDialog::checksumResponseCallback),
 		new Common::Callback<IntegrityDialog, const Networking::ErrorResponse &>(this, &IntegrityDialog::errorCallback));
 
 	Common::JSONValue *json = generateJSONRequest(
-		g_state->gamePath, g_state->gameid, g_state->engineid, g_state->extra, g_state->platform, g_state->language);
+		g_checksum_state->gamePath, g_checksum_state->gameid, g_checksum_state->engineid, g_checksum_state->extra, g_checksum_state->platform, g_checksum_state->language);
 	conn->setJSONData(json);
 	conn->setContentType("application/json");
 	conn->start();
@@ -470,7 +470,7 @@ Fileset %s is a new or unknown fileset, the game details are:\
 \
 Here describe the details of your release:\
 ",
-								   fileset.c_str(), fileset.c_str(), g_state->gameid.c_str(), g_state->platform.c_str(), g_state->language.c_str());
+								   fileset.c_str(), fileset.c_str(), g_checksum_state->gameid.c_str(), g_checksum_state->platform.c_str(), g_checksum_state->language.c_str());
 
 		Common::String emailLink = Common::String::format("mailto:integrity at scummvm.org?subject=Subject: Unknown game variant fileset %s&body=%s!", fileset.c_str(), emailText.c_str());
 
@@ -482,7 +482,7 @@ Here describe the details of your release:\
 		messageText.push_back(Common::U32String::format("Subject: Unknown game variant fileset %s", fileset.c_str()));
 		messageText.push_back(_(""));
 		messageText.push_back(Common::U32String::format("Fileset %s is a new or unknown fileset, the game details are:", fileset.c_str()));
-		messageText.push_back(Common::U32String::format("%s %s %s", g_state->gameid.c_str(), g_state->platform.c_str(), g_state->language.c_str()));
+		messageText.push_back(Common::U32String::format("%s %s %s", g_checksum_state->gameid.c_str(), g_checksum_state->platform.c_str(), g_checksum_state->language.c_str()));
 		messageText.push_back(_(""));
 		messageText.push_back(Common::U32String("Here describe the details of your release:"));
 


Commit: 18a47da6ce48aa27ea872d86468997d09446052f
    https://github.com/scummvm/scummvm/commit/18a47da6ce48aa27ea872d86468997d09446052f
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:43+02:00

Commit Message:
GUI: User filesets dialog can launch email client

Changed paths:
    gui/integrity-dialog.cpp


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index 9d717c06454..29a4b83f796 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -45,14 +45,12 @@ enum {
 struct ResultFormat {
 	bool error;
 	Common::U32StringArray messageText;
-	Common::String emailText;
 	Common::String emailLink;
 	Common::String errorText;
 
 	ResultFormat() {
 		error = 0;
 		messageText = Common::U32StringArray();
-		emailText = "";
 		emailLink = "";
 		errorText = "";
 	}
@@ -115,7 +113,7 @@ IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String domain)
 	_calcSizeLabel = new StaticTextWidget(this, "GameOptions_IntegrityDialog.DownloadSize", Common::U32String());
 	_cancelButton = new ButtonWidget(this, "GameOptions_IntegrityDialog.MainButton", _("Cancel"), Common::U32String(), kCleanupCmd);
 
-	_copyEmailButton = new ButtonWidget(this, "GameOptions_IntegrityDialog.CopyButton", _("Copy Email to Clipboard"), Common::U32String(), kCopyEmailCmd);
+	_copyEmailButton = new ButtonWidget(this, "GameOptions_IntegrityDialog.CopyButton", _("Launch Email Client"), Common::U32String(), kCopyEmailCmd);
 	_copyEmailButton->setVisible(false);
 
 	if (!g_checksum_state) {
@@ -219,7 +217,7 @@ void IntegrityDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 da
 		break;
 	}
 	case kCopyEmailCmd: {
-		g_system->setTextInClipboard(g_result->emailText);
+		g_system->openUrl(g_result->emailLink);
 		break;
 	}
 	default:
@@ -461,15 +459,7 @@ void IntegrityDialog::parseJSON(const Common::JSONValue *response) {
 		Common::String fileset = responseObject.getVal("fileset")->asString();
 
 		Common::String emailText =
-			Common::String::format("To: integrity at scummvm.org\
-\
-Subject: Unknown game variant fileset %s\
-\
-Fileset %s is a new or unknown fileset, the game details are:\
-%s %s %s\
-\
-Here describe the details of your release:\
-",
+			Common::String::format("Fileset %s is a new or unknown fileset, the game details are:\n%s %s %s\n\nHere describe the details of your release:\n",
 								   fileset.c_str(), fileset.c_str(), g_checksum_state->gameid.c_str(), g_checksum_state->platform.c_str(), g_checksum_state->language.c_str());
 
 		Common::String emailLink = Common::String::format("mailto:integrity at scummvm.org?subject=Subject: Unknown game variant fileset %s&body=%s!", fileset.c_str(), emailText.c_str());
@@ -487,7 +477,6 @@ Here describe the details of your release:\
 		messageText.push_back(Common::U32String("Here describe the details of your release:"));
 
 		g_result->messageText = messageText;
-		g_result->emailText = emailText;
 		g_result->emailLink = emailLink;
 		return;
 


Commit: 2d7559c7727e884aceeae007ebe6b48c5c5f5016
    https://github.com/scummvm/scummvm/commit/2d7559c7727e884aceeae007ebe6b48c5c5f5016
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:43+02:00

Commit Message:
GUI: Calculate checksums of rsrc forks correctly

Changed paths:
    gui/integrity-dialog.cpp


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index 29a4b83f796..bd39fdbaee3 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -318,23 +318,38 @@ Common::Array<Common::StringArray> IntegrityDialog::generateChecksums(Common::Pa
 		else {
 			const Common::Path filename(entry.getPath());
 			auto macFile = Common::MacResManager();
-			if (macFile.openFileOrDataFork(filename)) {
-				auto originalStream = macFile.openFileOrDataFork(filename);
-				auto fileStream = originalStream;
+			if (macFile.open(filename)) {
+				auto fileStream = macFile.openFileOrDataFork(filename);
+				Common::SeekableReadStream *dataForkStream;
+				if (macFile.isMacBinary(*fileStream))
+					dataForkStream = macFile.openDataForkFromMacBinary(fileStream);
+				else
+					dataForkStream = fileStream;
 
 				Common::Array<Common::String> fileChecksum = {filename.toString()};
+
+				// Data fork
 				// Various checksizes
 				for (auto size : {0, 5000, 1024 * 1024}) {
-					fileChecksum.push_back(Common::computeStreamMD5AsString(*(fileStream), size).c_str());
-					fileStream->seek(0);
+					fileChecksum.push_back(Common::computeStreamMD5AsString(*dataForkStream, size).c_str());
+					dataForkStream->seek(0);
 				}
 				// Tail checksums with checksize 5000
-				fileStream->seek(-5000, SEEK_END);
-				fileChecksum.push_back(Common::computeStreamMD5AsString(*(fileStream)).c_str());
+				dataForkStream->seek(-5000, SEEK_END);
+				fileChecksum.push_back(Common::computeStreamMD5AsString(*dataForkStream).c_str());
+
+				// Resource fork
+				if (macFile.hasResFork()) {
+					// Various checksizes
+					for (auto size : {0, 5000, 1024 * 1024}) {
+						fileChecksum.push_back(macFile.computeResForkMD5AsString(size).c_str());
+					}
+					// Tail checksums with checksize 5000
+					fileChecksum.push_back(macFile.computeResForkMD5AsString(5000, true).c_str());
+					fileChecksums.push_back(fileChecksum);
+				}
 
 				g_checksum_state->calculatedSize += fileStream->size();
-
-				fileChecksums.push_back(fileChecksum);
 			}
 
 			Common::File file;
@@ -390,7 +405,11 @@ Common::JSONValue *IntegrityDialog::generateJSONRequest(Common::Path gamePath, C
 		file.setVal("size", new Common::JSONValue((long long)fileSize));
 
 		Common::JSONArray checksums;
-		Common::StringArray checkcodes = {"md5", "md5-5000", "md5-1M", "md5-t-5000"};
+		Common::StringArray checkcodes;
+		if (fileChecksum.size() == 8)
+			checkcodes = {"md5-d", "md5-d-5000", "md5-d-1M", "md5-dt-5000", "md5-r", "md5-r-5000", "md5-r-1M", "md5-rt-5000"};
+		else
+			checkcodes = {"md5", "md5-5000", "md5-1M", "md5-t-5000"};
 
 		int index = -1;
 		for (Common::String val : fileChecksum) {


Commit: 9b1fb61eee887e149e2cdc1cdeb4c8ea3a64d9f7
    https://github.com/scummvm/scummvm/commit/9b1fb61eee887e149e2cdc1cdeb4c8ea3a64d9f7
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:43+02:00

Commit Message:
GUI: Percent encode mailto link in IntegrityDialog

Changed paths:
    gui/integrity-dialog.cpp


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index bd39fdbaee3..ffb6fcefb0b 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -477,11 +477,11 @@ void IntegrityDialog::parseJSON(const Common::JSONValue *response) {
 
 		Common::String fileset = responseObject.getVal("fileset")->asString();
 
-		Common::String emailText =
+		Common::String emailText = 
 			Common::String::format("Fileset %s is a new or unknown fileset, the game details are:\n%s %s %s\n\nHere describe the details of your release:\n",
 								   fileset.c_str(), fileset.c_str(), g_checksum_state->gameid.c_str(), g_checksum_state->platform.c_str(), g_checksum_state->language.c_str());
 
-		Common::String emailLink = Common::String::format("mailto:integrity at scummvm.org?subject=Subject: Unknown game variant fileset %s&body=%s!", fileset.c_str(), emailText.c_str());
+		Common::String emailLink = Common::percentEncodeString(Common::String::format("mailto:integrity at scummvm.org?subject=Subject: Unknown game variant fileset %s&body=%s!", fileset.c_str(), emailText.c_str()));
 
 		messageText.push_back(_("Your set of game files seems to be unknown to us."));
 		messageText.push_back(_("If you are sure that this is a valid unknown variant, please send the following e-mail to integrity at scummvm.org"));


Commit: 8a986d51dffe046d14a289396bb96e94a07d4482
    https://github.com/scummvm/scummvm/commit/8a986d51dffe046d14a289396bb96e94a07d4482
Author: Abhinav Chennubhotla (51199011+PhoenixFlame101 at users.noreply.github.com)
Date: 2024-06-14T01:15:44+02:00

Commit Message:
GUI: Add no_metadata error code to IntegrityDialog

Changed paths:
    gui/integrity-dialog.cpp


diff --git a/gui/integrity-dialog.cpp b/gui/integrity-dialog.cpp
index ffb6fcefb0b..3f571960359 100644
--- a/gui/integrity-dialog.cpp
+++ b/gui/integrity-dialog.cpp
@@ -477,9 +477,9 @@ void IntegrityDialog::parseJSON(const Common::JSONValue *response) {
 
 		Common::String fileset = responseObject.getVal("fileset")->asString();
 
-		Common::String emailText = 
+		Common::String emailText =
 			Common::String::format("Fileset %s is a new or unknown fileset, the game details are:\n%s %s %s\n\nHere describe the details of your release:\n",
-								   fileset.c_str(), fileset.c_str(), g_checksum_state->gameid.c_str(), g_checksum_state->platform.c_str(), g_checksum_state->language.c_str());
+								   fileset.c_str(), g_checksum_state->gameid.c_str(), g_checksum_state->platform.c_str(), g_checksum_state->language.c_str());
 
 		Common::String emailLink = Common::percentEncodeString(Common::String::format("mailto:integrity at scummvm.org?subject=Subject: Unknown game variant fileset %s&body=%s!", fileset.c_str(), emailText.c_str()));
 
@@ -502,6 +502,11 @@ void IntegrityDialog::parseJSON(const Common::JSONValue *response) {
 	} else if (responseError == 2) { // Fileset is empty
 		messageText.push_back(_("The game doesn't seem to have any files. Are you sure the path is correct?"));
 
+		g_result->messageText = messageText;
+		return;
+	} else if (responseError == 3) { // Game does not have any metadata
+		messageText.push_back(_("The game doesn't seem to have any metadata associated with it, so it is unable to be matched. Please fill in the correct metadata for the game."));
+
 		g_result->messageText = messageText;
 		return;
 	}


Commit: 228b19dafdaa9b8961fa17b258d385f116656978
    https://github.com/scummvm/scummvm/commit/228b19dafdaa9b8961fa17b258d385f116656978
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2024-06-14T01:15:44+02:00

Commit Message:
GUI: Hid integrity checker behind config option

Changed paths:
    gui/editgamedialog.cpp
    gui/editgamedialog.h


diff --git a/gui/editgamedialog.cpp b/gui/editgamedialog.cpp
index f9b203148f7..4e55d54effa 100644
--- a/gui/editgamedialog.cpp
+++ b/gui/editgamedialog.cpp
@@ -285,7 +285,8 @@ EditGameDialog::EditGameDialog(const Common::String &domain)
 	// in the small version of the GUI.
 
 	// GUI: Check integrity button
-	_checkIntegrityButton = new ButtonWidget(tab, "GameOptions_Paths.Checkintegrity", _("Check Integrity"), _("Perform integrity check for all game files"), kCmdCheckIntegrity);
+	if (ConfMan.hasKey("enable_integrity_checking", Common::ConfigManager::kApplicationDomain))
+		new ButtonWidget(tab, "GameOptions_Paths.Checkintegrity", _("Check Integrity"), _("Perform integrity check for all game files"), kCmdCheckIntegrity);
 
 	// GUI:  Button + Label for the game path
 	if (!g_gui.useLowResGUI())
diff --git a/gui/editgamedialog.h b/gui/editgamedialog.h
index 73bc28ca5f7..b02142bfef6 100644
--- a/gui/editgamedialog.h
+++ b/gui/editgamedialog.h
@@ -77,7 +77,6 @@ protected:
 	PathWidget *_savePathWidget;
 	ButtonWidget *_extraPathClearButton;
 	ButtonWidget *_savePathClearButton;
-	ButtonWidget *_checkIntegrityButton;
 
 	StaticTextWidget *_langPopUpDesc;
 	PopUpWidget *_langPopUp;


Commit: 154ba3b43d4dedb4e4b6e69281640e5215e61130
    https://github.com/scummvm/scummvm/commit/154ba3b43d4dedb4e4b6e69281640e5215e61130
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2024-06-14T01:18:46+02:00

Commit Message:
GUI: Added integrity dialog to all themes and bumped theme version

Changed paths:
    gui/ThemeEngine.h
    gui/themes/common/highres_layout.stx
    gui/themes/common/lowres_layout.stx
    gui/themes/residualvm/THEMERC
    gui/themes/scummclassic/THEMERC
    gui/themes/scummclassic/classic_layout.stx
    gui/themes/scummclassic/classic_layout_lowres.stx
    gui/themes/scummmodern/THEMERC
    gui/themes/scummremastered/THEMERC


diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index eac49fab6c3..2c3159f8195 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -36,7 +36,7 @@
 #include "graphics/pixelformat.h"
 
 
-#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.9.17"
+#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.9.18"
 
 class OSystem;
 
diff --git a/gui/themes/common/highres_layout.stx b/gui/themes/common/highres_layout.stx
index 33cef4ba4cc..63830d8c2a5 100644
--- a/gui/themes/common/highres_layout.stx
+++ b/gui/themes/common/highres_layout.stx
@@ -1834,43 +1834,6 @@
 		</layout>
 	</dialog>
 
-	<dialog name = 'GameOptions_IntegrityDialog' overlays = 'Dialog.GameOptions' shading = 'dim'>
-		<layout type = 'vertical' padding = '16, 16, 16, 8' spacing = '8'>
-			<widget name = 'ResultsText'
-					height = '150'
-			/>
-			<widget name = 'WarningText'
-					height = 'Globals.Line.Height'
-			/>
-			<widget name = 'StatusText'
-					height = 'Globals.Line.Height'
-			/>
-			<widget name = 'ErrorText'
-					height = 'Globals.Line.Height'
-			/>
-			<widget name = 'ProgressBar'
-					height = 'Globals.Button.Height'
-			/>
-			<space size = '1'/>
-			<widget name = 'PercentText'
-					height = 'Globals.Line.Height'
-					textalign = 'center'
-			/>
-			<widget name = 'DownloadSize'
-					height = 'Globals.Line.Height'
-			/>
-			<space/>
-			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10'>
-				<widget name = 'MainButton'
-						type = 'Button'
-				/>
-				<widget name = 'CopyButton'
-						type = 'Button'
-				/>
-			</layout>
-		</layout>
-	</dialog>
-
 	<dialog name = 'GlobalMenu' overlays = 'screen_center'>
 		<layout type = 'vertical' padding = '16, 16, 16, 16' align = 'center'>
 			<widget name = 'Logo'
@@ -2864,4 +2827,41 @@
 		</layout>
 	</dialog>
 
+	<dialog name = 'GameOptions_IntegrityDialog' overlays = 'Dialog.GameOptions' shading = 'dim'>
+		<layout type = 'vertical' padding = '16, 16, 16, 8' spacing = '8'>
+			<widget name = 'ResultsText'
+					height = '150'
+			/>
+			<widget name = 'WarningText'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'StatusText'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'ErrorText'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'ProgressBar'
+					height = 'Globals.Button.Height'
+			/>
+			<space size = '1'/>
+			<widget name = 'PercentText'
+					height = 'Globals.Line.Height'
+					textalign = 'center'
+			/>
+			<widget name = 'DownloadSize'
+					height = 'Globals.Line.Height'
+			/>
+			<space/>
+			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10'>
+				<widget name = 'MainButton'
+						type = 'Button'
+				/>
+				<widget name = 'CopyButton'
+						type = 'Button'
+				/>
+			</layout>
+		</layout>
+	</dialog>
+
 </layout_info>
diff --git a/gui/themes/common/lowres_layout.stx b/gui/themes/common/lowres_layout.stx
index d573400c4e6..df14cc40717 100644
--- a/gui/themes/common/lowres_layout.stx
+++ b/gui/themes/common/lowres_layout.stx
@@ -2642,4 +2642,41 @@
 		</layout>
 	</dialog>
 
+	<dialog name = 'GameOptions_IntegrityDialog' overlays = 'Dialog.GameOptions' shading = 'dim'>
+		<layout type = 'vertical' padding = '8, 8, 8, 8'>
+			<widget name = 'ResultsText'
+					height = '150'
+			/>
+			<widget name = 'WarningText'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'StatusText'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'ErrorText'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'ProgressBar'
+					height = 'Globals.Button.Height'
+			/>
+			<space size = '1'/>
+			<widget name = 'PercentText'
+					height = 'Globals.Line.Height'
+					textalign = 'center'
+			/>
+			<widget name = 'DownloadSize'
+					height = 'Globals.Line.Height'
+			/>
+			<space/>
+			<layout type = 'horizontal' padding = '8, 8, 8, 8'>
+				<widget name = 'MainButton'
+						type = 'Button'
+				/>
+				<widget name = 'CopyButton'
+						type = 'Button'
+				/>
+			</layout>
+		</layout>
+	</dialog>
+
 </layout_info>
diff --git a/gui/themes/residualvm/THEMERC b/gui/themes/residualvm/THEMERC
index c626af49461..928b6db066d 100644
--- a/gui/themes/residualvm/THEMERC
+++ b/gui/themes/residualvm/THEMERC
@@ -1,3 +1,3 @@
-[SCUMMVM_STX0.9.17:ResidualVM Modern Theme Remastered:No Author]
+[SCUMMVM_STX0.9.18:ResidualVM Modern Theme Remastered:No Author]
 %using ../common
 %using ../common-svg
diff --git a/gui/themes/scummclassic/THEMERC b/gui/themes/scummclassic/THEMERC
index 6f052dd0a38..92cc294651e 100644
--- a/gui/themes/scummclassic/THEMERC
+++ b/gui/themes/scummclassic/THEMERC
@@ -1 +1 @@
-[SCUMMVM_STX0.9.17:ScummVM Classic Theme:No Author]
+[SCUMMVM_STX0.9.18:ScummVM Classic Theme:No Author]
diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx
index 06a96083f79..c64b6716936 100644
--- a/gui/themes/scummclassic/classic_layout.stx
+++ b/gui/themes/scummclassic/classic_layout.stx
@@ -2472,4 +2472,41 @@
 		</layout>
 	</dialog>
 
+	<dialog name = 'GameOptions_IntegrityDialog' overlays = 'Dialog.GameOptions' shading = 'dim'>
+		<layout type = 'vertical' padding = '16, 16, 16, 8' spacing = '8'>
+			<widget name = 'ResultsText'
+					height = '150'
+			/>
+			<widget name = 'WarningText'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'StatusText'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'ErrorText'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'ProgressBar'
+					height = 'Globals.Button.Height'
+			/>
+			<space size = '1'/>
+			<widget name = 'PercentText'
+					height = 'Globals.Line.Height'
+					textalign = 'center'
+			/>
+			<widget name = 'DownloadSize'
+					height = 'Globals.Line.Height'
+			/>
+			<space/>
+			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10'>
+				<widget name = 'MainButton'
+						type = 'Button'
+				/>
+				<widget name = 'CopyButton'
+						type = 'Button'
+				/>
+			</layout>
+		</layout>
+	</dialog>
+
 </layout_info>
diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx
index ce3b4c15f72..802896afb74 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -2449,4 +2449,41 @@
 		</layout>
 	</dialog>
 
+	<dialog name = 'GameOptions_IntegrityDialog' overlays = 'Dialog.GameOptions' shading = 'dim'>
+		<layout type = 'vertical' padding = '8, 8, 8, 8'>
+			<widget name = 'ResultsText'
+					height = '150'
+			/>
+			<widget name = 'WarningText'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'StatusText'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'ErrorText'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'ProgressBar'
+					height = 'Globals.Button.Height'
+			/>
+			<space size = '1'/>
+			<widget name = 'PercentText'
+					height = 'Globals.Line.Height'
+					textalign = 'center'
+			/>
+			<widget name = 'DownloadSize'
+					height = 'Globals.Line.Height'
+			/>
+			<space/>
+			<layout type = 'horizontal' padding = '8, 8, 8, 8'>
+				<widget name = 'MainButton'
+						type = 'Button'
+				/>
+				<widget name = 'CopyButton'
+						type = 'Button'
+				/>
+			</layout>
+		</layout>
+	</dialog>
+
 </layout_info>
diff --git a/gui/themes/scummmodern/THEMERC b/gui/themes/scummmodern/THEMERC
index 9fcd24c0df1..48fb32e470d 100644
--- a/gui/themes/scummmodern/THEMERC
+++ b/gui/themes/scummmodern/THEMERC
@@ -1,2 +1,2 @@
-[SCUMMVM_STX0.9.17:ScummVM Modern Theme:No Author]
+[SCUMMVM_STX0.9.18:ScummVM Modern Theme:No Author]
 %using ../common
diff --git a/gui/themes/scummremastered/THEMERC b/gui/themes/scummremastered/THEMERC
index 951f7f5a814..cc604b77833 100644
--- a/gui/themes/scummremastered/THEMERC
+++ b/gui/themes/scummremastered/THEMERC
@@ -1,3 +1,3 @@
-[SCUMMVM_STX0.9.17:ScummVM Modern Theme Remastered:No Author]
+[SCUMMVM_STX0.9.18:ScummVM Modern Theme Remastered:No Author]
 %using ../common
 %using ../common-svg


Commit: fb4ed4eaa351f6a487a2de7b44f92b58efdb2c46
    https://github.com/scummvm/scummvm/commit/fb4ed4eaa351f6a487a2de7b44f92b58efdb2c46
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2024-06-14T01:19:21+02:00

Commit Message:
GUI: Regenerated theme files

Changed paths:
    gui/themes/default.inc
    gui/themes/residualvm.zip
    gui/themes/scummclassic.zip
    gui/themes/scummmodern.zip
    gui/themes/scummremastered.zip


diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index d6eebf3193f..cbf019396f2 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -3774,6 +3774,42 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
 "</layout>"
 "</layout>"
 "</dialog>"
+"<dialog name='GameOptions_IntegrityDialog' overlays='Dialog.GameOptions' shading='dim'>"
+"<layout type='vertical' padding='16,16,16,8' spacing='8'>"
+"<widget name='ResultsText' "
+"height='150' "
+"/>"
+"<widget name='WarningText' "
+"height='Globals.Line.Height' "
+"/>"
+"<widget name='StatusText' "
+"height='Globals.Line.Height' "
+"/>"
+"<widget name='ErrorText' "
+"height='Globals.Line.Height' "
+"/>"
+"<widget name='ProgressBar' "
+"height='Globals.Button.Height' "
+"/>"
+"<space size='1'/>"
+"<widget name='PercentText' "
+"height='Globals.Line.Height' "
+"textalign='center' "
+"/>"
+"<widget name='DownloadSize' "
+"height='Globals.Line.Height' "
+"/>"
+"<space/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'>"
+"<widget name='MainButton' "
+"type='Button' "
+"/>"
+"<widget name='CopyButton' "
+"type='Button' "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
 "</layout_info>"
 ;
  const char *defaultXML4 = "<layout_info resolution='y<H'>"
@@ -6087,6 +6123,42 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
 "</layout>"
 "</layout>"
 "</dialog>"
+"<dialog name='GameOptions_IntegrityDialog' overlays='Dialog.GameOptions' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,8'>"
+"<widget name='ResultsText' "
+"height='150' "
+"/>"
+"<widget name='WarningText' "
+"height='Globals.Line.Height' "
+"/>"
+"<widget name='StatusText' "
+"height='Globals.Line.Height' "
+"/>"
+"<widget name='ErrorText' "
+"height='Globals.Line.Height' "
+"/>"
+"<widget name='ProgressBar' "
+"height='Globals.Button.Height' "
+"/>"
+"<space size='1'/>"
+"<widget name='PercentText' "
+"height='Globals.Line.Height' "
+"textalign='center' "
+"/>"
+"<widget name='DownloadSize' "
+"height='Globals.Line.Height' "
+"/>"
+"<space/>"
+"<layout type='horizontal' padding='8,8,8,8'>"
+"<widget name='MainButton' "
+"type='Button' "
+"/>"
+"<widget name='CopyButton' "
+"type='Button' "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
 "</layout_info>"
 ;
 const char *defaultXML[] = { defaultXML1, defaultXML2, defaultXML3, defaultXML4 };
diff --git a/gui/themes/residualvm.zip b/gui/themes/residualvm.zip
index 47909204a16..311ff8b57b2 100644
Binary files a/gui/themes/residualvm.zip and b/gui/themes/residualvm.zip differ
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index 05d54d7b148..fda8a135414 100644
Binary files a/gui/themes/scummclassic.zip and b/gui/themes/scummclassic.zip differ
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index cd472ce2c35..3121c3460d1 100644
Binary files a/gui/themes/scummmodern.zip and b/gui/themes/scummmodern.zip differ
diff --git a/gui/themes/scummremastered.zip b/gui/themes/scummremastered.zip
index 482ed58b621..d20e9beb02e 100644
Binary files a/gui/themes/scummremastered.zip and b/gui/themes/scummremastered.zip differ




More information about the Scummvm-git-logs mailing list