[Scummvm-git-logs] scummvm master -> 1c48e73347e97e0b007db839ac28212b15754ce4
sev-
noreply at scummvm.org
Wed Mar 18 15:51:19 UTC 2026
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
1c48e73347 GUI: Parse unpacked themes
Commit: 1c48e73347e97e0b007db839ac28212b15754ce4
https://github.com/scummvm/scummvm/commit/1c48e73347e97e0b007db839ac28212b15754ce4
Author: Mohamed Shaaban (117195948+sh3boly at users.noreply.github.com)
Date: 2026-03-18T16:51:15+01:00
Commit Message:
GUI: Parse unpacked themes
Changed paths:
gui/ThemeEngine.cpp
gui/ThemeEngine.h
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index ac983be43bc..840c3c80160 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -340,7 +340,8 @@ bool ThemeEngine::init() {
if (!_themeArchive && !_themeFile.empty()) {
Common::FSNode node(_themeFile);
if (node.isDirectory()) {
- _themeArchive = new Common::FSDirectory(node);
+ debug("Loading unpacked theme from %s", node.getPath().toString().c_str());
+ _themeArchive = createUnpackedThemeArchive(node);
} else if (_themeFile.baseName().matchString("*.zip", true)) {
// TODO: Also use "node" directly?
// Look for the zip file via SearchMan
@@ -880,6 +881,9 @@ bool ThemeEngine::loadThemeXML(const Common::String &themeId) {
return false;
}
+ if (!themeId.contains(".zip") && !themeId.contains(".ZIP"))
+ _themeName += " (unpacked)";
+
Common::ArchiveMemberList members;
if (0 == _themeArchive->listMatchingMembers(members, "*.stx")) {
warning("Found no STX files for theme '%s'.", themeId.c_str());
@@ -1924,6 +1928,14 @@ bool ThemeEngine::themeConfigUsable(const Common::ArchiveMember &member, Common:
}
delete zipArchive;
+ } else {
+ Common::FSNode dirNode(Common::Path(member.getName()));
+ if (dirNode.isDirectory()) {
+ Common::FSNode themeRcNode = dirNode.getChild("THEMERC");
+ if (themeRcNode.exists() && !themeRcNode.isDirectory()) {
+ stream.open(themeRcNode);
+ }
+ }
}
if (stream.isOpen()) {
@@ -1992,6 +2004,8 @@ void ThemeEngine::listUsableThemes(Common::List<ThemeDescriptor> &list) {
if (ConfMan.hasKey("themepath"))
listUsableThemes(Common::FSNode(ConfMan.getPath("themepath")), list);
+ else
+ listUsableThemes(Common::FSNode(Common::Path("gui/themes")), list);
listUsableThemes(SearchMan, list);
@@ -2038,6 +2052,50 @@ void ThemeEngine::listUsableThemes(Common::Archive &archive, Common::List<ThemeD
fileList.clear();
}
+Common::Archive *ThemeEngine::createUnpackedThemeArchive(const Common::FSNode &themeDir) {
+ // Check if the directory has the THEMERC file
+ Common::FSNode themercNode = themeDir.getChild("THEMERC");
+ if (!themercNode.exists() || themercNode.isDirectory())
+ return 0;
+
+ Common::File themercFile;
+ if (!themercFile.open(themercNode))
+ return 0;
+
+ Common::SearchSet *archive = new Common::SearchSet();
+ archive->addDirectory(themeDir.getName(), themeDir, 0);
+
+ Common::String line;
+ int prio = 1;
+
+ // Parse the THEMERC file and extract the other directories
+ while (!themercFile.eos() && !themercFile.err()) {
+ line = themercFile.readLine();
+ line.trim();
+
+ if (line.hasPrefix("%using ")) {
+ Common::Path themePath = themeDir.getPath();
+ Common::String rawThemePath = line.substr(7);
+ rawThemePath.trim();
+
+ themePath = themePath.append(rawThemePath);
+
+ Common::Path normalizedThemePath = Common::Path(themePath).normalize();
+
+ Common::FSNode dir(normalizedThemePath);
+
+ if (dir.exists() && dir.isDirectory()) {
+ archive->addDirectory(dir.getName(), dir, prio++);
+ } else {
+ debug("ThemeEngine: Parsed path: %s from THEMERC doesn't exist", dir.getPath().toString().c_str());
+ }
+
+ }
+ }
+
+ return archive;
+}
+
void ThemeEngine::listUsableThemes(const Common::FSNode &node, Common::List<ThemeDescriptor> &list, int depth) {
if (!node.exists() || !node.isReadable() || !node.isDirectory())
return;
@@ -2058,22 +2116,37 @@ void ThemeEngine::listUsableThemes(const Common::FSNode &node, Common::List<Them
Common::FSList fileList;
// Check all files. We need this to find all themes inside ZIP archives.
- if (!node.getChildren(fileList, Common::FSNode::kListFilesOnly))
+ if (!node.getChildren(fileList, Common::FSNode::kListAll))
return;
for (auto &file : fileList) {
- // We will only process zip files for now
- if (!file.getPath().baseName().matchString("*.zip", true))
- continue;
-
td.name.clear();
+ bool isUnpackedTheme = false;
+ if (!file.getPath().baseName().matchString("*.zip", true)) {
+
+ // 2. If it's NOT a zip, check if it's a directory with a THEMERC file
+ if (file.isDirectory()) {
+ Common::FSNode themercNode = file.getChild("THEMERC");
+ if (themercNode.exists() && !themercNode.isDirectory()) {
+ isUnpackedTheme = true;
+ } else {
+ continue; // Not a zip, and no THEMERC found. Skip.
+ }
+ } else {
+ continue; // Not a zip, and not a directory. Skip.
+ }
+ }
+
if (themeConfigUsable(file, td.name)) {
td.filename = file.getPath();
td.id = file.getName();
// If the name of the node object also contains
// the ".zip" suffix, we will strip it.
- if (td.id.matchString("*.zip", true)) {
+ if (isUnpackedTheme) {
+ td.id += "-unpacked";
+ td.name += " (unpacked)";
+ } else if (td.id.matchString("*.zip", true)) {
for (int j = 0; j < 4; ++j)
td.id.deleteLastChar();
}
@@ -2148,7 +2221,11 @@ Common::String ThemeEngine::getThemeId(const Common::Path &filename) {
return id;
} else {
- return node.getName();
+ // unpacked theme we need to update the name with -unpacked
+ Common::String id = node.getName();
+ id.chop(1);
+ id += "-unpacked";
+ return id;
}
}
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index 88c8abd3570..a60171fe094 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -750,6 +750,8 @@ private:
static void listUsableThemes(const Common::FSNode &node, Common::List<ThemeDescriptor> &list, int depth = -1);
static void listUsableThemes(Common::Archive &archive, Common::List<ThemeDescriptor> &list);
+ Common::Archive *createUnpackedThemeArchive(const Common::FSNode &themeDir);
+
protected:
OSystem *_system; /** Global system object. */
More information about the Scummvm-git-logs
mailing list