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

sev- noreply at scummvm.org
Sun Jan 8 00:16:26 UTC 2023


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

Summary:
ef65534250 BACKENDS: SHADERS: Make possibility to load shaders from SearchMan
e41559cfa5 GUI: Moved icons pack set generation to common/
aa14d59447 BACKENDS: OPENGL: Switch shaders to SearchSet
82e21f3c3c COMMON: Probe files for existnce, so there is less noise
f262e71eb4 JANITORIAL: Remove redundant namespace specs
5d08b1a0f3 COMMON: Add flag to match whole path for Archive::listMatchingMembers()
ad8ffd0035 GUI: Initial code for Shader Browser. Zip selection works
c1478cd1e6 GUI: Fixed search icon tooltip
0a9d3ca616 GUI: Added text filter to the ShaderBrowser
8f469af5dc GUI: Added alternate file picker to ShaderBrowser
5de84d8724 GUI: Added button for updating shaders
ee33e99357 GUI: Rename downloadiconsdialog.* -> downloadpacksdialog.*
4d0f0fda52 GUI: Renamed DownloadIconsDialog -> DownloadPacksDialog
31afcec77c GUI: Generalize DownloadPacksDialog
965f0f370f GUI: Implemented shader packs downloading
bfbaff64c1 GUI: Fix ShadowBrowser for classic theme
3c7a05825c GUI: Sync classic theme, bump theme version and regenerate
efaeb08a4f GUI: Added default shaders pack.


Commit: ef65534250d07f966f98c0f0fb840351156c7bc0
    https://github.com/scummvm/scummvm/commit/ef65534250d07f966f98c0f0fb840351156c7bc0
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:44+01:00

Commit Message:
BACKENDS: SHADERS: Make possibility to load shaders from SearchMan

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/pipelines/libretro.cpp
    backends/graphics/opengl/pipelines/libretro.h
    backends/graphics/opengl/pipelines/libretro/parser.cpp
    backends/graphics/opengl/pipelines/libretro/parser.h
    backends/graphics/opengl/pipelines/libretro/types.h


diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index d2ceae90172..90792bd1b3f 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -356,7 +356,7 @@ bool OpenGLGraphicsManager::loadShader(const Common::String &fileName) {
 
 	// Load selected shader preset
 	if (!fileName.empty()) {
-		if (!_libretroPipeline->open(Common::FSNode(fileName))) {
+		if (!_libretroPipeline->open(fileName)) {
 			warning("Failed to load shader %s", fileName.c_str());
 			return false;
 		}
diff --git a/backends/graphics/opengl/pipelines/libretro.cpp b/backends/graphics/opengl/pipelines/libretro.cpp
index d065ff770a7..54ea821e4b0 100644
--- a/backends/graphics/opengl/pipelines/libretro.cpp
+++ b/backends/graphics/opengl/pipelines/libretro.cpp
@@ -44,16 +44,26 @@ namespace OpenGL {
 using LibRetro::UniformsMap;
 
 template<typename DecoderType>
-static Graphics::Surface *loadViaImageDecoder(const Common::FSNode &fileNode) {
-	Common::SeekableReadStream *stream = fileNode.createReadStream();
-	if (!stream) {
-		return nullptr;
+static Graphics::Surface *loadViaImageDecoder(const Common::String &fileName) {
+	Common::File file;
+
+	// First try SearchMan, then fallback to filesystem
+	if (Common::File::exists(fileName)) {
+		if (!file.open(fileName)) {
+			warning("LibRetroPipeline::loadViaImageDecoder: Cannot open file '%s'", fileName.c_str());
+			return nullptr;
+		}
+	} else {
+		Common::FSNode fsnode(fileName);
+		if (!fsnode.exists() || !fsnode.isReadable() || fsnode.isDirectory()
+				|| !file.open(fsnode)) {
+			warning("LibRetroPipeline::loadViaImageDecoder: Invalid file path '%s'", fileName.c_str());
+			return nullptr;
+		}
 	}
 
 	DecoderType decoder;
-	const bool success = decoder.loadStream(*stream);
-	delete stream;
-	stream = nullptr;
+	const bool success = decoder.loadStream(file);
 
 	if (!success) {
 		return nullptr;
@@ -71,7 +81,7 @@ static Graphics::Surface *loadViaImageDecoder(const Common::FSNode &fileNode) {
 
 struct ImageLoader {
 	const char *extension;
-	Graphics::Surface *(*load)(const Common::FSNode &fileNode);
+	Graphics::Surface *(*load)(const Common::String &fileName);
 };
 
 static const ImageLoader s_imageLoaders[] = {
@@ -189,7 +199,7 @@ LibRetroPipeline::LibRetroPipeline()
 	  _isAnimated(false), _frameCount(0) {
 }
 
-LibRetroPipeline::LibRetroPipeline(const Common::FSNode &shaderPreset)
+LibRetroPipeline::LibRetroPipeline(const Common::String &shaderPreset)
 	: _inputPipeline(ShaderMan.query(ShaderManager::kDefault)),
 	  _outputPipeline(ShaderMan.query(ShaderManager::kDefault)),
 	  _needsScaling(false), _shaderPreset(nullptr), _linearFiltering(false),
@@ -336,7 +346,7 @@ void LibRetroPipeline::deactivateInternal() {
 	// Don't call Pipeline::deactivateInternal as our framebuffer is passed to _outputPipeline
 }
 
-bool LibRetroPipeline::open(const Common::FSNode &shaderPreset) {
+bool LibRetroPipeline::open(const Common::String &shaderPreset) {
 	close();
 
 	_shaderPreset = LibRetro::parsePreset(shaderPreset);
@@ -384,20 +394,11 @@ void LibRetroPipeline::close() {
 	_currentTarget = uint(-1);
 }
 
-static Common::FSNode getChildRecursive(const Common::FSNode &basePath, const Common::String &fileName) {
-	Common::FSNode finalPath = basePath;
-	Common::StringTokenizer tok(fileName, "\\/");
-	while (!tok.empty()) {
-		finalPath = finalPath.getChild(tok.nextToken());
-	}
-	return finalPath;
-}
-
 bool LibRetroPipeline::loadTextures() {
 	for (LibRetro::ShaderPreset::TextureArray::const_iterator
 		 i = _shaderPreset->textures.begin(), end = _shaderPreset->textures.end();
 		 i != end; ++i) {
-		Texture texture = loadTexture(getChildRecursive( _shaderPreset->basePath, i->fileName));
+		Texture texture = loadTexture(Common::normalizePath(_shaderPreset->basePath + Common::String("/") + i->fileName, '/'));
 		texture.id = i->id;
 
 		if (!texture.textureData || !texture.glTexture) {
@@ -460,23 +461,31 @@ bool LibRetroPipeline::loadPasses() {
 	for (LibRetro::ShaderPreset::PassArray::const_iterator
 		 i = _shaderPreset->passes.begin(), end = _shaderPreset->passes.end();
 		 i != end; ++i) {
-		Common::FSNode fileNode(getChildRecursive(_shaderPreset->basePath, i->fileName));
-
-		Common::SeekableReadStream *stream = fileNode.createReadStream();
-		if (!stream) {
-			warning("LibRetroPipeline::loadPasses: Could not open file '%s'", fileNode.isReadable() ? fileNode.getName().c_str() : i->fileName.c_str());
-			return false;
+		Common::String fileName(Common::normalizePath(_shaderPreset->basePath + Common::String("/") + i->fileName, '/'));
+		Common::File file;
+
+		// First try SearchMan, then fallback to filesystem
+		if (Common::File::exists(fileName)) {
+			if (!file.open(fileName)) {
+				warning("LibRetroPipeline::loadPasses: Cannot open file '%s'", fileName.c_str());
+				return false;
+			}
+		} else {
+			Common::FSNode fsnode(fileName);
+			if (!fsnode.exists() || !fsnode.isReadable() || fsnode.isDirectory()
+					|| !file.open(fsnode)) {
+				warning("LibRetroPipeline::loadPasses: Invalid file path '%s'", fileName.c_str());
+				return false;
+			}
 		}
 
 		Common::Array<char> shaderFileContents;
-		shaderFileContents.resize(stream->size() + 1);
-		shaderFileContents[stream->size()] = 0;
-		const bool readSuccess = stream->read(shaderFileContents.begin(), stream->size()) == (uint32)stream->size();
-		delete stream;
-		stream = nullptr;
+		shaderFileContents.resize(file.size() + 1);
+		shaderFileContents[file.size()] = 0;
+		const bool readSuccess = file.read(shaderFileContents.begin(), file.size()) == (uint32)file.size();
 
 		if (!readSuccess) {
-			warning("LibRetroPipeline::loadPasses: Could not read file '%s'", fileNode.getName().c_str());
+			warning("LibRetroPipeline::loadPasses: Could not read file '%s'", fileName.c_str());
 			return false;
 		}
 
@@ -532,7 +541,7 @@ bool LibRetroPipeline::loadPasses() {
 			shaderFileStart,
 		};
 
-		if (!shader->loadFromStringsArray(fileNode.getName(),
+		if (!shader->loadFromStringsArray(fileName,
 				 ARRAYSIZE(vertexSources), vertexSources,
 				 ARRAYSIZE(fragmentSources), fragmentSources,
 				 g_libretroShaderAttributes)) {
@@ -724,8 +733,7 @@ void LibRetroPipeline::setShaderTexUniforms(const Common::String &prefix, Shader
 	shader->setUniform(prefix + "TextureSize", Math::Vector2d(texture.getWidth(), texture.getHeight()));
 }
 
-LibRetroPipeline::Texture LibRetroPipeline::loadTexture(const Common::FSNode &fileNode) {
-	Common::String fileName = fileNode.getName();
+LibRetroPipeline::Texture LibRetroPipeline::loadTexture(const Common::String &fileName) {
 	const char *extension = nullptr;
 	for (int dotPos = fileName.size() - 1; dotPos >= 0; --dotPos) {
 		if (fileName[dotPos] == '.') {
@@ -741,7 +749,7 @@ LibRetroPipeline::Texture LibRetroPipeline::loadTexture(const Common::FSNode &fi
 
 	for (const ImageLoader *loader = s_imageLoaders; loader->extension; ++loader) {
 		if (!scumm_stricmp(loader->extension, extension)) {
-			Graphics::Surface *textureData = loader->load(fileNode);
+			Graphics::Surface *textureData = loader->load(fileName);
 			if (!textureData) {
 				warning("LibRetroPipeline::loadTexture: Loader for '%s' could not load file '%s'", loader->extension, fileName.c_str());
 				return Texture();
diff --git a/backends/graphics/opengl/pipelines/libretro.h b/backends/graphics/opengl/pipelines/libretro.h
index 377fa38afbf..7ab594d4d8b 100644
--- a/backends/graphics/opengl/pipelines/libretro.h
+++ b/backends/graphics/opengl/pipelines/libretro.h
@@ -50,13 +50,13 @@ class LibRetroTextureTarget;
 class LibRetroPipeline : public Pipeline {
 public:
 	LibRetroPipeline();
-	LibRetroPipeline(const Common::FSNode &shaderPreset);
+	LibRetroPipeline(const Common::String &shaderPath);
 	~LibRetroPipeline() override;
 
 	void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) override;
 	void setProjectionMatrix(const Math::Matrix4 &projectionMatrix) override;
 
-	bool open(const Common::FSNode &shaderPreset);
+	bool open(const Common::String &shaderPath);
 	void close();
 
 	/* Called by OpenGLGraphicsManager */
@@ -118,7 +118,7 @@ private:
 		Graphics::Surface *textureData;
 		GLTexture *glTexture;
 	};
-	Texture loadTexture(const Common::FSNode &fileNode);
+	Texture loadTexture(const Common::String &fileName);
 
 	typedef Common::Array<Texture> TextureArray;
 	TextureArray _textures;
diff --git a/backends/graphics/opengl/pipelines/libretro/parser.cpp b/backends/graphics/opengl/pipelines/libretro/parser.cpp
index 3e2b2a17c46..89415a0dcb8 100644
--- a/backends/graphics/opengl/pipelines/libretro/parser.cpp
+++ b/backends/graphics/opengl/pipelines/libretro/parser.cpp
@@ -24,7 +24,7 @@
 #if !USE_FORCED_GLES
 #include "backends/graphics/opengl/pipelines/libretro/parser.h"
 
-#include "common/fs.h"
+#include "common/file.h"
 #include "common/hash-str.h"
 #include "common/stream.h"
 #include "common/algorithm.h"
@@ -533,30 +533,31 @@ bool PresetParser::parseParameters() {
 	return true;
 }
 
-ShaderPreset *parsePreset(const Common::FSNode &shaderPreset) {
-	if (!shaderPreset.exists() || !shaderPreset.isReadable() || shaderPreset.isDirectory()) {
-		warning("LibRetro Preset Parsing: No such readable file '%s'", shaderPreset.getName().c_str());
-		return nullptr;
-	}
+ShaderPreset *parsePreset(const Common::String &shaderPreset) {
+	Common::File file;
 
-	Common::FSNode basePath(shaderPreset.getParent());
-	if (!basePath.exists() || !basePath.isReadable() || !basePath.isDirectory()) {
-		warning("LibRetro Preset Parsing: Base path '%s' to file '%s' invalid", basePath.getName().c_str(), shaderPreset.getName().c_str());
-		return nullptr;
+	// First try SearchMan, then fallback to filesystem
+	if (Common::File::exists(shaderPreset)) {
+		if (!file.open(shaderPreset)) {
+			warning("LibRetro Preset Parsing: Cannot open file '%s'", shaderPreset.c_str());
+			return nullptr;
+		}
+	} else {
+		Common::FSNode fsnode(shaderPreset);
+		if (!fsnode.exists() || !fsnode.isReadable() || fsnode.isDirectory()
+				|| !file.open(fsnode)) {
+			warning("LibRetro Preset Parsing: Invalid file path '%s'", shaderPreset.c_str());
+			return nullptr;
+		}
 	}
 
-	Common::SeekableReadStream *stream = shaderPreset.createReadStream();
-	if (!stream) {
-		return nullptr;
-	}
+	Common::String basePath(Common::firstPathComponents(shaderPreset, '/'));
 
 	PresetParser parser;
-	ShaderPreset *shader = parser.parseStream(*stream);
-	delete stream;
-	stream = nullptr;
+	ShaderPreset *shader = parser.parseStream(file);
 
 	if (!shader) {
-		warning("LibRetro Preset Parsing: Error while parsing file '%s': %s", shaderPreset.getName().c_str(), parser.getErrorDesc().c_str());
+		warning("LibRetro Preset Parsing: Error while parsing file '%s': %s", shaderPreset.c_str(), parser.getErrorDesc().c_str());
 		return nullptr;
 	}
 
diff --git a/backends/graphics/opengl/pipelines/libretro/parser.h b/backends/graphics/opengl/pipelines/libretro/parser.h
index ada4d331e78..b1c7e1597c5 100644
--- a/backends/graphics/opengl/pipelines/libretro/parser.h
+++ b/backends/graphics/opengl/pipelines/libretro/parser.h
@@ -27,12 +27,10 @@
 #if !USE_FORCED_GLES
 #include "backends/graphics/opengl/pipelines/libretro/types.h"
 
-#include "common/fs.h"
-
 namespace OpenGL {
 namespace LibRetro {
 
-ShaderPreset *parsePreset(const Common::FSNode &shaderPreset);
+ShaderPreset *parsePreset(const Common::String &shaderPreset);
 
 } // End of namespace LibRetro
 } // End of namespace OpenGL
diff --git a/backends/graphics/opengl/pipelines/libretro/types.h b/backends/graphics/opengl/pipelines/libretro/types.h
index 72949229d9f..0fcb5f41a00 100644
--- a/backends/graphics/opengl/pipelines/libretro/types.h
+++ b/backends/graphics/opengl/pipelines/libretro/types.h
@@ -113,7 +113,7 @@ struct ShaderPass {
 };
 
 struct ShaderPreset {
-	Common::FSNode basePath;
+	Common::String basePath;
 
 	typedef Common::Array<ShaderTexture> TextureArray;
 	TextureArray textures;


Commit: e41559cfa5f8287ea20746c76902870d22301020
    https://github.com/scummvm/scummvm/commit/e41559cfa5f8287ea20746c76902870d22301020
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:51+01:00

Commit Message:
GUI: Moved icons pack set generation to common/

Changed paths:
  A common/zip-set.cpp
  A common/zip-set.h
    common/module.mk
    gui/gui-manager.cpp


diff --git a/common/module.mk b/common/module.mk
index b9ce15077e6..0f5f40f0b09 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -39,7 +39,8 @@ MODULE_OBJS := \
 	unicode-bidi.o \
 	ustr.o \
 	util.o \
-	xpfloat.o
+	xpfloat.o \
+	zip-set.o
 
 ifdef ENABLE_EVENTRECORDER
 MODULE_OBJS += \
diff --git a/common/zip-set.cpp b/common/zip-set.cpp
new file mode 100644
index 00000000000..eab10f60541
--- /dev/null
+++ b/common/zip-set.cpp
@@ -0,0 +1,96 @@
+/* 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 "common/config-manager.h"
+#include "common/debug.h"
+#include "common/file.h"
+#include "common/zip-set.h"
+#include "common/compression/unzip.h"
+
+namespace Common {
+
+struct ArchiveMemberListBackComparator {
+	bool operator()(const Common::ArchiveMemberPtr &a, const Common::ArchiveMemberPtr &b) {
+		return a->getName() > b->getName();
+	}
+};
+
+bool generateZipSet(Common::SearchSet &searchSet, const char *defaultFile, const char *packsMask, const char *packsPath) {
+	Common::Archive *dat;
+	bool changed = false;
+
+	if (!ConfMan.get(packsPath).empty()) {
+		Common::FSDirectory *iconDir = new Common::FSDirectory(ConfMan.get(packsPath));
+		Common::ArchiveMemberList iconFiles;
+
+		iconDir->listMatchingMembers(iconFiles, packsMask);
+		Common::sort(iconFiles.begin(), iconFiles.end(), ArchiveMemberListBackComparator());
+
+		for (Common::ArchiveMemberList::iterator ic = iconFiles.begin(); ic != iconFiles.end(); ++ic) {
+			dat = Common::makeZipArchive((*ic)->createReadStream());
+
+			if (dat) {
+				searchSet.add((*ic)->getName(), dat);
+				changed = true;
+				debug(2, "generateZipSet: Loaded pack file: %s", (*ic)->getName().c_str());
+			}
+		}
+
+		delete iconDir;
+	}
+
+	dat = nullptr;
+
+	if (ConfMan.hasKey("themepath")) {
+		Common::FSNode *fs = new Common::FSNode(normalizePath(ConfMan.get("themepath") + "/" + defaultFile, '/'));
+		if (fs->exists()) {
+			dat = Common::makeZipArchive(*fs);
+		}
+		delete fs;
+	}
+
+	if (!dat) {
+		Common::File *file = new Common::File;
+		if (ConfMan.hasKey(packsPath))
+			file->open(normalizePath(ConfMan.get(packsPath) + "/" + defaultFile, '/'));
+
+		if (!file->isOpen())
+			file->open(defaultFile);
+
+		if (file->isOpen())
+			dat = Common::makeZipArchive(defaultFile);
+
+		if (!dat) {
+			warning("generateZipSet: Could not find '%s'", defaultFile);
+			delete file;
+		}
+	}
+
+	if (dat) {
+		searchSet.add(defaultFile, dat);
+		changed = true;
+		debug(2, "generateZipSet: Loaded pack file: %s", defaultFile);
+	}
+
+	return changed;
+}
+
+} // End of namespace Common
diff --git a/common/zip-set.h b/common/zip-set.h
new file mode 100644
index 00000000000..331da4c3189
--- /dev/null
+++ b/common/zip-set.h
@@ -0,0 +1,54 @@
+/* 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 COMMON_ZIP_SET_H
+#define COMMON_ZIP_SET_H
+
+#include "common/archive.h"
+
+namespace Common {
+
+/**
+ * Scan the given firectory for a set of versioned zip packs and put then
+ * into the provided SearchSet
+ *
+ * There are 2 types of files: defaultFile, that could potentially sit
+ * in themepath or even built-in into an executable, and so called pack files
+ * typically containing creation date in them.
+ *
+ * These files are put in the SearchSet in a sorted way, thus, the latter
+ * packs have higher priority.
+ *
+ * Example: gui-icons.dat, gui-icons-20211112.dat, gui-icons-20220602.dat
+ *
+ * @param[out] searchSet    The SearchSet to modify
+ * @param[in]  defaultFile  Name of the default file
+ * @param[in]  packsMask    Mask of the pack files
+ * @param[in]  packsPath    Name of ConfMan variable with Path to the packs. Default is "iconspath""
+ *
+ * @return True if the string has been parsed correctly, false if an error
+ *
+ */
+bool generateZipSet(Common::SearchSet &searchSet, const char *defaultFile, const char *packsMask, const char *packsPath = "iconspath");
+
+}
+
+#endif
diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp
index a1ba5912a29..e152c54a32f 100644
--- a/gui/gui-manager.cpp
+++ b/gui/gui-manager.cpp
@@ -20,15 +20,8 @@
  */
 
 #include "common/events.h"
-#include "common/system.h"
-#include "common/util.h"
-#include "common/config-manager.h"
-#include "common/algorithm.h"
-#include "common/file.h"
-#include "common/rect.h"
-#include "common/textconsole.h"
 #include "common/translation.h"
-#include "common/compression/unzip.h"
+#include "common/zip-set.h"
 #include "gui/EventRecorder.h"
 
 #include "backends/keymapper/action.h"
@@ -113,71 +106,12 @@ GuiManager::~GuiManager() {
 	delete _theme;
 }
 
-struct ArchiveMemberListBackComparator {
-	bool operator()(const Common::ArchiveMemberPtr &a, const Common::ArchiveMemberPtr &b) {
-		return a->getName() > b->getName();
-	}
-};
 void GuiManager::initIconsSet() {
 	Common::StackLock lock(_iconsMutex);
-	Common::Archive *dat;
 
 	_iconsSet.clear();
 
-	dat = nullptr;
-
-	const char fname[] = "gui-icons.dat";
-
-	if (ConfMan.hasKey("themepath")) {
-		Common::FSNode *fs = new Common::FSNode(normalizePath(ConfMan.get("themepath") + "/" + fname, '/'));
-		if (fs->exists()) {
-			dat = Common::makeZipArchive(*fs);
-		}
-		delete fs;
-	}
-
-	if (!dat) {
-		Common::File *file = new Common::File;
-		if (ConfMan.hasKey("iconspath"))
-			file->open(normalizePath(ConfMan.get("iconspath") + "/" + fname, '/'));
-
-		if (!file->isOpen())
-			file->open(fname);
-
-		if (file->isOpen())
-			dat = Common::makeZipArchive(file);
-
-		if (!dat) {
-			warning("GUI: Could not find '%s'", fname);
-			delete file;
-		}
-	}
-
-	if (dat) {
-		_iconsSet.add(fname, dat);
-		_iconsSetChanged = true;
-		debug(2, "GUI: Loaded icon file: %s", fname);
-	}
-
-	if (!ConfMan.get("iconspath").empty()) {
-		Common::FSDirectory *iconDir = new Common::FSDirectory(ConfMan.get("iconspath"));
-		Common::ArchiveMemberList iconFiles;
-
-		iconDir->listMatchingMembers(iconFiles, "gui-icons*.dat");
-		Common::sort(iconFiles.begin(), iconFiles.end(), ArchiveMemberListBackComparator());
-
-		for (Common::ArchiveMemberList::iterator ic = iconFiles.begin(); ic != iconFiles.end(); ++ic) {
-			dat = Common::makeZipArchive((*ic)->createReadStream());
-
-			if (dat) {
-				_iconsSet.add((*ic)->getName(), dat);
-				_iconsSetChanged = true;
-				debug(2, "GUI: Loaded icon file: %s", (*ic)->getName().c_str());
-			}
-		}
-
-		delete iconDir;
-	}
+	_iconsSetChanged = Common::generateZipSet(_iconsSet, "gui-icons.dat", "gui-icons*.dat");
 }
 
 void GuiManager::computeScaleFactor() {


Commit: aa14d59447d42e1262363bbdf0d4d41b946afb8a
    https://github.com/scummvm/scummvm/commit/aa14d59447d42e1262363bbdf0d4d41b946afb8a
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:51+01:00

Commit Message:
BACKENDS: OPENGL: Switch shaders to SearchSet

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/pipelines/libretro.cpp
    backends/graphics/opengl/pipelines/libretro.h
    backends/graphics/opengl/pipelines/libretro/parser.cpp
    backends/graphics/opengl/pipelines/libretro/parser.h


diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 90792bd1b3f..13b9572f121 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -34,6 +34,7 @@
 #include "common/translation.h"
 #include "common/algorithm.h"
 #include "common/file.h"
+#include "common/zip-set.h"
 #include "gui/debugger.h"
 #include "engines/engine.h"
 #ifdef USE_OSD
@@ -354,9 +355,13 @@ bool OpenGLGraphicsManager::loadShader(const Common::String &fileName) {
 		return true;
 	}
 
+	Common::SearchSet shaderSet;
+
+	Common::generateZipSet(shaderSet, "shaders.dat", "shaders*.dat");
+
 	// Load selected shader preset
 	if (!fileName.empty()) {
-		if (!_libretroPipeline->open(fileName)) {
+		if (!_libretroPipeline->open(fileName, shaderSet)) {
 			warning("Failed to load shader %s", fileName.c_str());
 			return false;
 		}
diff --git a/backends/graphics/opengl/pipelines/libretro.cpp b/backends/graphics/opengl/pipelines/libretro.cpp
index 54ea821e4b0..552f3d0bb8e 100644
--- a/backends/graphics/opengl/pipelines/libretro.cpp
+++ b/backends/graphics/opengl/pipelines/libretro.cpp
@@ -44,26 +44,25 @@ namespace OpenGL {
 using LibRetro::UniformsMap;
 
 template<typename DecoderType>
-static Graphics::Surface *loadViaImageDecoder(const Common::String &fileName) {
-	Common::File file;
+static Graphics::Surface *loadViaImageDecoder(const Common::String &fileName, Common::SearchSet &archSet) {
+	Common::SeekableReadStream *stream;
 
 	// First try SearchMan, then fallback to filesystem
-	if (Common::File::exists(fileName)) {
-		if (!file.open(fileName)) {
-			warning("LibRetroPipeline::loadViaImageDecoder: Cannot open file '%s'", fileName.c_str());
-			return nullptr;
-		}
+	if (archSet.hasFile(fileName)) {
+		stream = archSet.createReadStreamForMember(fileName);
 	} else {
 		Common::FSNode fsnode(fileName);
 		if (!fsnode.exists() || !fsnode.isReadable() || fsnode.isDirectory()
-				|| !file.open(fsnode)) {
+				|| !(stream = fsnode.createReadStream())) {
 			warning("LibRetroPipeline::loadViaImageDecoder: Invalid file path '%s'", fileName.c_str());
 			return nullptr;
 		}
 	}
 
 	DecoderType decoder;
-	const bool success = decoder.loadStream(file);
+	const bool success = decoder.loadStream(*stream);
+
+	delete stream;
 
 	if (!success) {
 		return nullptr;
@@ -81,7 +80,7 @@ static Graphics::Surface *loadViaImageDecoder(const Common::String &fileName) {
 
 struct ImageLoader {
 	const char *extension;
-	Graphics::Surface *(*load)(const Common::String &fileName);
+	Graphics::Surface *(*load)(const Common::String &fileName, Common::SearchSet &archSet);
 };
 
 static const ImageLoader s_imageLoaders[] = {
@@ -199,15 +198,6 @@ LibRetroPipeline::LibRetroPipeline()
 	  _isAnimated(false), _frameCount(0) {
 }
 
-LibRetroPipeline::LibRetroPipeline(const Common::String &shaderPreset)
-	: _inputPipeline(ShaderMan.query(ShaderManager::kDefault)),
-	  _outputPipeline(ShaderMan.query(ShaderManager::kDefault)),
-	  _needsScaling(false), _shaderPreset(nullptr), _linearFiltering(false),
-	  _currentTarget(uint(-1)), _inputWidth(0), _inputHeight(0),
-	  _isAnimated(false), _frameCount(0) {
-	open(shaderPreset);
-}
-
 LibRetroPipeline::~LibRetroPipeline() {
 	close();
 }
@@ -346,19 +336,19 @@ void LibRetroPipeline::deactivateInternal() {
 	// Don't call Pipeline::deactivateInternal as our framebuffer is passed to _outputPipeline
 }
 
-bool LibRetroPipeline::open(const Common::String &shaderPreset) {
+bool LibRetroPipeline::open(const Common::String &shaderPreset, Common::SearchSet &archSet) {
 	close();
 
-	_shaderPreset = LibRetro::parsePreset(shaderPreset);
+	_shaderPreset = LibRetro::parsePreset(shaderPreset, archSet);
 	if (!_shaderPreset)
 		return false;
 
-	if (!loadTextures()) {
+	if (!loadTextures(archSet)) {
 		close();
 		return false;
 	}
 
-	if (!loadPasses()) {
+	if (!loadPasses(archSet)) {
 		close();
 		return false;
 	}
@@ -394,11 +384,11 @@ void LibRetroPipeline::close() {
 	_currentTarget = uint(-1);
 }
 
-bool LibRetroPipeline::loadTextures() {
+bool LibRetroPipeline::loadTextures(Common::SearchSet &archSet) {
 	for (LibRetro::ShaderPreset::TextureArray::const_iterator
 		 i = _shaderPreset->textures.begin(), end = _shaderPreset->textures.end();
 		 i != end; ++i) {
-		Texture texture = loadTexture(Common::normalizePath(_shaderPreset->basePath + Common::String("/") + i->fileName, '/'));
+		Texture texture = loadTexture(Common::normalizePath(_shaderPreset->basePath + Common::String("/") + i->fileName, '/'), archSet);
 		texture.id = i->id;
 
 		if (!texture.textureData || !texture.glTexture) {
@@ -433,7 +423,7 @@ static void stripShaderParameters(char *source, UniformsMap &uniforms) {
 	}
 }
 
-bool LibRetroPipeline::loadPasses() {
+bool LibRetroPipeline::loadPasses(Common::SearchSet &archSet) {
 	// Error out if there are no passes
 	if (!_shaderPreset->passes.size()) {
 		return false;
@@ -462,27 +452,26 @@ bool LibRetroPipeline::loadPasses() {
 		 i = _shaderPreset->passes.begin(), end = _shaderPreset->passes.end();
 		 i != end; ++i) {
 		Common::String fileName(Common::normalizePath(_shaderPreset->basePath + Common::String("/") + i->fileName, '/'));
-		Common::File file;
+		Common::SeekableReadStream *stream;
 
 		// First try SearchMan, then fallback to filesystem
-		if (Common::File::exists(fileName)) {
-			if (!file.open(fileName)) {
-				warning("LibRetroPipeline::loadPasses: Cannot open file '%s'", fileName.c_str());
-				return false;
-			}
+		if (archSet.hasFile(fileName)) {
+			stream = archSet.createReadStreamForMember(fileName);
 		} else {
 			Common::FSNode fsnode(fileName);
 			if (!fsnode.exists() || !fsnode.isReadable() || fsnode.isDirectory()
-					|| !file.open(fsnode)) {
+					|| !(stream = fsnode.createReadStream())) {
 				warning("LibRetroPipeline::loadPasses: Invalid file path '%s'", fileName.c_str());
 				return false;
 			}
 		}
 
 		Common::Array<char> shaderFileContents;
-		shaderFileContents.resize(file.size() + 1);
-		shaderFileContents[file.size()] = 0;
-		const bool readSuccess = file.read(shaderFileContents.begin(), file.size()) == (uint32)file.size();
+		shaderFileContents.resize(stream->size() + 1);
+		shaderFileContents[stream->size()] = 0;
+		const bool readSuccess = stream->read(shaderFileContents.begin(), stream->size()) == (uint32)stream->size();
+
+		delete stream;
 
 		if (!readSuccess) {
 			warning("LibRetroPipeline::loadPasses: Could not read file '%s'", fileName.c_str());
@@ -733,7 +722,7 @@ void LibRetroPipeline::setShaderTexUniforms(const Common::String &prefix, Shader
 	shader->setUniform(prefix + "TextureSize", Math::Vector2d(texture.getWidth(), texture.getHeight()));
 }
 
-LibRetroPipeline::Texture LibRetroPipeline::loadTexture(const Common::String &fileName) {
+LibRetroPipeline::Texture LibRetroPipeline::loadTexture(const Common::String &fileName, Common::SearchSet &archSet) {
 	const char *extension = nullptr;
 	for (int dotPos = fileName.size() - 1; dotPos >= 0; --dotPos) {
 		if (fileName[dotPos] == '.') {
@@ -749,7 +738,7 @@ LibRetroPipeline::Texture LibRetroPipeline::loadTexture(const Common::String &fi
 
 	for (const ImageLoader *loader = s_imageLoaders; loader->extension; ++loader) {
 		if (!scumm_stricmp(loader->extension, extension)) {
-			Graphics::Surface *textureData = loader->load(fileName);
+			Graphics::Surface *textureData = loader->load(fileName, archSet);
 			if (!textureData) {
 				warning("LibRetroPipeline::loadTexture: Loader for '%s' could not load file '%s'", loader->extension, fileName.c_str());
 				return Texture();
diff --git a/backends/graphics/opengl/pipelines/libretro.h b/backends/graphics/opengl/pipelines/libretro.h
index 7ab594d4d8b..01dd0bba798 100644
--- a/backends/graphics/opengl/pipelines/libretro.h
+++ b/backends/graphics/opengl/pipelines/libretro.h
@@ -50,13 +50,12 @@ class LibRetroTextureTarget;
 class LibRetroPipeline : public Pipeline {
 public:
 	LibRetroPipeline();
-	LibRetroPipeline(const Common::String &shaderPath);
 	~LibRetroPipeline() override;
 
 	void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) override;
 	void setProjectionMatrix(const Math::Matrix4 &projectionMatrix) override;
 
-	bool open(const Common::String &shaderPath);
+	bool open(const Common::String &shaderPath, Common::SearchSet &archSet);
 	void close();
 
 	/* Called by OpenGLGraphicsManager */
@@ -80,8 +79,8 @@ private:
 	void deactivateInternal() override;
 	void drawTextureInternal(const GLTexture &texture, const GLfloat *coordinates, const GLfloat *texcoords) override;
 
-	bool loadTextures();
-	bool loadPasses();
+	bool loadTextures(Common::SearchSet &archSet);
+	bool loadPasses(Common::SearchSet &archSet);
 
 	void setPipelineState();
 	bool setupFBOs();
@@ -118,7 +117,7 @@ private:
 		Graphics::Surface *textureData;
 		GLTexture *glTexture;
 	};
-	Texture loadTexture(const Common::String &fileName);
+	Texture loadTexture(const Common::String &fileName, Common::SearchSet &archSet);
 
 	typedef Common::Array<Texture> TextureArray;
 	TextureArray _textures;
diff --git a/backends/graphics/opengl/pipelines/libretro/parser.cpp b/backends/graphics/opengl/pipelines/libretro/parser.cpp
index 89415a0dcb8..718ffb1cb64 100644
--- a/backends/graphics/opengl/pipelines/libretro/parser.cpp
+++ b/backends/graphics/opengl/pipelines/libretro/parser.cpp
@@ -533,19 +533,16 @@ bool PresetParser::parseParameters() {
 	return true;
 }
 
-ShaderPreset *parsePreset(const Common::String &shaderPreset) {
-	Common::File file;
+ShaderPreset *parsePreset(const Common::String &shaderPreset, Common::SearchSet &archSet) {
+	Common::SeekableReadStream *stream;
 
 	// First try SearchMan, then fallback to filesystem
-	if (Common::File::exists(shaderPreset)) {
-		if (!file.open(shaderPreset)) {
-			warning("LibRetro Preset Parsing: Cannot open file '%s'", shaderPreset.c_str());
-			return nullptr;
-		}
+	if (archSet.hasFile(shaderPreset)) {
+		stream = archSet.createReadStreamForMember(shaderPreset);
 	} else {
 		Common::FSNode fsnode(shaderPreset);
 		if (!fsnode.exists() || !fsnode.isReadable() || fsnode.isDirectory()
-				|| !file.open(fsnode)) {
+				|| !(stream = fsnode.createReadStream())) {
 			warning("LibRetro Preset Parsing: Invalid file path '%s'", shaderPreset.c_str());
 			return nullptr;
 		}
@@ -554,7 +551,9 @@ ShaderPreset *parsePreset(const Common::String &shaderPreset) {
 	Common::String basePath(Common::firstPathComponents(shaderPreset, '/'));
 
 	PresetParser parser;
-	ShaderPreset *shader = parser.parseStream(file);
+	ShaderPreset *shader = parser.parseStream(*stream);
+
+	delete stream;
 
 	if (!shader) {
 		warning("LibRetro Preset Parsing: Error while parsing file '%s': %s", shaderPreset.c_str(), parser.getErrorDesc().c_str());
diff --git a/backends/graphics/opengl/pipelines/libretro/parser.h b/backends/graphics/opengl/pipelines/libretro/parser.h
index b1c7e1597c5..8f5b076cfc6 100644
--- a/backends/graphics/opengl/pipelines/libretro/parser.h
+++ b/backends/graphics/opengl/pipelines/libretro/parser.h
@@ -30,7 +30,7 @@
 namespace OpenGL {
 namespace LibRetro {
 
-ShaderPreset *parsePreset(const Common::String &shaderPreset);
+ShaderPreset *parsePreset(const Common::String &shaderPreset, Common::SearchSet &archSet);
 
 } // End of namespace LibRetro
 } // End of namespace OpenGL


Commit: 82e21f3c3c6edcb1b910c66761aa3f715daccbc1
    https://github.com/scummvm/scummvm/commit/82e21f3c3c6edcb1b910c66761aa3f715daccbc1
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:52+01:00

Commit Message:
COMMON: Probe files for existnce, so there is less noise

Changed paths:
    common/zip-set.cpp


diff --git a/common/zip-set.cpp b/common/zip-set.cpp
index eab10f60541..94edc46088f 100644
--- a/common/zip-set.cpp
+++ b/common/zip-set.cpp
@@ -69,11 +69,16 @@ bool generateZipSet(Common::SearchSet &searchSet, const char *defaultFile, const
 
 	if (!dat) {
 		Common::File *file = new Common::File;
-		if (ConfMan.hasKey(packsPath))
-			file->open(normalizePath(ConfMan.get(packsPath) + "/" + defaultFile, '/'));
+		if (ConfMan.hasKey(packsPath)) {
+			Common::String path(normalizePath(ConfMan.get(packsPath) + "/" + defaultFile, '/'));
+
+			if (File::exists(path))
+				file->open(path);
+		}
 
 		if (!file->isOpen())
-			file->open(defaultFile);
+			if (File::exists(defaultFile))
+				file->open(defaultFile);
 
 		if (file->isOpen())
 			dat = Common::makeZipArchive(defaultFile);


Commit: f262e71eb4a53ec7032b86df872f0899076ee69d
    https://github.com/scummvm/scummvm/commit/f262e71eb4a53ec7032b86df872f0899076ee69d
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:52+01:00

Commit Message:
JANITORIAL: Remove redundant namespace specs

Changed paths:
    common/zip-set.cpp
    common/zip-set.h


diff --git a/common/zip-set.cpp b/common/zip-set.cpp
index 94edc46088f..e76b9888530 100644
--- a/common/zip-set.cpp
+++ b/common/zip-set.cpp
@@ -28,24 +28,24 @@
 namespace Common {
 
 struct ArchiveMemberListBackComparator {
-	bool operator()(const Common::ArchiveMemberPtr &a, const Common::ArchiveMemberPtr &b) {
+	bool operator()(const ArchiveMemberPtr &a, const ArchiveMemberPtr &b) {
 		return a->getName() > b->getName();
 	}
 };
 
-bool generateZipSet(Common::SearchSet &searchSet, const char *defaultFile, const char *packsMask, const char *packsPath) {
-	Common::Archive *dat;
+bool generateZipSet(SearchSet &searchSet, const char *defaultFile, const char *packsMask, const char *packsPath) {
+	Archive *dat;
 	bool changed = false;
 
 	if (!ConfMan.get(packsPath).empty()) {
-		Common::FSDirectory *iconDir = new Common::FSDirectory(ConfMan.get(packsPath));
-		Common::ArchiveMemberList iconFiles;
+		FSDirectory *iconDir = new FSDirectory(ConfMan.get(packsPath));
+		ArchiveMemberList iconFiles;
 
 		iconDir->listMatchingMembers(iconFiles, packsMask);
-		Common::sort(iconFiles.begin(), iconFiles.end(), ArchiveMemberListBackComparator());
+		sort(iconFiles.begin(), iconFiles.end(), ArchiveMemberListBackComparator());
 
-		for (Common::ArchiveMemberList::iterator ic = iconFiles.begin(); ic != iconFiles.end(); ++ic) {
-			dat = Common::makeZipArchive((*ic)->createReadStream());
+		for (ArchiveMemberList::iterator ic = iconFiles.begin(); ic != iconFiles.end(); ++ic) {
+			dat = makeZipArchive((*ic)->createReadStream());
 
 			if (dat) {
 				searchSet.add((*ic)->getName(), dat);
@@ -60,17 +60,17 @@ bool generateZipSet(Common::SearchSet &searchSet, const char *defaultFile, const
 	dat = nullptr;
 
 	if (ConfMan.hasKey("themepath")) {
-		Common::FSNode *fs = new Common::FSNode(normalizePath(ConfMan.get("themepath") + "/" + defaultFile, '/'));
+		FSNode *fs = new FSNode(normalizePath(ConfMan.get("themepath") + "/" + defaultFile, '/'));
 		if (fs->exists()) {
-			dat = Common::makeZipArchive(*fs);
+			dat = makeZipArchive(*fs);
 		}
 		delete fs;
 	}
 
 	if (!dat) {
-		Common::File *file = new Common::File;
+		File *file = new File;
 		if (ConfMan.hasKey(packsPath)) {
-			Common::String path(normalizePath(ConfMan.get(packsPath) + "/" + defaultFile, '/'));
+			String path(normalizePath(ConfMan.get(packsPath) + "/" + defaultFile, '/'));
 
 			if (File::exists(path))
 				file->open(path);
@@ -81,7 +81,7 @@ bool generateZipSet(Common::SearchSet &searchSet, const char *defaultFile, const
 				file->open(defaultFile);
 
 		if (file->isOpen())
-			dat = Common::makeZipArchive(defaultFile);
+			dat = makeZipArchive(defaultFile);
 
 		if (!dat) {
 			warning("generateZipSet: Could not find '%s'", defaultFile);
diff --git a/common/zip-set.h b/common/zip-set.h
index 331da4c3189..4bba36d99e0 100644
--- a/common/zip-set.h
+++ b/common/zip-set.h
@@ -47,7 +47,7 @@ namespace Common {
  * @return True if the string has been parsed correctly, false if an error
  *
  */
-bool generateZipSet(Common::SearchSet &searchSet, const char *defaultFile, const char *packsMask, const char *packsPath = "iconspath");
+bool generateZipSet(SearchSet &searchSet, const char *defaultFile, const char *packsMask, const char *packsPath = "iconspath");
 
 }
 


Commit: 5d08b1a0f3a24b7f17b776ce4c2ef33b3c816e2f
    https://github.com/scummvm/scummvm/commit/5d08b1a0f3a24b7f17b776ce4c2ef33b3c816e2f
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:52+01:00

Commit Message:
COMMON: Add flag to match whole path for Archive::listMatchingMembers()

Changed paths:
    common/archive.cpp
    common/archive.h
    common/fs.cpp
    common/fs.h


diff --git a/common/archive.cpp b/common/archive.cpp
index cb76330791f..bb4c2c10a4e 100644
--- a/common/archive.cpp
+++ b/common/archive.cpp
@@ -40,19 +40,20 @@ SeekableReadStream *GenericArchiveMember::createReadStream() const {
 }
 
 
-int Archive::listMatchingMembers(ArchiveMemberList &list, const Path &pattern) const {
+int Archive::listMatchingMembers(ArchiveMemberList &list, const Path &pattern, bool matchPathComponents) const {
 	// Get all "names" (TODO: "files" ?)
 	ArchiveMemberList allNames;
 	listMembers(allNames);
 
 	String patternString = pattern.toString();
 	int matches = 0;
+	const char *wildcardExclusions = matchPathComponents ? NULL : "/";
 
 	ArchiveMemberList::const_iterator it = allNames.begin();
 	for (; it != allNames.end(); ++it) {
 		// TODO: We match case-insenstivie for now, our API does not define whether that's ok or not though...
 		// For our use case case-insensitive is probably what we want to have though.
-		if ((*it)->getName().matchString(patternString, true, "/")) {
+		if ((*it)->getName().matchString(patternString, true, wildcardExclusions)) {
 			list.push_back(*it);
 			matches++;
 		}
@@ -258,12 +259,12 @@ bool SearchSet::hasFile(const Path &path) const {
 	return false;
 }
 
-int SearchSet::listMatchingMembers(ArchiveMemberList &list, const Path &pattern) const {
+int SearchSet::listMatchingMembers(ArchiveMemberList &list, const Path &pattern, bool matchPathComponents) const {
 	int matches = 0;
 
 	ArchiveNodeList::const_iterator it = _list.begin();
 	for (; it != _list.end(); ++it)
-		matches += it->_arc->listMatchingMembers(list, pattern);
+		matches += it->_arc->listMatchingMembers(list, pattern, matchPathComponents);
 
 	return matches;
 }
diff --git a/common/archive.h b/common/archive.h
index b2a8546e623..93741e547d9 100644
--- a/common/archive.h
+++ b/common/archive.h
@@ -115,9 +115,12 @@ public:
 	 * Add all members of the Archive matching the specified pattern to the list.
 	 * Must only append to list, and not remove elements from it.
 	 *
+	 * @param matchPathComponents if set, then whole string will be matched, otherwise (default),
+	 *                            path separator ('/') does not match with wildcards
+	 *
 	 * @return The number of members added to list.
 	 */
-	virtual int listMatchingMembers(ArchiveMemberList &list, const Path &pattern) const;
+	virtual int listMatchingMembers(ArchiveMemberList &list, const Path &pattern, bool matchPathComponents = false) const;
 
 	/**
 	 * Add all members of the Archive to the list.
@@ -318,7 +321,7 @@ public:
 	void setPriority(const String& name, int priority);
 
 	bool hasFile(const Path &path) const override;
-	int listMatchingMembers(ArchiveMemberList &list, const Path &pattern) const override;
+	int listMatchingMembers(ArchiveMemberList &list, const Path &pattern, bool matchPathComponents = false) const override;
 	int listMembers(ArchiveMemberList &list) const override;
 
 	const ArchiveMemberPtr getMember(const Path &path) const override;
diff --git a/common/fs.cpp b/common/fs.cpp
index 74a7c53cf1f..e4c789bb4b2 100644
--- a/common/fs.cpp
+++ b/common/fs.cpp
@@ -327,7 +327,7 @@ void FSDirectory::ensureCached() const  {
 	_cached = true;
 }
 
-int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const Path &pattern) const {
+int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const Path &pattern, bool matchPathComponents) const {
 	if (!_node.isDirectory())
 		return 0;
 
diff --git a/common/fs.h b/common/fs.h
index 384a84a106e..9101bf98a3b 100644
--- a/common/fs.h
+++ b/common/fs.h
@@ -378,7 +378,7 @@ public:
 	/**
 	 * Return a list of matching file names. Pattern can use GLOB wildcards.
 	 */
-	int listMatchingMembers(ArchiveMemberList &list, const Path &pattern) const override;
+	int listMatchingMembers(ArchiveMemberList &list, const Path &pattern, bool matchPathComponents = false) const override;
 
 	/**
 	 * Return a list of all the files in the cache.


Commit: ad8ffd0035d37d0bda17aa63555e8eed99f688a0
    https://github.com/scummvm/scummvm/commit/ad8ffd0035d37d0bda17aa63555e8eed99f688a0
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:52+01:00

Commit Message:
GUI: Initial code for Shader Browser. Zip selection works

Changed paths:
  A gui/shaderbrowser-dialog.cpp
  A gui/shaderbrowser-dialog.h
    gui/module.mk
    gui/options.cpp
    gui/themes/common/highres_layout.stx
    gui/themes/common/lowres_layout.stx


diff --git a/gui/module.mk b/gui/module.mk
index a4a87c4f884..e63fe4aaad8 100644
--- a/gui/module.mk
+++ b/gui/module.mk
@@ -21,6 +21,7 @@ MODULE_OBJS := \
 	predictivedialog.o \
 	saveload.o \
 	saveload-dialog.o \
+	shaderbrowser-dialog.o \
 	themebrowser.o \
 	ThemeEngine.o \
 	ThemeEval.o \
diff --git a/gui/options.cpp b/gui/options.cpp
index 0c988bdc841..f791da0cbfc 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "gui/browser.h"
+#include "gui/shaderbrowser-dialog.h"
 #include "gui/themebrowser.h"
 #include "gui/message.h"
 #include "gui/gui-manager.h"
@@ -1150,13 +1151,12 @@ void OptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
 		g_gui.scheduleTopDialogRedraw();
 		break;
 	case kChooseShaderCmd: {
-		BrowserDialog browser(_("Select shader"), false);
+		ShaderBrowserDialog browser;
 		if (browser.runModal() > 0) {
 			// User made his choice...
-			Common::FSNode file(browser.getResult());
-			_shader->setLabel(file.getPath());
+			_shader->setLabel(browser.getResult());
 
-			if (!file.getPath().empty() && (file.getPath().decode() != _c("None", "path")))
+			if (!browser.getResult().empty() && (browser.getResult().decode() != _c("None", "path")))
 				_shaderClearButton->setEnabled(true);
 			else
 				_shaderClearButton->setEnabled(false);
diff --git a/gui/shaderbrowser-dialog.cpp b/gui/shaderbrowser-dialog.cpp
new file mode 100644
index 00000000000..3eda4e43d1b
--- /dev/null
+++ b/gui/shaderbrowser-dialog.cpp
@@ -0,0 +1,139 @@
+/* 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/shaderbrowser-dialog.h"
+
+#include "common/system.h"
+#include "common/algorithm.h"
+#include "common/str-array.h"
+#include "common/zip-set.h"
+
+#include "common/translation.h"
+
+#include "gui/widgets/list.h"
+#include "gui/browser.h"
+#include "gui/gui-manager.h"
+#include "gui/message.h"
+
+namespace GUI {
+
+enum {
+	kChooseCmd = 'Chos',
+	kChooseFileCmd = 'File',
+};
+
+const char *kFileMask = "*.glslp";
+const char *kFileExt  = "glslp";
+
+ShaderBrowserDialog::ShaderBrowserDialog() : Dialog("ShaderBrowser") {
+
+	new StaticTextWidget(this, "ShaderBrowser.Headline", _("Choose shader for loading"));
+
+	_fileName = new EditTextWidget(this, "ShaderBrowser.Filename", Common::U32String());
+
+	// Add file list
+	_fileList = new ListWidget(this, "ShaderBrowser.List");
+	_fileList->setNumberingMode(kListNumberingOff);
+	_fileList->setEditable(false);
+
+	_backgroundType = GUI::ThemeEngine::kDialogBackgroundPlain;
+
+	// Buttons
+	new ButtonWidget(this, "ShaderBrowser.Cancel", _("Cancel"), Common::U32String(), kCloseCmd);
+	new ButtonWidget(this, "ShaderBrowser.Choose", _("Choose"), Common::U32String(), kChooseCmd);
+}
+
+void ShaderBrowserDialog::open() {
+	// Call super implementation
+	Dialog::open();
+
+	Common::generateZipSet(_shaderSet, "shaders.dat", "shaders*.dat");
+
+	updateListing();
+}
+
+void ShaderBrowserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
+	switch (cmd) {
+	case kChooseCmd:
+		if (_fileName->getEditString().empty())
+			break;
+
+		normalieFileName();
+
+		setResult(1);
+		close();
+		break;
+	case kChooseFileCmd: {
+		BrowserDialog browser(_("Select shader"), false);
+		if (browser.runModal() > 0) {
+			// User made his choice...
+			Common::FSNode file(browser.getResult());
+			_fileName->setEditString(file.getPath());
+
+			g_gui.scheduleTopDialogRedraw();
+		}
+		break;
+	}
+	case kListSelectionChangedCmd:
+		_fileName->setEditString(_fileList->getList().operator[](_fileList->getSelected()));
+		_fileName->markAsDirty();
+		break;
+	case kListItemActivatedCmd:
+	case kListItemDoubleClickedCmd:
+		normalieFileName();
+		setResult(1);
+		close();
+		break;
+	default:
+		Dialog::handleCommand(sender, cmd, data);
+	}
+}
+
+void ShaderBrowserDialog::normalieFileName() {
+	Common::String filename = Common::convertFromU32String(_fileName->getEditString());
+
+	if (filename.matchString(kFileMask, true))
+		return;
+
+	_fileName->setEditString(filename + "." + kFileExt);
+}
+
+
+void ShaderBrowserDialog::updateListing() {
+	Common::U32StringArray list;
+	Common::ArchiveMemberList files;
+
+	_shaderSet.listMatchingMembers(files, kFileMask, true);
+
+	Common::sort(files.begin(), files.end(), Common::ArchiveMemberListComparator());
+
+	for (auto &file : files) {
+		list.push_back(Common::U32String(file->getName()));
+	}
+
+	_fileList->setList(list);
+	_fileList->scrollTo(0);
+
+	// Finally, redraw
+	g_gui.scheduleTopDialogRedraw();
+}
+
+} // End of namespace GUI
diff --git a/gui/shaderbrowser-dialog.h b/gui/shaderbrowser-dialog.h
new file mode 100644
index 00000000000..c2ebd76e9a3
--- /dev/null
+++ b/gui/shaderbrowser-dialog.h
@@ -0,0 +1,60 @@
+/* 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 SHADERBROWSER_DIALOG_H
+#define SHADERBROWSER_DIALOG_H
+
+#include "gui/dialog.h"
+#include "gui/widgets/edittext.h"
+
+namespace GUI {
+
+class ListWidget;
+class EditTextWidget;
+class CommandSender;
+
+enum {
+	kFBModeLoad = 0,
+	kFBModeSave
+};
+
+class ShaderBrowserDialog : public Dialog {
+public:
+	ShaderBrowserDialog();
+
+	void open() override;
+
+	void handleCommand(CommandSender *sender, uint32 cmd, uint32 data) override;
+
+	Common::String getResult() { return Dialog::getResult() ? _fileName->getEditString().encode() : Common::String(); }
+
+protected:
+	EditTextWidget   *_fileName;
+	ListWidget	     *_fileList;
+	Common::SearchSet _shaderSet;
+
+	void updateListing();
+	void normalieFileName();
+};
+
+} // End of namespace GUI
+
+#endif
diff --git a/gui/themes/common/highres_layout.stx b/gui/themes/common/highres_layout.stx
index 85b3d8aab6b..32f5d76847e 100644
--- a/gui/themes/common/highres_layout.stx
+++ b/gui/themes/common/highres_layout.stx
@@ -377,6 +377,29 @@
 		</layout>
 	</dialog>
 
+	<dialog name = 'ShaderBrowser' overlays = 'screen' inset = '32' shading = 'dim'>
+		<layout type = 'vertical' padding = '16, 16, 16, 16'>
+			<widget name = 'Headline'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'Filename'
+					height = 'Globals.Line.Height'
+			/>
+			<space size = '10' />
+			<widget name = 'List'/>
+			<layout type = 'vertical' padding = '0, 0, 16, 0'>
+				<layout type = 'horizontal' padding = '0, 0, 0, 0'>
+					<widget name = 'Cancel'
+							type = 'Button'
+					/>
+					<widget name = 'Choose'
+							type = 'Button'
+					/>
+				</layout>
+			</layout>
+		</layout>
+	</dialog>
+
 	<dialog name = 'GlobalOptions' overlays = 'screen' inset = '32' shading = 'dim' resolution='x<800'>
 		<layout type = 'vertical' padding = '0, 0, 0, 0'>
 			<widget name = 'TabWidget' type = 'TabWidget'/>
diff --git a/gui/themes/common/lowres_layout.stx b/gui/themes/common/lowres_layout.stx
index 7f36735e4a9..ccf123d05b6 100644
--- a/gui/themes/common/lowres_layout.stx
+++ b/gui/themes/common/lowres_layout.stx
@@ -334,6 +334,29 @@
 		</layout>
 	</dialog>
 
+	<dialog name = 'ShaderBrowser' overlays = 'screen' inset = '16' shading = 'dim'>
+		<layout type = 'vertical' padding = '16, 16, 16, 16'>
+			<widget name = 'Headline'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'Filename'
+					height = 'Globals.Line.Height'
+			/>
+			<space size = '5' />
+			<widget name = 'List'/>
+			<layout type = 'vertical' padding = '0, 0, 16, 0'>
+				<layout type = 'horizontal' padding = '0, 0, 0, 0'>
+					<widget name = 'Cancel'
+							type = 'Button'
+					/>
+					<widget name = 'Choose'
+							type = 'Button'
+					/>
+				</layout>
+			</layout>
+		</layout>
+	</dialog>
+
 	<dialog name = 'GlobalOptions' overlays = 'screen' inset = '16' shading = 'dim'>
 		<layout type = 'vertical' padding = '0, 0, 0, 0'>
 			<widget name = 'TabWidget' type = 'TabWidget'/>


Commit: c1478cd1e6f7f8b02c6156ae4eceb565ec439526
    https://github.com/scummvm/scummvm/commit/c1478cd1e6f7f8b02c6156ae4eceb565ec439526
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:52+01:00

Commit Message:
GUI: Fixed search icon tooltip

Changed paths:
    gui/launcher.cpp


diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index 9f06cd9942c..fb1a0dec175 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -765,7 +765,7 @@ void LauncherDialog::reflowLayout() {
 
 	if (g_gui.xmlEval()->getVar("Globals.ShowSearchPic") == 1 && g_gui.theme()->supportsImages()) {
 		if (!_searchPic)
-			_searchPic = new GraphicsWidget(this, _title + ".SearchPic");
+			_searchPic = new GraphicsWidget(this, _title + ".SearchPic", _("Search in game list"));
 		_searchPic->setGfxFromTheme(ThemeEngine::kImageSearch);
 
 		if (_searchDesc) {


Commit: 0a9d3ca61609e3279f7497249b56262bae0ba1b4
    https://github.com/scummvm/scummvm/commit/0a9d3ca61609e3279f7497249b56262bae0ba1b4
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:52+01:00

Commit Message:
GUI: Added text filter to the ShaderBrowser

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


diff --git a/gui/shaderbrowser-dialog.cpp b/gui/shaderbrowser-dialog.cpp
index 3eda4e43d1b..678d37ad011 100644
--- a/gui/shaderbrowser-dialog.cpp
+++ b/gui/shaderbrowser-dialog.cpp
@@ -28,6 +28,7 @@
 
 #include "common/translation.h"
 
+#include "gui/ThemeEval.h"
 #include "gui/widgets/list.h"
 #include "gui/browser.h"
 #include "gui/gui-manager.h"
@@ -38,6 +39,9 @@ namespace GUI {
 enum {
 	kChooseCmd = 'Chos',
 	kChooseFileCmd = 'File',
+	kSearchCmd = 'SRCH',
+	kListSearchCmd = 'LSSR',
+	kSearchClearCmd = 'SRCL',
 };
 
 const char *kFileMask = "*.glslp";
@@ -49,6 +53,20 @@ ShaderBrowserDialog::ShaderBrowserDialog() : Dialog("ShaderBrowser") {
 
 	_fileName = new EditTextWidget(this, "ShaderBrowser.Filename", Common::U32String());
 
+	// Search box
+	_searchDesc = nullptr;
+#ifndef DISABLE_FANCY_THEMES
+	_searchPic = nullptr;
+	if (g_gui.xmlEval()->getVar("Globals.ShowSearchPic") == 1 && g_gui.theme()->supportsImages()) {
+		_searchPic = new GraphicsWidget(this, "ShaderBrowser.SearchPic", _("Search in game list"));
+		_searchPic->setGfxFromTheme(ThemeEngine::kImageSearch);
+	} else
+#endif
+		_searchDesc = new StaticTextWidget(this, "ShaderBrowser.SearchDesc", _("Search:"));
+
+	_searchWidget = new EditTextWidget(this, "ShaderBrowser.Search", _search, Common::U32String(), kSearchCmd);
+	_searchClearButton = addClearButton(this, "ShaderBrowser.SearchClearButton", kSearchClearCmd);
+
 	// Add file list
 	_fileList = new ListWidget(this, "ShaderBrowser.List");
 	_fileList->setNumberingMode(kListNumberingOff);
@@ -70,6 +88,28 @@ void ShaderBrowserDialog::open() {
 	updateListing();
 }
 
+void ShaderBrowserDialog::reflowLayout() {
+#ifndef DISABLE_FANCY_THEMES
+	if (g_gui.xmlEval()->getVar("Globals.ShowSearchPic") == 1 && g_gui.theme()->supportsImages()) {
+		if (!_searchPic)
+			_searchPic = new GraphicsWidget(this, "ShaderBrowser.SearchPic", _("Search in game list"));
+		_searchPic->setGfxFromTheme(ThemeEngine::kImageSearch);
+	} else {
+		if (_searchPic) {
+			removeWidget(_searchPic);
+			g_gui.addToTrash(_searchPic, this);
+			_searchPic = nullptr;
+		}
+	}
+#endif
+
+	removeWidget(_searchClearButton);
+	g_gui.addToTrash(_searchClearButton, this);
+	_searchClearButton = addClearButton(this, "ShaderBrowser.SearchClearButton", kSearchClearCmd);
+
+	Dialog::reflowLayout();
+}
+
 void ShaderBrowserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
 	switch (cmd) {
 	case kChooseCmd:
@@ -92,6 +132,15 @@ void ShaderBrowserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
 		}
 		break;
 	}
+	case kSearchCmd:
+		// Update the active search filter.
+		_fileList->setFilter(_searchWidget->getEditString());
+		break;
+	case kSearchClearCmd:
+		// Reset the active search filter, thus showing all games again
+		_searchWidget->setEditString(Common::U32String());
+		_fileList->setFilter(Common::U32String());
+		break;
 	case kListSelectionChangedCmd:
 		_fileName->setEditString(_fileList->getList().operator[](_fileList->getSelected()));
 		_fileName->markAsDirty();
diff --git a/gui/shaderbrowser-dialog.h b/gui/shaderbrowser-dialog.h
index c2ebd76e9a3..2008616f885 100644
--- a/gui/shaderbrowser-dialog.h
+++ b/gui/shaderbrowser-dialog.h
@@ -41,6 +41,7 @@ public:
 	ShaderBrowserDialog();
 
 	void open() override;
+	void reflowLayout() override;
 
 	void handleCommand(CommandSender *sender, uint32 cmd, uint32 data) override;
 
@@ -50,6 +51,14 @@ protected:
 	EditTextWidget   *_fileName;
 	ListWidget	     *_fileList;
 	Common::SearchSet _shaderSet;
+	Common::String	  _search;
+
+	EditTextWidget   *_searchWidget;
+#ifndef DISABLE_FANCY_THEMES
+	GraphicsWidget	 *_searchPic;
+#endif
+	StaticTextWidget *_searchDesc;
+	ButtonWidget     *_searchClearButton;
 
 	void updateListing();
 	void normalieFileName();
diff --git a/gui/themes/common/highres_layout.stx b/gui/themes/common/highres_layout.stx
index 32f5d76847e..54eb19b6712 100644
--- a/gui/themes/common/highres_layout.stx
+++ b/gui/themes/common/highres_layout.stx
@@ -386,6 +386,21 @@
 					height = 'Globals.Line.Height'
 			/>
 			<space size = '10' />
+			<layout type = 'horizontal'  spacing = '5' padding = '10, 0, 0, 0'>
+				<widget name = 'SearchPic'
+						width = '16'
+						height = '17'
+						rtl = 'no'
+				/>
+				<widget name = 'Search'
+						width = '120'
+						height = 'Globals.Line.Height'
+				/>
+				<widget name = 'SearchClearButton'
+						height = 'Globals.Line.Height'
+						width = 'Globals.Line.Height'
+				/>
+			</layout>
 			<widget name = 'List'/>
 			<layout type = 'vertical' padding = '0, 0, 16, 0'>
 				<layout type = 'horizontal' padding = '0, 0, 0, 0'>
diff --git a/gui/themes/common/lowres_layout.stx b/gui/themes/common/lowres_layout.stx
index ccf123d05b6..3d043ed3b3b 100644
--- a/gui/themes/common/lowres_layout.stx
+++ b/gui/themes/common/lowres_layout.stx
@@ -343,6 +343,20 @@
 					height = 'Globals.Line.Height'
 			/>
 			<space size = '5' />
+			<layout type = 'horizontal' spacing = '2' padding = '0, 0, 0, 0'>
+				<widget name = 'SearchDesc'
+						width = '45'
+						height = 'Globals.Line.Height'
+						textalign = 'end'
+				/>
+				<widget name = 'Search'
+						height = 'Globals.Line.Height'
+				/>
+				<widget name = 'SearchClearButton'
+						height = 'Globals.Line.Height'
+						width = 'Globals.Line.Height'
+				/>
+			</layout>
 			<widget name = 'List'/>
 			<layout type = 'vertical' padding = '0, 0, 16, 0'>
 				<layout type = 'horizontal' padding = '0, 0, 0, 0'>


Commit: 8f469af5dcc8a1e9f6617559e0898ddf98c19c0b
    https://github.com/scummvm/scummvm/commit/8f469af5dcc8a1e9f6617559e0898ddf98c19c0b
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:52+01:00

Commit Message:
GUI: Added alternate file picker to ShaderBrowser

Changed paths:
    gui/options.cpp
    gui/shaderbrowser-dialog.cpp
    gui/shaderbrowser-dialog.h
    gui/themes/common/highres_layout.stx
    gui/themes/common/lowres_layout.stx
    po/POTFILES


diff --git a/gui/options.cpp b/gui/options.cpp
index f791da0cbfc..9b666a8f034 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -1151,7 +1151,7 @@ void OptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
 		g_gui.scheduleTopDialogRedraw();
 		break;
 	case kChooseShaderCmd: {
-		ShaderBrowserDialog browser;
+		ShaderBrowserDialog browser(ConfMan.get("shader", _domain));
 		if (browser.runModal() > 0) {
 			// User made his choice...
 			_shader->setLabel(browser.getResult());
diff --git a/gui/shaderbrowser-dialog.cpp b/gui/shaderbrowser-dialog.cpp
index 678d37ad011..87a4ebeea0c 100644
--- a/gui/shaderbrowser-dialog.cpp
+++ b/gui/shaderbrowser-dialog.cpp
@@ -47,11 +47,12 @@ enum {
 const char *kFileMask = "*.glslp";
 const char *kFileExt  = "glslp";
 
-ShaderBrowserDialog::ShaderBrowserDialog() : Dialog("ShaderBrowser") {
+ShaderBrowserDialog::ShaderBrowserDialog(const Common::String &initialSelection) : Dialog("ShaderBrowser") {
 
-	new StaticTextWidget(this, "ShaderBrowser.Headline", _("Choose shader for loading"));
+	new StaticTextWidget(this, "ShaderBrowser.Headline", _("Choose shader from the list below (or pick a file instead)"));
 
 	_fileName = new EditTextWidget(this, "ShaderBrowser.Filename", Common::U32String());
+	_fileName->setEditString(initialSelection);
 
 	// Search box
 	_searchDesc = nullptr;
@@ -67,6 +68,8 @@ ShaderBrowserDialog::ShaderBrowserDialog() : Dialog("ShaderBrowser") {
 	_searchWidget = new EditTextWidget(this, "ShaderBrowser.Search", _search, Common::U32String(), kSearchCmd);
 	_searchClearButton = addClearButton(this, "ShaderBrowser.SearchClearButton", kSearchClearCmd);
 
+	new ButtonWidget(this, "ShaderBrowser.BrowseFile", _("Pick file instead..."), _("Pick shader from file system"), kChooseFileCmd);
+
 	// Add file list
 	_fileList = new ListWidget(this, "ShaderBrowser.List");
 	_fileList->setNumberingMode(kListNumberingOff);
@@ -128,7 +131,8 @@ void ShaderBrowserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
 			Common::FSNode file(browser.getResult());
 			_fileName->setEditString(file.getPath());
 
-			g_gui.scheduleTopDialogRedraw();
+			setResult(1);
+			close();
 		}
 		break;
 	}
diff --git a/gui/shaderbrowser-dialog.h b/gui/shaderbrowser-dialog.h
index 2008616f885..6cfeb3e6e56 100644
--- a/gui/shaderbrowser-dialog.h
+++ b/gui/shaderbrowser-dialog.h
@@ -38,7 +38,7 @@ enum {
 
 class ShaderBrowserDialog : public Dialog {
 public:
-	ShaderBrowserDialog();
+	ShaderBrowserDialog(const Common::String &initialSelection);
 
 	void open() override;
 	void reflowLayout() override;
diff --git a/gui/themes/common/highres_layout.stx b/gui/themes/common/highres_layout.stx
index 54eb19b6712..5747d390b16 100644
--- a/gui/themes/common/highres_layout.stx
+++ b/gui/themes/common/highres_layout.stx
@@ -410,6 +410,10 @@
 					<widget name = 'Choose'
 							type = 'Button'
 					/>
+					<space/>
+					<widget name = 'BrowseFile'
+							type = 'Button'
+					/>
 				</layout>
 			</layout>
 		</layout>
diff --git a/gui/themes/common/lowres_layout.stx b/gui/themes/common/lowres_layout.stx
index 3d043ed3b3b..edafcd87a28 100644
--- a/gui/themes/common/lowres_layout.stx
+++ b/gui/themes/common/lowres_layout.stx
@@ -366,6 +366,10 @@
 					<widget name = 'Choose'
 							type = 'Button'
 					/>
+					<space/>
+					<widget name = 'BrowseFile'
+							type = 'Button'
+					/>
 				</layout>
 			</layout>
 		</layout>
diff --git a/po/POTFILES b/po/POTFILES
index 9b74187b98f..a2213c0db0b 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -19,6 +19,7 @@ gui/predictivedialog.cpp
 gui/recorderdialog.cpp
 gui/remotebrowser.cpp
 gui/saveload-dialog.cpp
+gui/shaderbrowser-dialog.cpp
 gui/themebrowser.cpp
 gui/ThemeEngine.cpp
 gui/unknown-game-dialog.cpp


Commit: 5de84d8724e24fb2a98fa8b81205d55dc09bafab
    https://github.com/scummvm/scummvm/commit/5de84d8724e24fb2a98fa8b81205d55dc09bafab
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:53+01:00

Commit Message:
GUI: Added button for updating shaders

Changed paths:
    gui/options.cpp
    gui/themes/common/highres_layout.stx
    gui/themes/common/lowres_layout.stx


diff --git a/gui/options.cpp b/gui/options.cpp
index 9b666a8f034..1fadb3153da 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -96,6 +96,7 @@ enum {
 	kPluginsPathClearCmd	= 'clpl',
 	kChooseThemeCmd			= 'chtf',
 	kUpdateIconsCmd			= 'upic',
+	kUpdateShadersCmd		= 'upsh',
 	kChooseShaderCmd        = 'chsh',
 	kClearShaderCmd         = 'clsh',
 	kUpdatesCheckCmd		= 'updc',
@@ -1573,6 +1574,12 @@ void OptionsDialog::addGraphicControls(GuiObject *boss, const Common::String &pr
 		_shader = new StaticTextWidget(boss, prefix + "grShader", _c("None", "shader"), _("Specifies path to the shader used for scaling the game screen"));
 
 		_shaderClearButton = addClearButton(boss, prefix + "grShaderClearButton", kClearShaderCmd);
+
+#ifdef USE_CLOUD
+#ifdef USE_LIBCURL
+		new ButtonWidget(boss, prefix + "UpdateShadersButton", _("Update Shaders"), _("Check for updates of shader packs"), kUpdateShadersCmd);
+#endif
+#endif
 	}
 
 	// Fullscreen checkbox
@@ -2511,7 +2518,7 @@ void GlobalOptionsDialog::addGUIControls(GuiObject *boss, const Common::String &
 
 #ifdef USE_CLOUD
 #ifdef USE_LIBCURL
-	new ButtonWidget(boss, prefix + "UpdateIconsButton", _("Update Icons"), Common::U32String(), kUpdateIconsCmd);
+	new ButtonWidget(boss, prefix + "UpdateIconsButton", _("Update Icons"),  _("Check for updates of icon packs"), kUpdateIconsCmd);
 #endif
 #endif
 }
diff --git a/gui/themes/common/highres_layout.stx b/gui/themes/common/highres_layout.stx
index 5747d390b16..f4348d1910c 100644
--- a/gui/themes/common/highres_layout.stx
+++ b/gui/themes/common/highres_layout.stx
@@ -552,6 +552,9 @@
 						height = 'Globals.Line.Height'
 						width = 'Globals.Line.Height'
 				/>
+				<widget name = 'UpdateShadersButton'
+						type = 'Button'
+				/>
 			</layout>
 			<widget name = 'grAspectCheckbox'
 					type = 'Checkbox'
diff --git a/gui/themes/common/lowres_layout.stx b/gui/themes/common/lowres_layout.stx
index edafcd87a28..15019688b8e 100644
--- a/gui/themes/common/lowres_layout.stx
+++ b/gui/themes/common/lowres_layout.stx
@@ -490,6 +490,9 @@
 						height = 'Globals.Line.Height'
 						width = 'Globals.Line.Height'
 				/>
+				<widget name = 'UpdateShadersButton'
+						type = 'Button'
+				/>
 			</layout>
 			<widget name = 'grAspectCheckbox'
 					type = 'Checkbox'


Commit: ee33e9935707c95f297d28f9980bc97ebc088120
    https://github.com/scummvm/scummvm/commit/ee33e9935707c95f297d28f9980bc97ebc088120
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:53+01:00

Commit Message:
GUI: Rename downloadiconsdialog.* -> downloadpacksdialog.*

Changed paths:
  A gui/downloadpacksdialog.cpp
  A gui/downloadpacksdialog.h
  R gui/downloadiconsdialog.cpp
  R gui/downloadiconsdialog.h
    gui/module.mk
    gui/options.cpp


diff --git a/gui/downloadiconsdialog.cpp b/gui/downloadpacksdialog.cpp
similarity index 99%
rename from gui/downloadiconsdialog.cpp
rename to gui/downloadpacksdialog.cpp
index 9b65301ab38..f9fbe9e86bc 100644
--- a/gui/downloadiconsdialog.cpp
+++ b/gui/downloadpacksdialog.cpp
@@ -20,7 +20,7 @@
  */
 
 #include "backends/networking/curl/request.h"
-#include "gui/downloadiconsdialog.h"
+#include "gui/downloadpacksdialog.h"
 #include "gui/downloaddialog.h"
 #include "backends/networking/curl/session.h"
 #include "common/config-manager.h"
diff --git a/gui/downloadiconsdialog.h b/gui/downloadpacksdialog.h
similarity index 100%
rename from gui/downloadiconsdialog.h
rename to gui/downloadpacksdialog.h
diff --git a/gui/module.mk b/gui/module.mk
index e63fe4aaad8..e7db62dd677 100644
--- a/gui/module.mk
+++ b/gui/module.mk
@@ -47,7 +47,7 @@ ifdef USE_CLOUD
 ifdef USE_LIBCURL
 MODULE_OBJS += \
 	downloaddialog.o \
-	downloadiconsdialog.o \
+	downloadpacksdialog.o \
 	remotebrowser.o
 endif
 endif
diff --git a/gui/options.cpp b/gui/options.cpp
index 1fadb3153da..97617a704d4 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -58,7 +58,7 @@
 #ifdef USE_LIBCURL
 #include "backends/cloud/cloudmanager.h"
 #include "gui/downloaddialog.h"
-#include "gui/downloadiconsdialog.h"
+#include "gui/downloadpacksdialog.h"
 #endif
 
 #ifdef USE_SDL_NET


Commit: 4d0f0fda52161e035c229e684df01b2a41424490
    https://github.com/scummvm/scummvm/commit/4d0f0fda52161e035c229e684df01b2a41424490
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:53+01:00

Commit Message:
GUI: Renamed DownloadIconsDialog -> DownloadPacksDialog

Changed paths:
    gui/downloadpacksdialog.cpp
    gui/downloadpacksdialog.h
    gui/options.cpp
    gui/themes/common/highres_layout.stx
    gui/themes/common/lowres_layout.stx
    gui/themes/scummclassic/classic_layout.stx
    gui/themes/scummclassic/classic_layout_lowres.stx


diff --git a/gui/downloadpacksdialog.cpp b/gui/downloadpacksdialog.cpp
index f9fbe9e86bc..9a6bd3c2ad0 100644
--- a/gui/downloadpacksdialog.cpp
+++ b/gui/downloadpacksdialog.cpp
@@ -47,7 +47,7 @@ enum {
 };
 
 struct DialogState {
-	DownloadIconsDialog *dialog;
+	DownloadPacksDialog *dialog;
 	Networking::Session session;
 	Common::HashMap<Common::String, uint32> fileHash;
 	IconProcessState state;
@@ -116,7 +116,7 @@ void DialogState::downloadListCallback(Networking::DataResponse r) {
 
 		size_t pos = s.findFirstOf(',');
 		if (pos == Common::String::npos) {
-			warning("DownloadIconsDialog: wrong string format at line %d: <%s>", nline, s.c_str());
+			warning("DownloadPacksDialog: wrong string format at line %d: <%s>", nline, s.c_str());
 			continue;
 		}
 
@@ -168,26 +168,26 @@ static uint32 getDownloadSpeed() {
 	return speed;
 }
 
-DownloadIconsDialog::DownloadIconsDialog() :
-	Dialog("GlobalOptions_DownloadIconsDialog"), CommandSender(this), _close(false) {
+DownloadPacksDialog::DownloadPacksDialog() :
+	Dialog("GlobalOptions_DownloadPacksDialog"), CommandSender(this), _close(false) {
 
 	_backgroundType = GUI::ThemeEngine::kDialogBackgroundPlain;
 
-	_statusText = new StaticTextWidget(this, "GlobalOptions_DownloadIconsDialog.StatusText", _("Downloading icons list..."));
-	_errorText = new StaticTextWidget(this, "GlobalOptions_DownloadIconsDialog.ErrorText", Common::U32String(""));
+	_statusText = new StaticTextWidget(this, "GlobalOptions_DownloadPacksDialog.StatusText", _("Downloading icons list..."));
+	_errorText = new StaticTextWidget(this, "GlobalOptions_DownloadPacksDialog.ErrorText", Common::U32String(""));
 
 	uint32 progress = getDownloadingProgress();
-	_progressBar = new SliderWidget(this, "GlobalOptions_DownloadIconsDialog.ProgressBar");
+	_progressBar = new SliderWidget(this, "GlobalOptions_DownloadPacksDialog.ProgressBar");
 	_progressBar->setMinValue(0);
 	_progressBar->setMaxValue(100);
 	_progressBar->setValue(progress);
 	_progressBar->setEnabled(false);
-	_percentLabel = new StaticTextWidget(this, "GlobalOptions_DownloadIconsDialog.PercentText", Common::String::format("%u %%", progress));
-	_downloadSizeLabel = new StaticTextWidget(this, "GlobalOptions_DownloadIconsDialog.DownloadSize", Common::U32String());
-	_downloadSpeedLabel = new StaticTextWidget(this, "GlobalOptions_DownloadIconsDialog.DownloadSpeed", Common::U32String());
-	_cancelButton = new ButtonWidget(this, "GlobalOptions_DownloadIconsDialog.MainButton", _("Cancel download"), Common::U32String(), kCleanupCmd);
-	_closeButton = new ButtonWidget(this, "GlobalOptions_DownloadIconsDialog.CloseButton", _("Hide"), Common::U32String(), kCloseCmd);
-	_clearCacheButton = new ButtonWidget(this, "GlobalOptions_DownloadIconsDialog.ResetButton", _("Clear Cache"), Common::U32String(), kClearCacheCmd);
+	_percentLabel = new StaticTextWidget(this, "GlobalOptions_DownloadPacksDialog.PercentText", Common::String::format("%u %%", progress));
+	_downloadSizeLabel = new StaticTextWidget(this, "GlobalOptions_DownloadPacksDialog.DownloadSize", Common::U32String());
+	_downloadSpeedLabel = new StaticTextWidget(this, "GlobalOptions_DownloadPacksDialog.DownloadSpeed", Common::U32String());
+	_cancelButton = new ButtonWidget(this, "GlobalOptions_DownloadPacksDialog.MainButton", _("Cancel download"), Common::U32String(), kCleanupCmd);
+	_closeButton = new ButtonWidget(this, "GlobalOptions_DownloadPacksDialog.CloseButton", _("Hide"), Common::U32String(), kCloseCmd);
+	_clearCacheButton = new ButtonWidget(this, "GlobalOptions_DownloadPacksDialog.ResetButton", _("Clear Cache"), Common::U32String(), kClearCacheCmd);
 
 	if (!g_state) {
 		g_state = new DialogState;
@@ -206,23 +206,23 @@ DownloadIconsDialog::DownloadIconsDialog() :
 	}
 }
 
-DownloadIconsDialog::~DownloadIconsDialog() {
+DownloadPacksDialog::~DownloadPacksDialog() {
 }
 
-void DownloadIconsDialog::open() {
+void DownloadPacksDialog::open() {
 	Dialog::open();
 	reflowLayout();
 	g_gui.scheduleTopDialogRedraw();
 }
 
-void DownloadIconsDialog::close() {
+void DownloadPacksDialog::close() {
 	if (g_state)
 		g_state->dialog = nullptr;
 
 	Dialog::close();
 }
 
-void DownloadIconsDialog::setState(IconProcessState state) {
+void DownloadPacksDialog::setState(IconProcessState state) {
 	g_state->state = state;
 
 	switch (state) {
@@ -289,7 +289,7 @@ void DownloadIconsDialog::setState(IconProcessState state) {
 	}
 }
 
-void DownloadIconsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
+void DownloadPacksDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
 	switch (cmd) {
 	case kCleanupCmd:
 		{
@@ -326,7 +326,7 @@ void DownloadIconsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
 	}
 }
 
-void DownloadIconsDialog::handleTickle() {
+void DownloadPacksDialog::handleTickle() {
 	if (_close) {
 		close();
 		_close = false;
@@ -342,26 +342,26 @@ void DownloadIconsDialog::handleTickle() {
 	Dialog::handleTickle();
 }
 
-void DownloadIconsDialog::reflowLayout() {
+void DownloadPacksDialog::reflowLayout() {
 	Dialog::reflowLayout();
 	refreshWidgets();
 }
 
-Common::U32String DownloadIconsDialog::getSizeLabelText() {
+Common::U32String DownloadPacksDialog::getSizeLabelText() {
 	Common::String downloaded, downloadedUnits, total, totalUnits;
 	downloaded = getHumanReadableBytes(g_state->downloadedSize, downloadedUnits);
 	total = getHumanReadableBytes(g_state->totalSize, totalUnits);
 	return Common::U32String::format(_("Downloaded %s %S / %s %S"), downloaded.c_str(), _(downloadedUnits).c_str(), total.c_str(), _(totalUnits).c_str());
 }
 
-Common::U32String DownloadIconsDialog::getSpeedLabelText() {
+Common::U32String DownloadPacksDialog::getSpeedLabelText() {
 	Common::String speed, speedUnits;
 	speed = getHumanReadableBytes(getDownloadSpeed(), speedUnits);
 	speedUnits += "/s";
 	return Common::U32String::format(_("Download speed: %s %S"), speed.c_str(), _(speedUnits).c_str());
 }
 
-void DownloadIconsDialog::refreshWidgets() {
+void DownloadPacksDialog::refreshWidgets() {
 	uint32 progress = getDownloadingProgress();
 	_percentLabel->setLabel(Common::String::format("%u %%", progress));
 	_downloadSizeLabel->setLabel(getSizeLabelText());
@@ -369,14 +369,14 @@ void DownloadIconsDialog::refreshWidgets() {
 	_progressBar->setValue(progress);
 }
 
-void DownloadIconsDialog::setError(Common::U32String &msg) {
+void DownloadPacksDialog::setError(Common::U32String &msg) {
 	_errorText->setLabel(msg);
 
 	_cancelButton->setLabel(_("Close"));
 	_cancelButton->setCmd(kCleanupCmd);
 }
 
-void DownloadIconsDialog::calculateList() {
+void DownloadPacksDialog::calculateList() {
 	Common::String iconsPath = ConfMan.get("iconspath");
 	if (iconsPath.empty()) {
 		Common::U32String str(_("ERROR: No icons path set"));
@@ -422,7 +422,7 @@ void DownloadIconsDialog::calculateList() {
 	setState(kDownloadStateListCalculated);
 }
 
-void DownloadIconsDialog::clearCache() {
+void DownloadPacksDialog::clearCache() {
 	Common::String iconsPath = ConfMan.get("iconspath");
 	if (iconsPath.empty()) {
 		Common::U32String str(_("ERROR: No icons path set"));
diff --git a/gui/downloadpacksdialog.h b/gui/downloadpacksdialog.h
index 016c2e52326..786570beb94 100644
--- a/gui/downloadpacksdialog.h
+++ b/gui/downloadpacksdialog.h
@@ -19,8 +19,8 @@
  *
  */
 
-#ifndef GUI_DOWNLOADICONSDIALOG_H
-#define GUI_DOWNLOADICONSDIALOG_H
+#ifndef GUI_DOWNLOADPACKSDIALOG_H
+#define GUI_DOWNLOADPACKSDIALOG_H
 
 #include "gui/dialog.h"
 #include "common/str.h"
@@ -45,7 +45,7 @@ enum IconProcessState {
 	kDownloadComplete
 };
 
-class DownloadIconsDialog : public Dialog, public CommandSender {
+class DownloadPacksDialog : public Dialog, public CommandSender {
 	StaticTextWidget *_statusText;
 	StaticTextWidget *_errorText;
 	StaticTextWidget *_percentLabel;
@@ -65,8 +65,8 @@ class DownloadIconsDialog : public Dialog, public CommandSender {
 	void refreshWidgets();
 
 public:
-	DownloadIconsDialog();
-	~DownloadIconsDialog() override;
+	DownloadPacksDialog();
+	~DownloadPacksDialog() override;
 
 	void open() override;
 	void close() override;
diff --git a/gui/options.cpp b/gui/options.cpp
index 97617a704d4..2ebe2bd7782 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -3110,7 +3110,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
 
 #ifdef USE_LIBCURL
 	case kUpdateIconsCmd: {
-		DownloadIconsDialog dia;
+		DownloadPacksDialog dia;
 		dia.runModal();
 		break;
 	}
diff --git a/gui/themes/common/highres_layout.stx b/gui/themes/common/highres_layout.stx
index f4348d1910c..29bb5301638 100644
--- a/gui/themes/common/highres_layout.stx
+++ b/gui/themes/common/highres_layout.stx
@@ -1120,7 +1120,7 @@
 		</layout>
 	</dialog>
 
-	<dialog name = 'GlobalOptions_DownloadIconsDialog' overlays = 'Dialog.GlobalOptions' shading = 'dim'>
+	<dialog name = 'GlobalOptions_DownloadPacksDialog' overlays = 'Dialog.GlobalOptions' shading = 'dim'>
 		<layout type = 'vertical' padding = '16, 16, 16, 8' spacing = '8'>
 			<widget name = 'StatusText'
 					height = 'Globals.Line.Height'
diff --git a/gui/themes/common/lowres_layout.stx b/gui/themes/common/lowres_layout.stx
index 15019688b8e..d77bd40234c 100644
--- a/gui/themes/common/lowres_layout.stx
+++ b/gui/themes/common/lowres_layout.stx
@@ -1072,7 +1072,7 @@
 		</layout>
 	</dialog>
 
-	<dialog name = 'GlobalOptions_DownloadIconsDialog' overlays = 'Dialog.GlobalOptions' shading = 'dim'>
+	<dialog name = 'GlobalOptions_DownloadPacksDialog' overlays = 'Dialog.GlobalOptions' shading = 'dim'>
 		<layout type = 'vertical' padding = '8, 8, 8, 4' spacing = '8'>
 			<widget name = 'StatusText'
 					height = 'Globals.Line.Height'
diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx
index fb51079a41a..8f1e090f832 100644
--- a/gui/themes/scummclassic/classic_layout.stx
+++ b/gui/themes/scummclassic/classic_layout.stx
@@ -927,7 +927,7 @@
 		</layout>
 	</dialog>
 
-	<dialog name = 'GlobalOptions_DownloadIconsDialog' overlays = 'Dialog.GlobalOptions' shading = 'dim'>
+	<dialog name = 'GlobalOptions_DownloadPacksDialog' overlays = 'Dialog.GlobalOptions' shading = 'dim'>
 		<layout type = 'vertical' padding = '16, 16, 16, 8' spacing = '8'>
 			<widget name = 'StatusText'
 					height = 'Globals.Line.Height'
diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx
index 38fc007f7cd..30048f61149 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -950,7 +950,7 @@
 		</layout>
 	</dialog>
 
-	<dialog name = 'GlobalOptions_DownloadIconsDialog' overlays = 'Dialog.GlobalOptions' shading = 'dim'>
+	<dialog name = 'GlobalOptions_DownloadPacksDialog' overlays = 'Dialog.GlobalOptions' shading = 'dim'>
 		<layout type = 'vertical' padding = '8, 8, 8, 4' spacing = '8'>
 			<widget name = 'StatusText'
 					height = 'Globals.Line.Height'


Commit: 31afcec77cc45ce362bf7c0486a857f08b34d794
    https://github.com/scummvm/scummvm/commit/31afcec77cc45ce362bf7c0486a857f08b34d794
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:53+01:00

Commit Message:
GUI: Generalize DownloadPacksDialog

Changed paths:
    gui/downloadpacksdialog.cpp
    gui/downloadpacksdialog.h
    gui/options.cpp


diff --git a/gui/downloadpacksdialog.cpp b/gui/downloadpacksdialog.cpp
index 9a6bd3c2ad0..fd4e57c80e1 100644
--- a/gui/downloadpacksdialog.cpp
+++ b/gui/downloadpacksdialog.cpp
@@ -55,8 +55,14 @@ struct DialogState {
 	uint32 totalSize;
 	uint32 totalFiles;
 	uint32 startTime;
+	const char *listfname;
 
-	DialogState() { state = kDownloadStateNone; downloadedSize = totalSize = totalFiles = startTime = 0; dialog = nullptr; }
+	DialogState(const char *fname) {
+		listfname = fname;
+		state = kDownloadStateNone;
+		downloadedSize = totalSize = totalFiles = startTime = 0;
+		dialog = nullptr;
+	}
 
 	void downloadList();
 	void proceedDownload();
@@ -71,7 +77,7 @@ private:
 
 
 void DialogState::downloadList() {
-	Networking::SessionRequest *rq = session.get("https://downloads.scummvm.org/frs/icons/LIST", "",
+	Networking::SessionRequest *rq = session.get(Common::String::format("https://downloads.scummvm.org/frs/icons/%s", listfname), "",
 		new Common::Callback<DialogState, Networking::DataResponse>(this, &DialogState::downloadListCallback),
 		new Common::Callback<DialogState, Networking::ErrorResponse>(this, &DialogState::errorCallback),
 		true);
@@ -168,12 +174,14 @@ static uint32 getDownloadSpeed() {
 	return speed;
 }
 
-DownloadPacksDialog::DownloadPacksDialog() :
-	Dialog("GlobalOptions_DownloadPacksDialog"), CommandSender(this), _close(false) {
+DownloadPacksDialog::DownloadPacksDialog(Common::U32String packname, const char *listfname, const char *packsglob) :
+	Dialog("GlobalOptions_DownloadPacksDialog"), CommandSender(this), _close(false), _packname(packname),
+	_packsglob(packsglob) {
 
 	_backgroundType = GUI::ThemeEngine::kDialogBackgroundPlain;
 
-	_statusText = new StaticTextWidget(this, "GlobalOptions_DownloadPacksDialog.StatusText", _("Downloading icons list..."));
+	// I18N: String like "Downloading icon packs list..."
+	_statusText = new StaticTextWidget(this, "GlobalOptions_DownloadPacksDialog.StatusText", Common::U32String::format(_("Downloading %S list..."), _packname.c_str()));
 	_errorText = new StaticTextWidget(this, "GlobalOptions_DownloadPacksDialog.ErrorText", Common::U32String(""));
 
 	uint32 progress = getDownloadingProgress();
@@ -190,7 +198,7 @@ DownloadPacksDialog::DownloadPacksDialog() :
 	_clearCacheButton = new ButtonWidget(this, "GlobalOptions_DownloadPacksDialog.ResetButton", _("Clear Cache"), Common::U32String(), kClearCacheCmd);
 
 	if (!g_state) {
-		g_state = new DialogState;
+		g_state = new DialogState(listfname);
 
 		g_state->dialog = this;
 
@@ -228,7 +236,7 @@ void DownloadPacksDialog::setState(IconProcessState state) {
 	switch (state) {
 	case kDownloadStateNone:
 	case kDownloadStateList:
-		_statusText->setLabel(_("Downloading icons list..."));
+		_statusText->setLabel(Common::U32String::format(_("Downloading %S list..."), _packname.c_str()));
 		_cancelButton->setLabel(_("Cancel download"));
 		_cancelButton->setCmd(kCleanupCmd);
 		_closeButton->setVisible(true);
@@ -238,7 +246,7 @@ void DownloadPacksDialog::setState(IconProcessState state) {
 		break;
 
 	case kDownloadStateListDownloaded:
-		_statusText->setLabel(Common::U32String::format(_("Downloading icons list... %d entries"), g_state->fileHash.size()));
+		_statusText->setLabel(Common::U32String::format(_("Downloading %S list... %d entries"), _packname.c_str(), g_state->fileHash.size()));
 		_cancelButton->setLabel(_("Cancel download"));
 		_cancelButton->setCmd(kCleanupCmd);
 		_closeButton->setVisible(true);
@@ -390,7 +398,7 @@ void DownloadPacksDialog::calculateList() {
 
 	Common::ArchiveMemberList iconFiles;
 
-	iconDir->listMatchingMembers(iconFiles, "gui-icons*.dat");
+	iconDir->listMatchingMembers(iconFiles, _packsglob);
 
 	for (auto ic = iconFiles.begin(); ic != iconFiles.end(); ++ic) {
 		Common::String fname = (*ic)->getName();
@@ -413,7 +421,8 @@ void DownloadPacksDialog::calculateList() {
 	g_state->totalFiles = g_state->fileHash.size();
 
 	if (g_state->totalSize == 0) {
-		Common::U32String error(_("No new icons packs available"));
+		// I18N: String like "No new icon packs available"
+		Common::U32String error(Common::U32String::format(_("No new %S available"), _packname.c_str()));
 		_closeButton->setEnabled(false);
 		setError(error);
 		return;
@@ -434,7 +443,7 @@ void DownloadPacksDialog::clearCache() {
 
 	Common::ArchiveMemberList iconFiles;
 
-	iconDir->listMatchingMembers(iconFiles, "gui-icons*.dat");
+	iconDir->listMatchingMembers(iconFiles, _packsglob);
 	int totalSize = 0;
 
 	for (auto ic = iconFiles.begin(); ic != iconFiles.end(); ++ic) {
@@ -458,7 +467,7 @@ void DownloadPacksDialog::clearCache() {
 			Common::FSNode fs(Common::Path(iconsPath).join(fname));
 			Common::WriteStream *str = fs.createWriteStream();
 
-			// Overwrite previously downloaded icon files with dummy data
+			// Overwrite previously downloaded pack files with dummy data
 			str->writeByte(0);
 			str->finalize();
 		}
@@ -467,7 +476,7 @@ void DownloadPacksDialog::clearCache() {
 		// Reload (now empty) icons set
 		g_gui.initIconsSet();
 
-		// Fetch current icons list file and re-trigger downloads
+		// Fetch current packs list file and re-trigger downloads
 		g_state->downloadList();
 		calculateList();
 		_cancelButton->setVisible(true);
diff --git a/gui/downloadpacksdialog.h b/gui/downloadpacksdialog.h
index 786570beb94..07d6b8be74a 100644
--- a/gui/downloadpacksdialog.h
+++ b/gui/downloadpacksdialog.h
@@ -56,6 +56,9 @@ class DownloadPacksDialog : public Dialog, public CommandSender {
 	ButtonWidget *_closeButton;
 	ButtonWidget *_clearCacheButton;
 
+	Common::U32String _packname;
+	const char *_packsglob;
+
 	Common::String _localDirectory;
 	bool _close;
 
@@ -65,7 +68,7 @@ class DownloadPacksDialog : public Dialog, public CommandSender {
 	void refreshWidgets();
 
 public:
-	DownloadPacksDialog();
+	DownloadPacksDialog(Common::U32String packname, const char *listfname, const char *packsglob);
 	~DownloadPacksDialog() override;
 
 	void open() override;
diff --git a/gui/options.cpp b/gui/options.cpp
index 2ebe2bd7782..0b4d4ea6b12 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -3110,7 +3110,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
 
 #ifdef USE_LIBCURL
 	case kUpdateIconsCmd: {
-		DownloadPacksDialog dia;
+		DownloadPacksDialog dia(_("icon packs"), "LIST", "gui-icons*.dat");
 		dia.runModal();
 		break;
 	}


Commit: 965f0f370f9cbf4149f8f7ca62652258ac9dd696
    https://github.com/scummvm/scummvm/commit/965f0f370f9cbf4149f8f7ca62652258ac9dd696
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:53+01:00

Commit Message:
GUI: Implemented shader packs downloading

Changed paths:
    gui/options.cpp
    gui/themes/residualvm.zip
    gui/themes/scummclassic.zip
    gui/themes/scummmodern.zip
    gui/themes/scummremastered.zip


diff --git a/gui/options.cpp b/gui/options.cpp
index 0b4d4ea6b12..c8f5942b296 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -3116,6 +3116,14 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
 	}
 #endif
 
+#ifdef USE_LIBCURL
+	case kUpdateShadersCmd: {
+		DownloadPacksDialog dia(_("shader packs"), "LIST-SHADERS", "shaders*.dat");
+		dia.runModal();
+		break;
+	}
+#endif
+
 #endif
 	case kThemePathClearCmd:
 		_themePath->setLabel(_c("None", "path"));
diff --git a/gui/themes/residualvm.zip b/gui/themes/residualvm.zip
index 95581e90c1f..80006f36022 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 f2caf9e72da..c148b6d30de 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 563925e6d44..aaee6df2563 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 d820aae1b12..70a5c6f55d5 100644
Binary files a/gui/themes/scummremastered.zip and b/gui/themes/scummremastered.zip differ


Commit: bfbaff64c1afcc32277a4724fcc5f9c4b39629ac
    https://github.com/scummvm/scummvm/commit/bfbaff64c1afcc32277a4724fcc5f9c4b39629ac
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:53+01:00

Commit Message:
GUI: Fix ShadowBrowser for classic theme

Changed paths:
    gui/shaderbrowser-dialog.cpp


diff --git a/gui/shaderbrowser-dialog.cpp b/gui/shaderbrowser-dialog.cpp
index 87a4ebeea0c..81c16c13582 100644
--- a/gui/shaderbrowser-dialog.cpp
+++ b/gui/shaderbrowser-dialog.cpp
@@ -97,7 +97,16 @@ void ShaderBrowserDialog::reflowLayout() {
 		if (!_searchPic)
 			_searchPic = new GraphicsWidget(this, "ShaderBrowser.SearchPic", _("Search in game list"));
 		_searchPic->setGfxFromTheme(ThemeEngine::kImageSearch);
+
+		if (_searchDesc) {
+			removeWidget(_searchDesc);
+			g_gui.addToTrash(_searchDesc, this);
+			_searchDesc = nullptr;
+		}
 	} else {
+		if (!_searchDesc)
+			_searchDesc = new StaticTextWidget(this, "ShaderBrowser.SearchDesc", _("Search:"));
+
 		if (_searchPic) {
 			removeWidget(_searchPic);
 			g_gui.addToTrash(_searchPic, this);


Commit: 3c7a05825c92b6de92873006425fae70735ce324
    https://github.com/scummvm/scummvm/commit/3c7a05825c92b6de92873006425fae70735ce324
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:53+01:00

Commit Message:
GUI: Sync classic theme, bump theme version and regenerate

Changed paths:
    gui/ThemeEngine.h
    gui/themes/default.inc
    gui/themes/residualvm.zip
    gui/themes/residualvm/THEMERC
    gui/themes/scummclassic.zip
    gui/themes/scummclassic/THEMERC
    gui/themes/scummclassic/classic_layout.stx
    gui/themes/scummclassic/classic_layout_lowres.stx
    gui/themes/scummmodern.zip
    gui/themes/scummmodern/THEMERC
    gui/themes/scummremastered.zip
    gui/themes/scummremastered/THEMERC


diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index 9fd32ced76c..dd4fbf5e92d 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.7"
+#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.9.8"
 
 class OSystem;
 
diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index aee84ab15f1..df6b58ef7e0 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -1649,6 +1649,47 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
 "</layout>"
 "</layout>"
 "</dialog>"
+"<dialog name='ShaderBrowser' overlays='screen' inset='32' shading='dim'>"
+"<layout type='vertical' padding='16,16,16,16'>"
+"<widget name='Headline' "
+"height='Globals.Line.Height' "
+"/>"
+"<widget name='Filename' "
+"height='Globals.Line.Height' "
+"/>"
+"<space size='10' />"
+"<layout type='horizontal' spacing='5' padding='10,0,0,0'>"
+"<widget name='SearchDesc' "
+"width='60' "
+"height='Globals.Line.Height' "
+"textalign='end' "
+"/>"
+"<widget name='Search' "
+"width='120' "
+"height='Globals.Line.Height' "
+"/>"
+"<widget name='SearchClearButton' "
+"height='Globals.Line.Height' "
+"width='Globals.Line.Height' "
+"/>"
+"</layout>"
+"<widget name='List'/>"
+"<layout type='vertical' padding='0,0,16,0'>"
+"<layout type='horizontal' padding='0,0,0,0'>"
+"<widget name='Cancel' "
+"type='Button' "
+"/>"
+"<widget name='Choose' "
+"type='Button' "
+"/>"
+"<space/>"
+"<widget name='BrowseFile' "
+"type='Button' "
+"/>"
+"</layout>"
+"</layout>"
+"</layout>"
+"</dialog>"
 "<dialog name='GlobalOptions' overlays='Dialog.Launcher.GameList' shading='dim'>"
 "<layout type='vertical' padding='0,0,0,0'>"
 "<widget name='TabWidget' type='TabWidget'/>"
@@ -1760,6 +1801,9 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
 "height='Globals.Line.Height' "
 "width='Globals.Line.Height' "
 "/>"
+"<widget name='UpdateShadersButton' "
+"type='Button' "
+"/>"
 "</layout>"
 "<widget name='grAspectCheckbox' "
 "type='Checkbox' "
@@ -2310,7 +2354,7 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
 "</layout>"
 "</layout>"
 "</dialog>"
-"<dialog name='GlobalOptions_DownloadIconsDialog' overlays='Dialog.GlobalOptions' shading='dim'>"
+"<dialog name='GlobalOptions_DownloadPacksDialog' overlays='Dialog.GlobalOptions' shading='dim'>"
 "<layout type='vertical' padding='16,16,16,8' spacing='8'>"
 "<widget name='StatusText' "
 "height='Globals.Line.Height' "
@@ -3602,6 +3646,46 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
 "</layout>"
 "</layout>"
 "</dialog>"
+"<dialog name='ShaderBrowser' overlays='screen' inset='16' shading='dim'>"
+"<layout type='vertical' padding='16,16,16,16'>"
+"<widget name='Headline' "
+"height='Globals.Line.Height' "
+"/>"
+"<widget name='Filename' "
+"height='Globals.Line.Height' "
+"/>"
+"<space size='5' />"
+"<layout type='horizontal' spacing='2' padding='0,0,0,0'>"
+"<widget name='SearchDesc' "
+"width='45' "
+"height='Globals.Line.Height' "
+"textalign='end' "
+"/>"
+"<widget name='Search' "
+"height='Globals.Line.Height' "
+"/>"
+"<widget name='SearchClearButton' "
+"height='Globals.Line.Height' "
+"width='Globals.Line.Height' "
+"/>"
+"</layout>"
+"<widget name='List'/>"
+"<layout type='vertical' padding='0,0,16,0'>"
+"<layout type='horizontal' padding='0,0,0,0'>"
+"<widget name='Cancel' "
+"type='Button' "
+"/>"
+"<widget name='Choose' "
+"type='Button' "
+"/>"
+"<space/>"
+"<widget name='BrowseFile' "
+"type='Button' "
+"/>"
+"</layout>"
+"</layout>"
+"</layout>"
+"</dialog>"
 "<dialog name='GlobalOptions_Control' overlays='Dialog.GlobalOptions.TabWidget'>"
 "<layout type='vertical' padding='16,16,16,16' spacing='8'>"
 "<widget name='grTouchpadCheckbox' "
@@ -3696,6 +3780,9 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
 "height='Globals.Line.Height' "
 "width='Globals.Line.Height' "
 "/>"
+"<widget name='UpdateShadersButton' "
+"type='Button' "
+"/>"
 "</layout>"
 "<widget name='grAspectCheckbox' "
 "type='Checkbox' "
@@ -4260,7 +4347,7 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
 "</layout>"
 "</layout>"
 "</dialog>"
-"<dialog name='GlobalOptions_DownloadIconsDialog' overlays='Dialog.GlobalOptions' shading='dim'>"
+"<dialog name='GlobalOptions_DownloadPacksDialog' overlays='Dialog.GlobalOptions' shading='dim'>"
 "<layout type='vertical' padding='8,8,8,4' spacing='8'>"
 "<widget name='StatusText' "
 "height='Globals.Line.Height' "
diff --git a/gui/themes/residualvm.zip b/gui/themes/residualvm.zip
index 80006f36022..c93386c9a9b 100644
Binary files a/gui/themes/residualvm.zip and b/gui/themes/residualvm.zip differ
diff --git a/gui/themes/residualvm/THEMERC b/gui/themes/residualvm/THEMERC
index ff48516c834..a654ab03677 100644
--- a/gui/themes/residualvm/THEMERC
+++ b/gui/themes/residualvm/THEMERC
@@ -1,3 +1,3 @@
-[SCUMMVM_STX0.9.7:ResidualVM Modern Theme Remastered:No Author]
+[SCUMMVM_STX0.9.8:ResidualVM Modern Theme Remastered:No Author]
 %using ../common
 %using ../common-svg
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index c148b6d30de..99bae0a9616 100644
Binary files a/gui/themes/scummclassic.zip and b/gui/themes/scummclassic.zip differ
diff --git a/gui/themes/scummclassic/THEMERC b/gui/themes/scummclassic/THEMERC
index b246d9d991b..d676d6143ee 100644
--- a/gui/themes/scummclassic/THEMERC
+++ b/gui/themes/scummclassic/THEMERC
@@ -1 +1 @@
-[SCUMMVM_STX0.9.7:ScummVM Classic Theme:No Author]
+[SCUMMVM_STX0.9.8:ScummVM Classic Theme:No Author]
diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx
index 8f1e090f832..4ce5c778ae8 100644
--- a/gui/themes/scummclassic/classic_layout.stx
+++ b/gui/themes/scummclassic/classic_layout.stx
@@ -247,6 +247,48 @@
 		</layout>
 	</dialog>
 
+	<dialog name = 'ShaderBrowser' overlays = 'screen' inset = '32' shading = 'dim'>
+		<layout type = 'vertical' padding = '16, 16, 16, 16'>
+			<widget name = 'Headline'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'Filename'
+					height = 'Globals.Line.Height'
+			/>
+			<space size = '10' />
+			<layout type = 'horizontal'  spacing = '5' padding = '10, 0, 0, 0'>
+				<widget name = 'SearchDesc'
+						width = '60'
+						height = 'Globals.Line.Height'
+						textalign = 'end'
+				/>
+				<widget name = 'Search'
+						width = '120'
+						height = 'Globals.Line.Height'
+				/>
+				<widget name = 'SearchClearButton'
+						height = 'Globals.Line.Height'
+						width = 'Globals.Line.Height'
+				/>
+			</layout>
+			<widget name = 'List'/>
+			<layout type = 'vertical' padding = '0, 0, 16, 0'>
+				<layout type = 'horizontal' padding = '0, 0, 0, 0'>
+					<widget name = 'Cancel'
+							type = 'Button'
+					/>
+					<widget name = 'Choose'
+							type = 'Button'
+					/>
+					<space/>
+					<widget name = 'BrowseFile'
+							type = 'Button'
+					/>
+				</layout>
+			</layout>
+		</layout>
+	</dialog>
+
 	<dialog name = 'GlobalOptions' overlays = 'Dialog.Launcher.GameList' shading = 'dim'>
 		<layout type = 'vertical' padding = '0, 0, 0, 0'>
 			<widget name = 'TabWidget' type = 'TabWidget'/>
@@ -362,6 +404,9 @@
 						height = 'Globals.Line.Height'
 						width = 'Globals.Line.Height'
 				/>
+				<widget name = 'UpdateShadersButton'
+						type = 'Button'
+				/>
 			</layout>
 			<widget name = 'grAspectCheckbox'
 					type = 'Checkbox'
diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx
index 30048f61149..2162d15832e 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -274,6 +274,47 @@
 		</layout>
 	</dialog>
 
+	<dialog name = 'ShaderBrowser' overlays = 'screen' inset = '16' shading = 'dim'>
+		<layout type = 'vertical' padding = '16, 16, 16, 16'>
+			<widget name = 'Headline'
+					height = 'Globals.Line.Height'
+			/>
+			<widget name = 'Filename'
+					height = 'Globals.Line.Height'
+			/>
+			<space size = '5' />
+			<layout type = 'horizontal' spacing = '2' padding = '0, 0, 0, 0'>
+				<widget name = 'SearchDesc'
+						width = '45'
+						height = 'Globals.Line.Height'
+						textalign = 'end'
+				/>
+				<widget name = 'Search'
+						height = 'Globals.Line.Height'
+				/>
+				<widget name = 'SearchClearButton'
+						height = 'Globals.Line.Height'
+						width = 'Globals.Line.Height'
+				/>
+			</layout>
+			<widget name = 'List'/>
+			<layout type = 'vertical' padding = '0, 0, 16, 0'>
+				<layout type = 'horizontal' padding = '0, 0, 0, 0'>
+					<widget name = 'Cancel'
+							type = 'Button'
+					/>
+					<widget name = 'Choose'
+							type = 'Button'
+					/>
+					<space/>
+					<widget name = 'BrowseFile'
+							type = 'Button'
+					/>
+				</layout>
+			</layout>
+		</layout>
+	</dialog>
+
 	<dialog name = 'GlobalOptions_Control' overlays = 'Dialog.GlobalOptions.TabWidget'>
 		<layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
 			<widget name = 'grTouchpadCheckbox'
@@ -371,6 +412,9 @@
 						height = 'Globals.Line.Height'
 						width = 'Globals.Line.Height'
 				/>
+				<widget name = 'UpdateShadersButton'
+						type = 'Button'
+				/>
 			</layout>
 			<widget name = 'grAspectCheckbox'
 					type = 'Checkbox'
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index aaee6df2563..f8bef2ef97a 100644
Binary files a/gui/themes/scummmodern.zip and b/gui/themes/scummmodern.zip differ
diff --git a/gui/themes/scummmodern/THEMERC b/gui/themes/scummmodern/THEMERC
index 91ad5858107..033658a726e 100644
--- a/gui/themes/scummmodern/THEMERC
+++ b/gui/themes/scummmodern/THEMERC
@@ -1,2 +1,2 @@
-[SCUMMVM_STX0.9.7:ScummVM Modern Theme:No Author]
+[SCUMMVM_STX0.9.8:ScummVM Modern Theme:No Author]
 %using ../common
diff --git a/gui/themes/scummremastered.zip b/gui/themes/scummremastered.zip
index 70a5c6f55d5..5a8d5d773db 100644
Binary files a/gui/themes/scummremastered.zip and b/gui/themes/scummremastered.zip differ
diff --git a/gui/themes/scummremastered/THEMERC b/gui/themes/scummremastered/THEMERC
index 3cdb93d5d87..02def911816 100644
--- a/gui/themes/scummremastered/THEMERC
+++ b/gui/themes/scummremastered/THEMERC
@@ -1,3 +1,3 @@
-[SCUMMVM_STX0.9.7:ScummVM Modern Theme Remastered:No Author]
+[SCUMMVM_STX0.9.8:ScummVM Modern Theme Remastered:No Author]
 %using ../common
 %using ../common-svg


Commit: efaeb08a4f8feb4c067b99ba66cedb0b58b5745f
    https://github.com/scummvm/scummvm/commit/efaeb08a4f8feb4c067b99ba66cedb0b58b5745f
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-01-08T01:15:54+01:00

Commit Message:
GUI: Added default shaders pack.

The source is in https://github.com/scummvm/scummvm-shaders/tree/master/base

Changed paths:
  A gui/themes/shaders.dat


diff --git a/gui/themes/shaders.dat b/gui/themes/shaders.dat
new file mode 100644
index 00000000000..abef18bc141
Binary files /dev/null and b/gui/themes/shaders.dat differ




More information about the Scummvm-git-logs mailing list