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

sev- sev at scummvm.org
Sat Aug 7 08:44:52 UTC 2021


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

Summary:
0db0b2c201 COMMON: Create Path type
7eb4841065 ALL: Use Path type in Archive functions
0d65c2fd12 ALL: Use Path type in File functions
48ce80a32c AGS: Fix String -> Path conversions
909595176a COMMON: Use Path type in MacResManager functions
17297ea7ef COMMON: Use Path type in punycode_decodepath
02aace0598 DIRECTOR: Use ':' as directory separator
8501ce8e26 COMMON: Convert names to printable in FSDirectory warnings
56087578c7 DIRECTOR: LINGO: Update patcher paths
9a22c59b67 WIN32: Fix compilation
6020f24661 COMMON: Create punycode_encodepath
e6c696031f DIRECTOR: Punycode dump file names
2eca1126c5 VIDEO: Use Path type in VideoDecoder functions
cedc5678ac DIRECTOR: Fix loading video
8c4ecf6cc5 COMMON: Add Doxygen comments to path.h
763d2813a0 COMMON: Replace Path's += with append/join
ed41e12fd2 ANDROID: Pass Path to hasFile instead of String
d2b42b52d1 COMMON: Use Path functions in FSNode constructor
d6f255cfff DIRECTOR: Fix start movie path conversion
eaee94eab8 DIRECTOR: Set dir separator before parsing options


Commit: 0db0b2c2018ea1b74f6d3d04807d36e3bdfcea41
    https://github.com/scummvm/scummvm/commit/0db0b2c2018ea1b74f6d3d04807d36e3bdfcea41
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
COMMON: Create Path type

Changed paths:
  A common/path.cpp
  A common/path.h
    common/module.mk


diff --git a/common/module.mk b/common/module.mk
index 665def8888..85c7a3bf67 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -27,6 +27,7 @@ MODULE_OBJS := \
 	mdct.o \
 	mutex.o \
 	osd_message_queue.o \
+	path.o \
 	platform.o \
 	punycode.o \
 	quicktime.o \
diff --git a/common/path.cpp b/common/path.cpp
new file mode 100644
index 0000000000..4b138633e5
--- /dev/null
+++ b/common/path.cpp
@@ -0,0 +1,141 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/path.h"
+
+namespace Common {
+
+Path::Path(const Path &path) {
+	_str = path.rawString();
+}
+
+Path::Path(const char *str, char separator) {
+	setString(str, separator);
+}
+
+Path::Path(const String &str, char separator) {
+	setString(str.c_str(), separator);
+}
+
+Path::Path(char c, char separator) {
+	const char str[] = { c, '\0' };
+	setString(str, separator);
+}
+
+void Path::setString(const char *str, char separator) {
+	for (; *str; str++) {
+		if (*str == separator)
+			_str += DIR_SEPARATOR;
+		else
+			_str += *str;
+	}
+}
+
+String Path::toString(char separator) const {
+	String res;
+	for (const char *ptr = _str.c_str(); *ptr; ptr++) {
+		if (*ptr == DIR_SEPARATOR)
+			res += separator;
+		else
+			res += *ptr;
+	}
+	return res;
+}
+
+bool Path::operator==(const Path &x) const {
+	return _str == x.rawString();
+}
+
+bool Path::operator!=(const Path &x) const {
+	return _str != x.rawString();
+}
+
+bool Path::empty() const {
+	return _str.empty();
+}
+
+Path &Path::operator=(const Path &path) {
+	_str = path.rawString();
+	return *this;
+}
+
+Path &Path::operator=(const char *str) {
+	setString(str);
+	return *this;
+}
+
+Path &Path::operator=(const String &str) {
+	setString(str.c_str());
+	return *this;
+}
+
+Path &Path::operator=(char c) {
+	const char str[] = { c, '\0' };
+	setString(str);
+	return *this;
+}
+
+Path &Path::operator+=(const Path &path) {
+	_str += path.rawString();
+	return *this;
+}
+
+Path &Path::operator+=(const char *str) {
+	_str += Path(str).rawString();
+	return *this;
+}
+
+Path &Path::operator+=(const String &str) {
+	_str += Path(str).rawString();
+	return *this;
+}
+
+Path &Path::operator+=(char c) {
+	_str += Path(c).rawString();
+	return *this;
+}
+
+Path operator+(const Path &x, const Path &y) {
+	Path temp(x);
+	temp += y;
+	return temp;
+}
+
+Path operator+(const Path &x, const String &y) {
+	Path temp(x);
+	temp += y;
+	return temp;
+}
+
+Path operator+(const Path &x, const char *y) {
+	Path temp(x);
+	temp += y;
+	return temp;
+}
+
+Path operator+(const Path &x, char y) {
+	Path temp(x);
+	temp += y;
+	return temp;
+}
+
+} // End of namespace Common
diff --git a/common/path.h b/common/path.h
new file mode 100644
index 0000000000..128fc8ab3b
--- /dev/null
+++ b/common/path.h
@@ -0,0 +1,73 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef COMMON_PATH_H
+#define COMMON_PATH_H
+
+#include "common/scummsys.h"
+#include "common/str.h"
+
+namespace Common {
+
+const char DIR_SEPARATOR = '\x1f'; // unit separator
+
+class Path {
+private:
+	String _str;
+
+public:
+	Path() {}
+	Path(const Path &path);
+	Path(const char *str, char separator = '/');
+	Path(const String &str, char separator = '/');
+	Path(char c, char separator = '/');
+
+private:
+	void setString(const char *str, char separator = '/');
+
+public:
+	const String &rawString() const { return _str; }
+	String toString(char separator = '/') const;
+
+	bool operator==(const Path &x) const;
+	bool operator!=(const Path &x) const;
+
+	bool empty() const;
+
+	Path &operator=(const Path &str);
+	Path &operator=(const char *str);
+	Path &operator=(const String &str);
+	Path &operator=(char c);
+	Path &operator+=(const Path &str);
+	Path &operator+=(const char *str);
+	Path &operator+=(const String &str);
+	Path &operator+=(char c);
+};
+
+Path operator+(const Path &x, const Path &y);
+Path operator+(const Path &x, const String &y);
+Path operator+(const Path &x, const char *y);
+Path operator+(const Path &x, char y);
+
+} // End of namespace Common
+
+#endif


Commit: 7eb48410652f1a92e5f3bf2ef5f34dd6dea356ef
    https://github.com/scummvm/scummvm/commit/7eb48410652f1a92e5f3bf2ef5f34dd6dea356ef
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
ALL: Use Path type in Archive functions

Changed paths:
    backends/platform/android/asset-archive.cpp
    backends/platform/android/asset-archive.h
    backends/platform/sdl/win32/win32.cpp
    common/archive.cpp
    common/archive.h
    common/fs.cpp
    common/fs.h
    common/installshield_cab.cpp
    common/installshieldv3_archive.cpp
    common/installshieldv3_archive.h
    common/stuffit.cpp
    common/unarj.cpp
    common/unzip.cpp
    engines/advancedDetector.cpp
    engines/glk/blorb.cpp
    engines/glk/blorb.h
    engines/glk/comprehend/pics.cpp
    engines/glk/comprehend/pics.h
    engines/glk/hugo/resource_archive.cpp
    engines/glk/hugo/resource_archive.h
    engines/glk/zcode/pics.cpp
    engines/glk/zcode/pics.h
    engines/glk/zcode/sound_folder.cpp
    engines/glk/zcode/sound_folder.h
    engines/grim/lab.cpp
    engines/grim/lab.h
    engines/grim/update/lang_filter.cpp
    engines/grim/update/lang_filter.h
    engines/grim/update/mscab.cpp
    engines/grim/update/mscab.h
    engines/kyra/resource/resource_intern.cpp
    engines/kyra/resource/resource_intern.h
    engines/lastexpress/data/archive.cpp
    engines/lastexpress/data/archive.h
    engines/lastexpress/resource.cpp
    engines/lastexpress/resource.h
    engines/mads/resources.cpp
    engines/mohawk/installer_archive.cpp
    engines/mohawk/installer_archive.h
    engines/ngi/ngiarchive.cpp
    engines/ngi/ngiarchive.h
    engines/parallaction/disk_ns.cpp
    engines/prince/archive.cpp
    engines/prince/archive.h
    engines/stark/formats/xarc.cpp
    engines/stark/formats/xarc.h
    engines/trecision/fastfile.cpp
    engines/trecision/fastfile.h
    engines/ultima/shared/engine/data_archive.cpp
    engines/ultima/shared/engine/data_archive.h
    engines/ultima/shared/engine/resources.cpp
    engines/ultima/shared/engine/resources.h
    engines/wintermute/base/file/base_package.cpp
    engines/wintermute/base/file/base_package.h
    engines/xeen/files.cpp
    engines/xeen/files.h
    engines/zvision/file/zfs_archive.cpp
    engines/zvision/file/zfs_archive.h


diff --git a/backends/platform/android/asset-archive.cpp b/backends/platform/android/asset-archive.cpp
index 0d8fab8415..9a0f602eab 100644
--- a/backends/platform/android/asset-archive.cpp
+++ b/backends/platform/android/asset-archive.cpp
@@ -115,7 +115,8 @@ AndroidAssetArchive::AndroidAssetArchive(jobject am) : _hasCached(false) {
 AndroidAssetArchive::~AndroidAssetArchive() {
 }
 
-bool AndroidAssetArchive::hasFile(const Common::String &name) const {
+bool AndroidAssetArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	AAsset *asset = AAssetManager_open(_am, name.c_str(), AASSET_MODE_RANDOM);
 	bool exists = false;
 	if (asset != NULL) {
@@ -156,15 +157,17 @@ int AndroidAssetArchive::listMembers(Common::ArchiveMemberList &member_list) con
 	return count;
 }
 
-const Common::ArchiveMemberPtr AndroidAssetArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr AndroidAssetArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *AndroidAssetArchive::createReadStreamForMember(const Common::String &path) const {
-	if (!hasFile(path)) {
+Common::SeekableReadStream *AndroidAssetArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
+	if (!hasFile(name)) {
 		return nullptr;
 	}
-	return new AssetInputStream(_am, path);
+	return new AssetInputStream(_am, name);
 }
 
 #endif
diff --git a/backends/platform/android/asset-archive.h b/backends/platform/android/asset-archive.h
index 98871f47c9..125a1b73ac 100644
--- a/backends/platform/android/asset-archive.h
+++ b/backends/platform/android/asset-archive.h
@@ -39,10 +39,10 @@ public:
 	AndroidAssetArchive(jobject am);
 	virtual ~AndroidAssetArchive();
 
-	virtual bool hasFile(const Common::String &name) const override;
+	virtual bool hasFile(const Common::Path &path) const override;
 	virtual int listMembers(Common::ArchiveMemberList &list) const override;
-	virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	virtual const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	virtual Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 
 private:
 	AAssetManager *_am;
diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp
index 026dadb2d2..f7156f35b7 100644
--- a/backends/platform/sdl/win32/win32.cpp
+++ b/backends/platform/sdl/win32/win32.cpp
@@ -325,10 +325,10 @@ class Win32ResourceArchive final : public Common::Archive {
 public:
 	Win32ResourceArchive();
 
-	virtual bool hasFile(const Common::String &name) const override;
+	virtual bool hasFile(const Common::Path &path) const override;
 	virtual int listMembers(Common::ArchiveMemberList &list) const override;
-	virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	virtual const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	virtual Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 private:
 	typedef Common::List<Common::String> FilenameList;
 
@@ -349,7 +349,8 @@ Win32ResourceArchive::Win32ResourceArchive() {
 	EnumResourceNames(NULL, MAKEINTRESOURCE(256), &EnumResNameProc, (LONG_PTR)this);
 }
 
-bool Win32ResourceArchive::hasFile(const Common::String &name) const {
+bool Win32ResourceArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	for (FilenameList::const_iterator i = _files.begin(); i != _files.end(); ++i) {
 		if (i->equalsIgnoreCase(name))
 			return true;
@@ -367,12 +368,14 @@ int Win32ResourceArchive::listMembers(Common::ArchiveMemberList &list) const {
 	return count;
 }
 
-const Common::ArchiveMemberPtr Win32ResourceArchive::getMember(const Common::String &name) const {
-	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
+const Common::ArchiveMemberPtr Win32ResourceArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
+	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name.toString(), this));
 }
 
-Common::SeekableReadStream *Win32ResourceArchive::createReadStreamForMember(const Common::String &name) const {
-	TCHAR *tName = Win32::stringToTchar(name);
+Common::SeekableReadStream *Win32ResourceArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
+	TCHAR *tName = Win32::stringToTchar(name.toString());
 	HRSRC resource = FindResource(NULL, tName, MAKEINTRESOURCE(256));
 	free(tName);
 
diff --git a/common/archive.cpp b/common/archive.cpp
index 4f87000291..558b46b314 100644
--- a/common/archive.cpp
+++ b/common/archive.cpp
@@ -205,13 +205,13 @@ void SearchSet::setPriority(const String &name, int priority) {
 	insert(node);
 }
 
-bool SearchSet::hasFile(const String &name) const {
-	if (name.empty())
+bool SearchSet::hasFile(const Path &path) const {
+	if (path.empty())
 		return false;
 
 	ArchiveNodeList::const_iterator it = _list.begin();
 	for (; it != _list.end(); ++it) {
-		if (it->_arc->hasFile(name))
+		if (it->_arc->hasFile(path))
 			return true;
 	}
 
@@ -238,26 +238,26 @@ int SearchSet::listMembers(ArchiveMemberList &list) const {
 	return matches;
 }
 
-const ArchiveMemberPtr SearchSet::getMember(const String &name) const {
-	if (name.empty())
+const ArchiveMemberPtr SearchSet::getMember(const Path &path) const {
+	if (path.empty())
 		return ArchiveMemberPtr();
 
 	ArchiveNodeList::const_iterator it = _list.begin();
 	for (; it != _list.end(); ++it) {
-		if (it->_arc->hasFile(name))
-			return it->_arc->getMember(name);
+		if (it->_arc->hasFile(path))
+			return it->_arc->getMember(path);
 	}
 
 	return ArchiveMemberPtr();
 }
 
-SeekableReadStream *SearchSet::createReadStreamForMember(const String &name) const {
-	if (name.empty())
+SeekableReadStream *SearchSet::createReadStreamForMember(const Path &path) const {
+	if (path.empty())
 		return nullptr;
 
 	ArchiveNodeList::const_iterator it = _list.begin();
 	for (; it != _list.end(); ++it) {
-		SeekableReadStream *stream = it->_arc->createReadStreamForMember(name);
+		SeekableReadStream *stream = it->_arc->createReadStreamForMember(path);
 		if (stream)
 			return stream;
 	}
diff --git a/common/archive.h b/common/archive.h
index 4bf01b73df..ae39651cc3 100644
--- a/common/archive.h
+++ b/common/archive.h
@@ -25,6 +25,7 @@
 
 #include "common/str.h"
 #include "common/list.h"
+#include "common/path.h"
 #include "common/ptr.h"
 #include "common/singleton.h"
 
@@ -107,7 +108,7 @@ public:
 	 * Patterns are not allowed, as this is meant to be a quick File::exists()
 	 * replacement.
 	 */
-	virtual bool hasFile(const String &name) const = 0;
+	virtual bool hasFile(const Path &path) const = 0;
 
 	/**
 	 * Add all members of the Archive matching the specified pattern to the list.
@@ -128,7 +129,7 @@ public:
 	/**
 	 * Return an ArchiveMember representation of the given file.
 	 */
-	virtual const ArchiveMemberPtr getMember(const String &name) const = 0;
+	virtual const ArchiveMemberPtr getMember(const Path &path) const = 0;
 
 	/**
 	 * Create a stream bound to a member with the specified name in the
@@ -136,7 +137,7 @@ public:
 	 *
 	 * @return The newly created input stream.
 	 */
-	virtual SeekableReadStream *createReadStreamForMember(const String &name) const = 0;
+	virtual SeekableReadStream *createReadStreamForMember(const Path &path) const = 0;
 };
 
 
@@ -251,17 +252,17 @@ public:
 	 */
 	void setPriority(const String& name, int priority);
 
-	virtual bool hasFile(const String &name) const;
+	virtual bool hasFile(const Path &path) const;
 	virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern) const;
 	virtual int listMembers(ArchiveMemberList &list) const;
 
-	virtual const ArchiveMemberPtr getMember(const String &name) const;
+	virtual const ArchiveMemberPtr getMember(const Path &path) const;
 
 	/**
 	 * Implement createReadStreamForMember from the Archive base class. The current policy is
 	 * opening the first file encountered that matches the name.
 	 */
-	virtual SeekableReadStream *createReadStreamForMember(const String &name) const;
+	virtual SeekableReadStream *createReadStreamForMember(const Path &path) const;
 
 	/**
 	 * Ignore clashes when adding directories. For more details, see the corresponding parameter
diff --git a/common/fs.cpp b/common/fs.cpp
index e120055a38..e296ce32aa 100644
--- a/common/fs.cpp
+++ b/common/fs.cpp
@@ -35,15 +35,16 @@ FSNode::FSNode(AbstractFSNode *realNode)
 	: _realNode(realNode) {
 }
 
-FSNode::FSNode(const String &p) {
+FSNode::FSNode(const Path &p) {
 	assert(g_system);
 	FilesystemFactory *factory = g_system->getFilesystemFactory();
 	AbstractFSNode *tmp = nullptr;
+	String s = p.toString();
 
-	if (p.empty() || p == ".")
+	if (s.empty() || s == ".")
 		tmp = factory->makeCurrentDirectoryFileNode();
 	else
-		tmp = factory->makeFileNodePath(p);
+		tmp = factory->makeFileNodePath(s);
 	_realNode = SharedPtr<AbstractFSNode>(tmp);
 }
 
@@ -175,25 +176,25 @@ FSDirectory::FSDirectory(const FSNode &node, int depth, bool flat, bool ignoreCl
 	_includeDirectories(includeDirectories) {
 }
 
-FSDirectory::FSDirectory(const String &prefix, const FSNode &node, int depth, bool flat,
+FSDirectory::FSDirectory(const Path &prefix, const FSNode &node, int depth, bool flat,
 						 bool ignoreClashes, bool includeDirectories)
   : _node(node), _cached(false), _depth(depth), _flat(flat), _ignoreClashes(ignoreClashes),
 	_includeDirectories(includeDirectories) {
 
-	setPrefix(prefix);
+	setPrefix(prefix.rawString());
 }
 
-FSDirectory::FSDirectory(const String &name, int depth, bool flat, bool ignoreClashes, bool includeDirectories)
+FSDirectory::FSDirectory(const Path &name, int depth, bool flat, bool ignoreClashes, bool includeDirectories)
   : _node(name), _cached(false), _depth(depth), _flat(flat), _ignoreClashes(ignoreClashes),
 	_includeDirectories(includeDirectories) {
 }
 
-FSDirectory::FSDirectory(const String &prefix, const String &name, int depth, bool flat,
+FSDirectory::FSDirectory(const Path &prefix, const Path &name, int depth, bool flat,
 						 bool ignoreClashes, bool includeDirectories)
   : _node(name), _cached(false), _depth(depth), _flat(flat), _ignoreClashes(ignoreClashes),
 	_includeDirectories(includeDirectories) {
 
-	setPrefix(prefix);
+	setPrefix(prefix.rawString());
 }
 
 FSDirectory::~FSDirectory() {
@@ -202,8 +203,8 @@ FSDirectory::~FSDirectory() {
 void FSDirectory::setPrefix(const String &prefix) {
 	_prefix = prefix;
 
-	if (!_prefix.empty() && !_prefix.hasSuffix("/"))
-		_prefix += "/";
+	if (!_prefix.empty() && _prefix.lastChar() != DIR_SEPARATOR)
+		_prefix += DIR_SEPARATOR;
 }
 
 FSNode FSDirectory::getFSNode() const {
@@ -222,7 +223,8 @@ FSNode *FSDirectory::lookupCache(NodeCache &cache, const String &name) const {
 	return nullptr;
 }
 
-bool FSDirectory::hasFile(const String &name) const {
+bool FSDirectory::hasFile(const Path &path) const {
+	String name = path.rawString();
 	if (name.empty() || !_node.isDirectory())
 		return false;
 
@@ -230,7 +232,8 @@ bool FSDirectory::hasFile(const String &name) const {
 	return node && node->exists();
 }
 
-const ArchiveMemberPtr FSDirectory::getMember(const String &name) const {
+const ArchiveMemberPtr FSDirectory::getMember(const Path &path) const {
+	String name = path.rawString();
 	if (name.empty() || !_node.isDirectory())
 		return ArchiveMemberPtr();
 
@@ -247,7 +250,8 @@ const ArchiveMemberPtr FSDirectory::getMember(const String &name) const {
 	return ArchiveMemberPtr(new FSNode(*node));
 }
 
-SeekableReadStream *FSDirectory::createReadStreamForMember(const String &name) const {
+SeekableReadStream *FSDirectory::createReadStreamForMember(const Path &path) const {
+	String name = path.rawString();
 	if (name.empty() || !_node.isDirectory())
 		return nullptr;
 
@@ -261,23 +265,24 @@ SeekableReadStream *FSDirectory::createReadStreamForMember(const String &name) c
 	return stream;
 }
 
-FSDirectory *FSDirectory::getSubDirectory(const String &name, int depth, bool flat, bool ignoreClashes) {
-	return getSubDirectory(String(), name, depth, flat, ignoreClashes);
+FSDirectory *FSDirectory::getSubDirectory(const Path &name, int depth, bool flat, bool ignoreClashes) {
+	return getSubDirectory(Path(), name, depth, flat, ignoreClashes);
 }
 
-FSDirectory *FSDirectory::getSubDirectory(const String &prefix, const String &name, int depth,
+FSDirectory *FSDirectory::getSubDirectory(const Path &prefix, const Path &name, int depth,
 		bool flat, bool ignoreClashes) {
-	if (name.empty() || !_node.isDirectory())
+	String rawName = name.rawString();
+	if (rawName.empty() || !_node.isDirectory())
 		return nullptr;
 
-	FSNode *node = lookupCache(_subDirCache, name);
+	FSNode *node = lookupCache(_subDirCache, rawName);
 	if (!node)
 		return nullptr;
 
 	return new FSDirectory(prefix, *node, depth, flat, ignoreClashes);
 }
 
-void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String& prefix) const {
+void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const Path& prefix) const {
 	if (depth <= 0)
 		return;
 
@@ -286,7 +291,7 @@ void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String&
 
 	FSList::iterator it = list.begin();
 	for ( ; it != list.end(); ++it) {
-		String name = prefix + it->getName();
+		String name = prefix.rawString() + it->getName();
 
 		// don't touch name as it might be used for warning messages
 		String lowercaseName = name;
@@ -306,7 +311,7 @@ void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String&
 						        name.c_str());
 					}
 				}
-				cacheDirectoryRecursive(*it, depth - 1, _flat ? prefix : lowercaseName + "/");
+				cacheDirectoryRecursive(*it, depth - 1, _flat ? prefix : lowercaseName + DIR_SEPARATOR);
 				_subDirCache[lowercaseName] = *it;
 			}
 		} else {
diff --git a/common/fs.h b/common/fs.h
index 1093a4bbdb..94784f39bc 100644
--- a/common/fs.h
+++ b/common/fs.h
@@ -102,7 +102,7 @@ public:
 	 * operating system does not support the concept), some other directory is
 	 * used (usually the root directory).
 	 */
-	explicit FSNode(const String &path);
+	explicit FSNode(const Path &path);
 
 	virtual ~FSNode() {}
 
@@ -313,7 +313,7 @@ class FSDirectory : public Archive {
 	FSNode *lookupCache(NodeCache &cache, const String &name) const;
 
 	// cache management
-	void cacheDirectoryRecursive(FSNode node, int depth, const String& prefix) const;
+	void cacheDirectoryRecursive(FSNode node, int depth, const Path& prefix) const;
 
 	// fill cache if not already cached
 	void ensureCached() const;
@@ -324,7 +324,7 @@ public:
 	 * unbound FSDirectory if name is not found in the file system or if the node is not a
 	 * valid directory.
 	 */
-	FSDirectory(const String &name, int depth = 1, bool flat = false,
+	FSDirectory(const Path &name, int depth = 1, bool flat = false,
 	            bool ignoreClashes = false, bool includeDirectories = false);
 	/**
 	 * @overload
@@ -336,12 +336,12 @@ public:
 	 * Create a FSDirectory representing a tree with the specified depth. The parameter
 	 * prefix is prepended to the keys in the cache. See @ref FSDirectory.
 	 */
-	FSDirectory(const String &prefix, const String &name, int depth = 1,
+	FSDirectory(const Path &prefix, const Path &name, int depth = 1,
 	            bool flat = false, bool ignoreClashes = false, bool includeDirectories = false);
 	/**
 	 * @overload
 	 */
-	FSDirectory(const String &prefix, const FSNode &node, int depth = 1,
+	FSDirectory(const Path &prefix, const FSNode &node, int depth = 1,
 	            bool flat = false, bool ignoreClashes = false, bool includeDirectories = false);
 
 	virtual ~FSDirectory();
@@ -355,21 +355,21 @@ public:
 	 * Create a new FSDirectory pointing to a subdirectory of the instance.
 	 * @return A new FSDirectory instance.
 	 */
-	FSDirectory *getSubDirectory(const String &name, int depth = 1, bool flat = false,
+	FSDirectory *getSubDirectory(const Path &name, int depth = 1, bool flat = false,
 	                             bool ignoreClashes = false);
 	/**
 	 * Create a new FSDirectory pointing to a subdirectory of the instance. See FSDirectory
 	 * for an explanation of the prefix parameter.
 	 * @return A new FSDirectory instance.
 	 */
-	FSDirectory *getSubDirectory(const String &prefix, const String &name, int depth = 1,
+	FSDirectory *getSubDirectory(const Path &prefix, const Path &name, int depth = 1,
 	                             bool flat = false, bool ignoreClashes = false);
 
 	/**
 	 * Check for the existence of a file in the cache. A full match of relative path and file name
 	 * is needed for success.
 	 */
-	virtual bool hasFile(const String &name) const;
+	virtual bool hasFile(const Path &path) const;
 
 	/**
 	 * Return a list of matching file names. Pattern can use GLOB wildcards.
@@ -385,13 +385,13 @@ public:
 	 * Get an ArchiveMember representation of the specified file. A full match of relative
 	 * path and file name is needed for success.
 	 */
-	virtual const ArchiveMemberPtr getMember(const String &name) const;
+	virtual const ArchiveMemberPtr getMember(const Path &path) const;
 
 	/**
 	 * Open the specified file. A full match of relative path and file name is needed
 	 * for success.
 	 */
-	virtual SeekableReadStream *createReadStreamForMember(const String &name) const;
+	virtual SeekableReadStream *createReadStreamForMember(const Path &path) const;
 };
 
 /** @} */
diff --git a/common/installshield_cab.cpp b/common/installshield_cab.cpp
index 8c5754f53a..eb09bd094d 100644
--- a/common/installshield_cab.cpp
+++ b/common/installshield_cab.cpp
@@ -64,10 +64,10 @@ public:
 	void close();
 
 	// Archive API implementation
-	virtual bool hasFile(const String &name) const;
+	virtual bool hasFile(const Path &path) const;
 	virtual int listMembers(ArchiveMemberList &list) const;
-	virtual const ArchiveMemberPtr getMember(const String &name) const;
-	virtual SeekableReadStream *createReadStreamForMember(const String &name) const;
+	virtual const ArchiveMemberPtr getMember(const Path &path) const;
+	virtual SeekableReadStream *createReadStreamForMember(const Path &path) const;
 
 private:
 	struct FileEntry {
@@ -217,7 +217,8 @@ void InstallShieldCabinet::close() {
 	_version = 0;
 }
 
-bool InstallShieldCabinet::hasFile(const String &name) const {
+bool InstallShieldCabinet::hasFile(const Path &path) const {
+	String name = path.toString();
 	return _map.contains(name);
 }
 
@@ -228,11 +229,13 @@ int InstallShieldCabinet::listMembers(ArchiveMemberList &list) const {
 	return _map.size();
 }
 
-const ArchiveMemberPtr InstallShieldCabinet::getMember(const String &name) const {
+const ArchiveMemberPtr InstallShieldCabinet::getMember(const Path &path) const {
+	String name = path.toString();
 	return ArchiveMemberPtr(new GenericArchiveMember(name, this));
 }
 
-SeekableReadStream *InstallShieldCabinet::createReadStreamForMember(const String &name) const {
+SeekableReadStream *InstallShieldCabinet::createReadStreamForMember(const Path &path) const {
+	String name = path.toString();
 	if (!_map.contains(name))
 		return nullptr;
 
diff --git a/common/installshieldv3_archive.cpp b/common/installshieldv3_archive.cpp
index b7fbd9004b..dc4f77c44c 100644
--- a/common/installshieldv3_archive.cpp
+++ b/common/installshieldv3_archive.cpp
@@ -107,7 +107,8 @@ void InstallShieldV3::close() {
 	_map.clear();
 }
 
-bool InstallShieldV3::hasFile(const Common::String &name) const {
+bool InstallShieldV3::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return _map.contains(name);
 }
 
@@ -118,11 +119,13 @@ int InstallShieldV3::listMembers(Common::ArchiveMemberList &list) const {
 	return _map.size();
 }
 
-const Common::ArchiveMemberPtr InstallShieldV3::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr InstallShieldV3::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *InstallShieldV3::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *InstallShieldV3::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!_stream || !_map.contains(name))
 		return nullptr;
 
diff --git a/common/installshieldv3_archive.h b/common/installshieldv3_archive.h
index 07ed31313e..ca0183b787 100644
--- a/common/installshieldv3_archive.h
+++ b/common/installshieldv3_archive.h
@@ -43,10 +43,10 @@ public:
 	bool isOpen() const { return _stream != nullptr; }
 
 	// Common::Archive API implementation
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 
 private:
 	struct FileEntry {
diff --git a/common/stuffit.cpp b/common/stuffit.cpp
index 793b0b952c..11452d9f67 100644
--- a/common/stuffit.cpp
+++ b/common/stuffit.cpp
@@ -47,10 +47,10 @@ public:
 	bool isOpen() const { return _stream != 0; }
 
 	// Common::Archive API implementation
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 
 private:
 	struct FileEntry {
@@ -199,7 +199,8 @@ void StuffItArchive::close() {
 	_map.clear();
 }
 
-bool StuffItArchive::hasFile(const Common::String &name) const {
+bool StuffItArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return _map.contains(name);
 }
 
@@ -210,11 +211,13 @@ int StuffItArchive::listMembers(Common::ArchiveMemberList &list) const {
 	return _map.size();
 }
 
-const Common::ArchiveMemberPtr StuffItArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr StuffItArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *StuffItArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *StuffItArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!_stream || !_map.contains(name))
 		return nullptr;
 
diff --git a/common/unarj.cpp b/common/unarj.cpp
index 9737521245..34bfed21cc 100644
--- a/common/unarj.cpp
+++ b/common/unarj.cpp
@@ -702,10 +702,10 @@ public:
 	virtual ~ArjArchive();
 
 	// Archive implementation
-	virtual bool hasFile(const String &name) const;
+	virtual bool hasFile(const Path &path) const;
 	virtual int listMembers(ArchiveMemberList &list) const;
-	virtual const ArchiveMemberPtr getMember(const String &name) const;
-	virtual SeekableReadStream *createReadStreamForMember(const String &name) const;
+	virtual const ArchiveMemberPtr getMember(const Path &path) const;
+	virtual SeekableReadStream *createReadStreamForMember(const Path &path) const;
 };
 
 ArjArchive::ArjArchive(const String &filename) : _arjFilename(filename) {
@@ -746,7 +746,8 @@ ArjArchive::~ArjArchive() {
 	}
 }
 
-bool ArjArchive::hasFile(const String &name) const {
+bool ArjArchive::hasFile(const Path &path) const {
+	String name = path.toString();
 	return _headers.contains(name);
 }
 
@@ -762,14 +763,16 @@ int ArjArchive::listMembers(ArchiveMemberList &list) const {
 	return matches;
 }
 
-const ArchiveMemberPtr ArjArchive::getMember(const String &name) const {
+const ArchiveMemberPtr ArjArchive::getMember(const Path &path) const {
+	String name = path.toString();
 	if (!hasFile(name))
 		return ArchiveMemberPtr();
 
 	return ArchiveMemberPtr(new GenericArchiveMember(name, this));
 }
 
-SeekableReadStream *ArjArchive::createReadStreamForMember(const String &name) const {
+SeekableReadStream *ArjArchive::createReadStreamForMember(const Path &path) const {
+	String name = path.toString();
 	if (!_headers.contains(name)) {
 		return nullptr;
 	}
diff --git a/common/unzip.cpp b/common/unzip.cpp
index 152b5bb812..a240fd6e6d 100644
--- a/common/unzip.cpp
+++ b/common/unzip.cpp
@@ -1429,10 +1429,10 @@ public:
 
 	~ZipArchive();
 
-	virtual bool hasFile(const String &name) const;
+	virtual bool hasFile(const Path &path) const;
 	virtual int listMembers(ArchiveMemberList &list) const;
-	virtual const ArchiveMemberPtr getMember(const String &name) const;
-	virtual SeekableReadStream *createReadStreamForMember(const String &name) const;
+	virtual const ArchiveMemberPtr getMember(const Path &path) const;
+	virtual SeekableReadStream *createReadStreamForMember(const Path &path) const;
 };
 
 /*
@@ -1461,7 +1461,8 @@ ZipArchive::~ZipArchive() {
 	unzClose(_zipFile);
 }
 
-bool ZipArchive::hasFile(const String &name) const {
+bool ZipArchive::hasFile(const Path &path) const {
+	String name = path.toString();
 	return (unzLocateFile(_zipFile, name.c_str(), 2) == UNZ_OK);
 }
 
@@ -1478,14 +1479,16 @@ int ZipArchive::listMembers(ArchiveMemberList &list) const {
 	return members;
 }
 
-const ArchiveMemberPtr ZipArchive::getMember(const String &name) const {
+const ArchiveMemberPtr ZipArchive::getMember(const Path &path) const {
+	String name = path.toString();
 	if (!hasFile(name))
 		return ArchiveMemberPtr();
 
 	return ArchiveMemberPtr(new GenericArchiveMember(name, this));
 }
 
-SeekableReadStream *ZipArchive::createReadStreamForMember(const String &name) const {
+SeekableReadStream *ZipArchive::createReadStreamForMember(const Path &path) const {
+	String name = path.toString();
 	if (unzLocateFile(_zipFile, name.c_str(), 2) != UNZ_OK)
 		return nullptr;
 
diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp
index 500a4c79df..76775832af 100644
--- a/engines/advancedDetector.cpp
+++ b/engines/advancedDetector.cpp
@@ -43,7 +43,8 @@ class FileMapArchive : public Common::Archive {
 public:
 	FileMapArchive(const AdvancedMetaEngineDetection::FileMap &fileMap) : _fileMap(fileMap) {}
 
-	bool hasFile(const Common::String &name) const override {
+	bool hasFile(const Common::Path &path) const override {
+		Common::String name = path.toString();
 		return _fileMap.contains(name);
 	}
 
@@ -57,7 +58,8 @@ public:
 		return files;
 	}
 
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override {
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override {
+		Common::String name = path.toString();
 		AdvancedMetaEngineDetection::FileMap::const_iterator it = _fileMap.find(name);
 		if (it == _fileMap.end()) {
 			return Common::ArchiveMemberPtr();
@@ -66,7 +68,8 @@ public:
 		return Common::ArchiveMemberPtr(new Common::FSNode(it->_value));
 	}
 
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override {
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override {
+		Common::String name = path.toString();
 		Common::FSNode fsNode = _fileMap.getValOrDefault(name);
 		return fsNode.createReadStream();
 	}
diff --git a/engines/glk/blorb.cpp b/engines/glk/blorb.cpp
index 611e5660cc..50b6b750e4 100644
--- a/engines/glk/blorb.cpp
+++ b/engines/glk/blorb.cpp
@@ -39,7 +39,8 @@ Blorb::Blorb(const Common::FSNode &fileNode, InterpreterType interpType) :
 		error("Could not parse blorb file");
 }
 
-bool Blorb::hasFile(const Common::String &name) const {
+bool Blorb::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	for (uint idx = 0; idx < _chunks.size(); ++idx) {
 		if (_chunks[idx]._filename.equalsIgnoreCase(name))
 			return true;
@@ -56,14 +57,16 @@ int Blorb::listMembers(Common::ArchiveMemberList &list) const {
 	return (int)_chunks.size();
 }
 
-const Common::ArchiveMemberPtr Blorb::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr Blorb::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *Blorb::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *Blorb::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	for (uint idx = 0; idx < _chunks.size(); ++idx) {
 		const ChunkEntry &ce = _chunks[idx];
 
diff --git a/engines/glk/blorb.h b/engines/glk/blorb.h
index 50f449a31b..d793d89cc8 100644
--- a/engines/glk/blorb.h
+++ b/engines/glk/blorb.h
@@ -112,7 +112,7 @@ public:
 	 * Patterns are not allowed, as this is meant to be a quick File::exists()
 	 * replacement.
 	 */
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 
 	/**
 	 * Add all members of the Archive to list.
@@ -125,14 +125,14 @@ public:
 	/**
 	 * Returns a ArchiveMember representation of the given file.
 	 */
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
 
 	/**
 	 * Create a stream bound to a member with the specified name in the
 	 * archive. If no member with this name exists, 0 is returned.
 	 * @return the newly created input stream
 	 */
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 
 	/**
 	 * Read the RIdx section from the stream.
diff --git a/engines/glk/comprehend/pics.cpp b/engines/glk/comprehend/pics.cpp
index 4c3fb447e0..3300c64077 100644
--- a/engines/glk/comprehend/pics.cpp
+++ b/engines/glk/comprehend/pics.cpp
@@ -360,7 +360,8 @@ int Pics::getPictureNumber(const Common::String &filename) const {
 	return atoi(num.c_str());
 }
 
-bool Pics::hasFile(const Common::String &name) const {
+bool Pics::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	int num = getPictureNumber(name);
 	if (num == -1)
 		return false;
@@ -379,14 +380,16 @@ int Pics::listMembers(Common::ArchiveMemberList &list) const {
 	return list.size();
 }
 
-const Common::ArchiveMemberPtr Pics::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr Pics::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *Pics::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *Pics::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	// Get the picture number
 	int num = getPictureNumber(name);
 	if (num == -1 || !hasFile(name))
diff --git a/engines/glk/comprehend/pics.h b/engines/glk/comprehend/pics.h
index 01ebee3cf5..bef8c90913 100644
--- a/engines/glk/comprehend/pics.h
+++ b/engines/glk/comprehend/pics.h
@@ -122,7 +122,7 @@ public:
 	 * Patterns are not allowed, as this is meant to be a quick File::exists()
 	 * replacement.
 	 */
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 
 	/**
 	 * Add all members of the Archive to list.
@@ -135,14 +135,14 @@ public:
 	/**
 	 * Returns a ArchiveMember representation of the given file.
 	 */
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
 
 	/**
 	 * Create a stream bound to a member with the specified name in the
 	 * archive. If no member with this name exists, 0 is returned.
 	 * @return the newly created input stream
 	 */
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 };
 
 } // namespace Comprehend
diff --git a/engines/glk/hugo/resource_archive.cpp b/engines/glk/hugo/resource_archive.cpp
index 2a23f9645d..05da9f9669 100644
--- a/engines/glk/hugo/resource_archive.cpp
+++ b/engines/glk/hugo/resource_archive.cpp
@@ -48,7 +48,8 @@ bool ResourceArchive::splitName(const Common::String &name,
 }
 
 
-bool ResourceArchive::hasFile(const Common::String &name) const {
+bool ResourceArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	Common::String filename, resName;
 
 	if (!splitName(name, filename, resName))
@@ -59,14 +60,16 @@ bool ResourceArchive::hasFile(const Common::String &name) const {
 	return resLength != 0;
 }
 
-const Common::ArchiveMemberPtr ResourceArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr ResourceArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *ResourceArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *ResourceArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	Common::String filename, resName;
 
 	// Split up the file and resource entry; return if it's not one
diff --git a/engines/glk/hugo/resource_archive.h b/engines/glk/hugo/resource_archive.h
index f386b313fb..e8cf9b5f1d 100644
--- a/engines/glk/hugo/resource_archive.h
+++ b/engines/glk/hugo/resource_archive.h
@@ -47,7 +47,7 @@ public:
 	 * Patterns are not allowed, as this is meant to be a quick File::exists()
 	 * replacement.
 	 */
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 
 	/**
 	 * Add all members of the Archive to list.
@@ -62,14 +62,14 @@ public:
 	/**
 	 * Returns a ArchiveMember representation of the given file.
 	 */
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
 
 	/**
 	 * Create a stream bound to a member with the specified name in the
 	 * archive. If no member with this name exists, 0 is returned.
 	 * @return the newly created input stream
 	 */
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 };
 
 } // End of namespace Hugo
diff --git a/engines/glk/zcode/pics.cpp b/engines/glk/zcode/pics.cpp
index 9a76a2c07c..7220cbe72f 100644
--- a/engines/glk/zcode/pics.cpp
+++ b/engines/glk/zcode/pics.cpp
@@ -113,7 +113,8 @@ bool Pics::exists() {
 	return Common::File::exists(getFilename());
 }
 
-bool Pics::hasFile(const Common::String &name) const {
+bool Pics::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	for (uint idx = 0; idx < _index.size(); ++idx) {
 		if (_index[idx]._filename.equalsIgnoreCase(name))
 			return true;
@@ -130,14 +131,16 @@ int Pics::listMembers(Common::ArchiveMemberList &list) const {
 	return (int)_index.size();
 }
 
-const Common::ArchiveMemberPtr Pics::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr Pics::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *Pics::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *Pics::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	PictureDecoder decoder;
 
 	for (uint idx = 0; idx < _index.size(); ++idx) {
diff --git a/engines/glk/zcode/pics.h b/engines/glk/zcode/pics.h
index 0d1e970d21..940f08ec0b 100644
--- a/engines/glk/zcode/pics.h
+++ b/engines/glk/zcode/pics.h
@@ -108,7 +108,7 @@ public:
 	 * Patterns are not allowed, as this is meant to be a quick File::exists()
 	 * replacement.
 	 */
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 
 	/**
 	 * Add all members of the Archive to list.
@@ -121,14 +121,14 @@ public:
 	/**
 	 * Returns a ArchiveMember representation of the given file.
 	 */
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
 
 	/**
 	 * Create a stream bound to a member with the specified name in the
 	 * archive. If no member with this name exists, 0 is returned.
 	 * @return the newly created input stream
 	 */
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 };
 
 } // End of namespace ZCode
diff --git a/engines/glk/zcode/sound_folder.cpp b/engines/glk/zcode/sound_folder.cpp
index a40e8be00e..71701f6a4e 100644
--- a/engines/glk/zcode/sound_folder.cpp
+++ b/engines/glk/zcode/sound_folder.cpp
@@ -48,7 +48,8 @@ SoundSubfolder::SoundSubfolder(const Common::FSNode &folder) : _folder(folder) {
 	}
 }
 
-bool SoundSubfolder::hasFile(const Common::String &name) const {
+bool SoundSubfolder::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return _filenames.contains(name);
 }
 
@@ -62,14 +63,16 @@ int SoundSubfolder::listMembers(Common::ArchiveMemberList &list) const {
 	return total;
 }
 
-const Common::ArchiveMemberPtr SoundSubfolder::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr SoundSubfolder::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *SoundSubfolder::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *SoundSubfolder::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	Common::File *f = new Common::File();
 	if (_filenames.contains(name) && f->open(_folder.getChild(_filenames[name])))
 		return f;
@@ -112,7 +115,8 @@ SoundZip::~SoundZip() {
 	delete _zip;
 }
 
-bool SoundZip::hasFile(const Common::String &name) const {
+bool SoundZip::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return _filenames.contains(name);
 }
 
@@ -127,7 +131,8 @@ int SoundZip::listMembers(Common::ArchiveMemberList &list) const {
 	return total;
 }
 
-const Common::ArchiveMemberPtr SoundZip::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr SoundZip::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
@@ -135,7 +140,8 @@ const Common::ArchiveMemberPtr SoundZip::getMember(const Common::String &name) c
 
 }
 
-Common::SeekableReadStream *SoundZip::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *SoundZip::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!_filenames.contains(name))
 		return nullptr;
 
diff --git a/engines/glk/zcode/sound_folder.h b/engines/glk/zcode/sound_folder.h
index 2da45c272c..a0cdb52ca4 100644
--- a/engines/glk/zcode/sound_folder.h
+++ b/engines/glk/zcode/sound_folder.h
@@ -56,7 +56,7 @@ public:
 	 * Patterns are not allowed, as this is meant to be a quick File::exists()
 	 * replacement.
 	 */
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 
 	/**
 	 * Add all members of the Archive to list.
@@ -69,14 +69,14 @@ public:
 	/**
 	 * Returns a ArchiveMember representation of the given file.
 	 */
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
 
 	/**
 	 * Create a stream bound to a member with the specified name in the
 	 * archive. If no member with this name exists, 0 is returned.
 	 * @return the newly created input stream
 	 */
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 };
 
 /**
@@ -109,7 +109,7 @@ public:
 	 * Patterns are not allowed, as this is meant to be a quick File::exists()
 	 * replacement.
 	 */
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 
 	/**
 	 * Add all members of the Archive to list.
@@ -122,14 +122,14 @@ public:
 	/**
 	 * Returns a ArchiveMember representation of the given file.
 	 */
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
 
 	/**
 	 * Create a stream bound to a member with the specified name in the
 	 * archive. If no member with this name exists, 0 is returned.
 	 * @return the newly created input stream
 	 */
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 };
 
 } // End of namespace ZCode
diff --git a/engines/grim/lab.cpp b/engines/grim/lab.cpp
index 777976dc9d..35ce5b6644 100644
--- a/engines/grim/lab.cpp
+++ b/engines/grim/lab.cpp
@@ -146,8 +146,8 @@ void Lab::parseMonkey4FileTable(Common::File *file) {
 	delete[] stringTable;
 }
 
-bool Lab::hasFile(const Common::String &filename) const {
-	Common::String fname(filename);
+bool Lab::hasFile(const Common::Path &filename) const {
+	Common::String fname(filename.toString());
 	fname.toLowercase();
 	return _entries.contains(fname);
 }
@@ -163,7 +163,8 @@ int Lab::listMembers(Common::ArchiveMemberList &list) const {
 	return count;
 }
 
-const Common::ArchiveMemberPtr Lab::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr Lab::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
@@ -172,7 +173,8 @@ const Common::ArchiveMemberPtr Lab::getMember(const Common::String &name) const
 	return _entries[fname];
 }
 
-Common::SeekableReadStream *Lab::createReadStreamForMember(const Common::String &filename) const {
+Common::SeekableReadStream *Lab::createReadStreamForMember(const Common::Path &path) const {
+	Common::String filename = path.toString();
 	if (!hasFile(filename))
 		return nullptr;
 
diff --git a/engines/grim/lab.h b/engines/grim/lab.h
index a60af746ef..c9ff45ed18 100644
--- a/engines/grim/lab.h
+++ b/engines/grim/lab.h
@@ -50,10 +50,10 @@ public:
 	Lab();
 	virtual ~Lab();
 	// Common::Archive implementation
-	virtual bool hasFile(const Common::String &name) const override;
+	virtual bool hasFile(const Common::Path &path) const override;
 	virtual int listMembers(Common::ArchiveMemberList &list) const override;
-	virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	virtual const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	virtual Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 
 private:
 	void parseGrimFileTable(Common::File *_f);
diff --git a/engines/grim/update/lang_filter.cpp b/engines/grim/update/lang_filter.cpp
index 2256338d69..acd78ef252 100644
--- a/engines/grim/update/lang_filter.cpp
+++ b/engines/grim/update/lang_filter.cpp
@@ -66,7 +66,8 @@ LangFilter::~LangFilter() {
 	delete _arc;
 }
 
-bool LangFilter::hasFile(const Common::String &name) const {
+bool LangFilter::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!_arc)
 		return false;
 
@@ -109,11 +110,13 @@ int LangFilter::listMembers(Common::ArchiveMemberList &list) const {
 	return num;
 }
 
-const Common::ArchiveMemberPtr LangFilter::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr LangFilter::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *LangFilter::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *LangFilter::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!_arc)
 		return nullptr;
 
diff --git a/engines/grim/update/lang_filter.h b/engines/grim/update/lang_filter.h
index 54cc2f7fba..33b048e2ae 100644
--- a/engines/grim/update/lang_filter.h
+++ b/engines/grim/update/lang_filter.h
@@ -34,10 +34,10 @@ public:
 	~LangFilter();
 
 	// Common::Archive API implementation
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 private:
 	Common::Archive *_arc;
 
diff --git a/engines/grim/update/mscab.cpp b/engines/grim/update/mscab.cpp
index 6e46f5048b..815a8e7fde 100644
--- a/engines/grim/update/mscab.cpp
+++ b/engines/grim/update/mscab.cpp
@@ -146,7 +146,8 @@ Common::String MsCabinet::readString(Common::ReadStream *stream) {
 	return ret;
 }
 
-bool MsCabinet::hasFile(const Common::String &name) const {
+bool MsCabinet::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return _fileMap.contains(name);
 }
 
@@ -157,11 +158,13 @@ int MsCabinet::listMembers(Common::ArchiveMemberList &list) const {
 	return _fileMap.size();
 }
 
-const Common::ArchiveMemberPtr MsCabinet::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr MsCabinet::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *MsCabinet::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *MsCabinet::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	byte *fileBuf;
 
 	if (!hasFile(name))
diff --git a/engines/grim/update/mscab.h b/engines/grim/update/mscab.h
index 43e9cae962..2ed538c713 100644
--- a/engines/grim/update/mscab.h
+++ b/engines/grim/update/mscab.h
@@ -38,10 +38,10 @@ public:
 	~MsCabinet();
 
 	// Common::Archive API implementation
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 
 private:
 	Common::SeekableReadStream *_data;
diff --git a/engines/kyra/resource/resource_intern.cpp b/engines/kyra/resource/resource_intern.cpp
index 502ac369e0..7d5460b9f9 100644
--- a/engines/kyra/resource/resource_intern.cpp
+++ b/engines/kyra/resource/resource_intern.cpp
@@ -37,7 +37,8 @@ PlainArchive::PlainArchive(Common::ArchiveMemberPtr file)
 	: _file(file), _files() {
 }
 
-bool PlainArchive::hasFile(const Common::String &name) const {
+bool PlainArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return (_files.find(name) != _files.end());
 }
 
@@ -52,14 +53,16 @@ int PlainArchive::listMembers(Common::ArchiveMemberList &list) const {
 	return count;
 }
 
-const Common::ArchiveMemberPtr PlainArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr PlainArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *PlainArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *PlainArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	FileMap::const_iterator fDesc = _files.find(name);
 	if (fDesc == _files.end())
 		return 0;
@@ -92,7 +95,8 @@ TlkArchive::~TlkArchive() {
 	delete[] _fileEntries;
 }
 
-bool TlkArchive::hasFile(const Common::String &name) const {
+bool TlkArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return (findFile(name) != 0);
 }
 
@@ -107,14 +111,16 @@ int TlkArchive::listMembers(Common::ArchiveMemberList &list) const {
 	return count;
 }
 
-const Common::ArchiveMemberPtr TlkArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr TlkArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *TlkArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *TlkArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	const uint32 *fileDesc = findFile(name);
 	if (!fileDesc)
 		return 0;
@@ -186,7 +192,8 @@ CachedArchive::~CachedArchive() {
 	_files.clear();
 }
 
-bool CachedArchive::hasFile(const Common::String &name) const {
+bool CachedArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return (_files.find(name) != _files.end());
 }
 
@@ -201,14 +208,16 @@ int CachedArchive::listMembers(Common::ArchiveMemberList &list) const {
 	return count;
 }
 
-const Common::ArchiveMemberPtr CachedArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr CachedArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *CachedArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *CachedArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	FileMap::const_iterator fDesc = _files.find(name);
 	if (fDesc == _files.end())
 		return 0;
diff --git a/engines/kyra/resource/resource_intern.h b/engines/kyra/resource/resource_intern.h
index ca7e7829b9..b11a2618eb 100644
--- a/engines/kyra/resource/resource_intern.h
+++ b/engines/kyra/resource/resource_intern.h
@@ -50,10 +50,10 @@ public:
 	Entry getFileEntry(const Common::String &name) const;
 
 	// Common::Archive API implementation
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 private:
 	typedef Common::HashMap<Common::String, Entry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap;
 
@@ -66,10 +66,10 @@ public:
 	TlkArchive(Common::ArchiveMemberPtr file, uint16 entryCount, const uint32 *fileEntries);
 	~TlkArchive() override;
 
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 private:
 	Common::ArchiveMemberPtr _file;
 
@@ -93,10 +93,10 @@ public:
 	CachedArchive(const FileInputList &files);
 	~CachedArchive() override;
 
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 private:
 	struct Entry {
 		byte *data;
diff --git a/engines/lastexpress/data/archive.cpp b/engines/lastexpress/data/archive.cpp
index f667da9e1c..bf143afce4 100644
--- a/engines/lastexpress/data/archive.cpp
+++ b/engines/lastexpress/data/archive.cpp
@@ -74,7 +74,8 @@ HPFArchive::HPFArchive(const Common::String &path) {
 	delete archive;
 }
 
-bool HPFArchive::hasFile(const Common::String &name) const {
+bool HPFArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return (_files.find(name) != _files.end());
 }
 
@@ -89,14 +90,16 @@ int HPFArchive::listMembers(Common::ArchiveMemberList &list) const {
 	return numMembers;
 }
 
-const Common::ArchiveMemberPtr HPFArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr HPFArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *HPFArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *HPFArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	FileMap::const_iterator fDesc = _files.find(name);
 	if (fDesc == _files.end())
 		return NULL;
diff --git a/engines/lastexpress/data/archive.h b/engines/lastexpress/data/archive.h
index f51aa25e9a..215fcef618 100644
--- a/engines/lastexpress/data/archive.h
+++ b/engines/lastexpress/data/archive.h
@@ -46,10 +46,10 @@ class HPFArchive : public Common::Archive {
 public:
 	HPFArchive(const Common::String &path);
 
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 
 	int count() { return _files.size(); }
 
diff --git a/engines/lastexpress/resource.cpp b/engines/lastexpress/resource.cpp
index 2a48778c18..1d136bc9a0 100644
--- a/engines/lastexpress/resource.cpp
+++ b/engines/lastexpress/resource.cpp
@@ -144,7 +144,8 @@ Common::SeekableReadStream *ResourceManager::getFileStream(const Common::String
 //////////////////////////////////////////////////////////////////////////
 // Archive functions
 //////////////////////////////////////////////////////////////////////////
-bool ResourceManager::hasFile(const Common::String &name) const {
+bool ResourceManager::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	for (Common::Array<HPFArchive *>::const_iterator it = _archives.begin(); it != _archives.end(); ++it) {
 		if ((*it)->hasFile(name))
 			return true;
@@ -167,14 +168,16 @@ int ResourceManager::listMembers(Common::ArchiveMemberList &list) const {
 	return count;
 }
 
-const Common::ArchiveMemberPtr ResourceManager::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr ResourceManager::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *ResourceManager::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *ResourceManager::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	for (Common::Array<HPFArchive *>::const_iterator it = _archives.begin(); it != _archives.end(); ++it) {
 
 		Common::SeekableReadStream *stream = (*it)->createReadStreamForMember(name);
diff --git a/engines/lastexpress/resource.h b/engines/lastexpress/resource.h
index 6f20f07861..cfec690538 100644
--- a/engines/lastexpress/resource.h
+++ b/engines/lastexpress/resource.h
@@ -45,10 +45,10 @@ public:
 	Common::SeekableReadStream *getFileStream(const Common::String &name) const;
 
 	// Archive functions
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 
 	// Resource loading
 	Background *loadBackground(const Common::String &name) const;
diff --git a/engines/mads/resources.cpp b/engines/mads/resources.cpp
index 01ad4a9b91..d1fce7fbf8 100644
--- a/engines/mads/resources.cpp
+++ b/engines/mads/resources.cpp
@@ -83,10 +83,10 @@ public:
 	~HagArchive() override;
 
 	// Archive implementation
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 };
 
 const char *const MADSCONCAT_STRING = "MADSCONCAT";
@@ -99,7 +99,8 @@ HagArchive::~HagArchive() {
 }
 
 // Archive implementation
-bool HagArchive::hasFile(const Common::String &name) const {
+bool HagArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	HagIndex hagIndex;
 	HagEntry hagEntry;
 	return getHeaderEntry(name, hagIndex, hagEntry);
@@ -122,14 +123,16 @@ int HagArchive::listMembers(Common::ArchiveMemberList &list) const {
 	return members;
 }
 
-const Common::ArchiveMemberPtr HagArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr HagArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *HagArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *HagArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	HagIndex hagIndex;
 	HagEntry hagEntry;
 
diff --git a/engines/mohawk/installer_archive.cpp b/engines/mohawk/installer_archive.cpp
index 62fc953f53..14905faa91 100644
--- a/engines/mohawk/installer_archive.cpp
+++ b/engines/mohawk/installer_archive.cpp
@@ -107,7 +107,8 @@ void InstallerArchive::close() {
 	_map.clear();
 }
 
-bool InstallerArchive::hasFile(const Common::String &name) const {
+bool InstallerArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return _map.contains(name);
 }
 
@@ -118,11 +119,13 @@ int InstallerArchive::listMembers(Common::ArchiveMemberList &list) const {
 	return _map.size();
 }
 
-const Common::ArchiveMemberPtr InstallerArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr InstallerArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *InstallerArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *InstallerArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!_stream || !_map.contains(name))
 		return nullptr;
 
diff --git a/engines/mohawk/installer_archive.h b/engines/mohawk/installer_archive.h
index 19f6343b80..25664ed651 100644
--- a/engines/mohawk/installer_archive.h
+++ b/engines/mohawk/installer_archive.h
@@ -43,10 +43,10 @@ public:
 	bool isOpen() const { return _stream != nullptr; }
 
 	// Common::Archive API implementation
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 
 private:
 	struct FileEntry {
diff --git a/engines/ngi/ngiarchive.cpp b/engines/ngi/ngiarchive.cpp
index 5e246ed023..c2866b4f9a 100644
--- a/engines/ngi/ngiarchive.cpp
+++ b/engines/ngi/ngiarchive.cpp
@@ -100,7 +100,8 @@ NGIArchive::~NGIArchive() {
 	g_nmi->_currArchive = nullptr;
 }
 
-bool NGIArchive::hasFile(const Common::String &name) const {
+bool NGIArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return _headers.contains(name);
 }
 
@@ -116,14 +117,16 @@ int NGIArchive::listMembers(Common::ArchiveMemberList &list) const {
 	return matches;
 }
 
-const Common::ArchiveMemberPtr NGIArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr NGIArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *NGIArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *NGIArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!_headers.contains(name)) {
 		return 0;
 	}
diff --git a/engines/ngi/ngiarchive.h b/engines/ngi/ngiarchive.h
index 1998ec45f5..e7201713c8 100644
--- a/engines/ngi/ngiarchive.h
+++ b/engines/ngi/ngiarchive.h
@@ -51,10 +51,10 @@ public:
 	~NGIArchive() override;
 
 	// Archive implementation
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 };
 
 /**
diff --git a/engines/parallaction/disk_ns.cpp b/engines/parallaction/disk_ns.cpp
index 5e3b1d2d39..13072e1db3 100644
--- a/engines/parallaction/disk_ns.cpp
+++ b/engines/parallaction/disk_ns.cpp
@@ -74,10 +74,10 @@ public:
 	NSArchive(Common::SeekableReadStream *stream, Common::Platform platform, uint32 features);
 	~NSArchive() override;
 
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
-	bool hasFile(const Common::String &name) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
 };
 
 
@@ -123,7 +123,8 @@ uint32 NSArchive::lookup(const char *name) const {
 	return i;
 }
 
-Common::SeekableReadStream *NSArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *NSArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	debugC(3, kDebugDisk, "NSArchive::createReadStreamForMember(%s)", name.c_str());
 
 	if (name.empty())
@@ -139,7 +140,8 @@ Common::SeekableReadStream *NSArchive::createReadStreamForMember(const Common::S
 	return new Common::SeekableSubReadStream(_stream, offset, endOffset, DisposeAfterUse::NO);
 }
 
-bool NSArchive::hasFile(const Common::String &name) const {
+bool NSArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (name.empty())
 		return false;
 	return lookup(name.c_str()) != _numFiles;
@@ -152,7 +154,8 @@ int NSArchive::listMembers(Common::ArchiveMemberList &list) const {
 	return _numFiles;
 }
 
-const Common::ArchiveMemberPtr NSArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr NSArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	uint32 index = lookup(name.c_str());
 
 	const char *item = 0;
diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp
index 22d7d9e719..d974af721d 100644
--- a/engines/prince/archive.cpp
+++ b/engines/prince/archive.cpp
@@ -130,7 +130,8 @@ void PtcArchive::close() {
 	_items.clear();
 }
 
-bool PtcArchive::hasFile(const Common::String &name) const {
+bool PtcArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	// TODO: check if path matching should be added
 	return _items.contains(name);
 }
@@ -146,14 +147,16 @@ int PtcArchive::listMembers(Common::ArchiveMemberList &list) const {
 	return matches;
 }
 
-const Common::ArchiveMemberPtr PtcArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr PtcArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!_items.contains(name)) {
 		Common::ArchiveMemberPtr();
 	}
 	return Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *PtcArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *PtcArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!_items.contains(name)) {
 		return 0;
 	}
diff --git a/engines/prince/archive.h b/engines/prince/archive.h
index 5b4c87399b..3c738c9fdf 100644
--- a/engines/prince/archive.h
+++ b/engines/prince/archive.h
@@ -40,10 +40,10 @@ public:
 	bool isOpen() const { return _stream != 0; }
 
 	// Common::Archive API implementation
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 
 private:
 	struct FileEntry {
diff --git a/engines/stark/formats/xarc.cpp b/engines/stark/formats/xarc.cpp
index 7695f15c5f..7bb6e9a54e 100644
--- a/engines/stark/formats/xarc.cpp
+++ b/engines/stark/formats/xarc.cpp
@@ -134,7 +134,8 @@ Common::String XARCArchive::getFilename() const {
 	return _filename;
 }
 
-bool XARCArchive::hasFile(const Common::String &name) const {
+bool XARCArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	for (Common::ArchiveMemberList::const_iterator it = _members.begin(); it != _members.end(); ++it) {
 		if ((*it)->getName() == name) {
 			// Found it
@@ -170,7 +171,8 @@ int XARCArchive::listMembers(Common::ArchiveMemberList &list) const {
 	return files;
 }
 
-const Common::ArchiveMemberPtr XARCArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr XARCArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	for (Common::ArchiveMemberList::const_iterator it = _members.begin(); it != _members.end(); ++it) {
 		if ((*it)->getName() == name) {
 			// Found it
@@ -182,7 +184,8 @@ const Common::ArchiveMemberPtr XARCArchive::getMember(const Common::String &name
 	return Common::ArchiveMemberPtr();
 }
 
-Common::SeekableReadStream *XARCArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *XARCArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	for (Common::ArchiveMemberList::const_iterator it = _members.begin(); it != _members.end(); ++it) {
 		if ((*it)->getName() == name) {
 			// Found it
diff --git a/engines/stark/formats/xarc.h b/engines/stark/formats/xarc.h
index fb3237f543..24b52ffeba 100644
--- a/engines/stark/formats/xarc.h
+++ b/engines/stark/formats/xarc.h
@@ -37,11 +37,11 @@ public:
 	Common::String getFilename() const;
 
 	// Archive API
-	bool hasFile(const Common::String &name) const;
+	bool hasFile(const Common::Path &path) const;
 	int listMatchingMembers(Common::ArchiveMemberList &list, const Common::String &pattern) const;
 	int listMembers(Common::ArchiveMemberList &list) const;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const;
 
 	Common::SeekableReadStream *createReadStreamForMember(const XARCMember *member) const;
 
diff --git a/engines/trecision/fastfile.cpp b/engines/trecision/fastfile.cpp
index da11c8f9e6..6d15476f54 100644
--- a/engines/trecision/fastfile.cpp
+++ b/engines/trecision/fastfile.cpp
@@ -74,7 +74,8 @@ void FastFile::close() {
 	_fileEntries.clear();
 }
 
-bool FastFile::hasFile(const Common::String &name) const {
+bool FastFile::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	const FileEntry *entry = getEntry(name);
 	return entry != nullptr;
 }
@@ -87,11 +88,13 @@ int FastFile::listMembers(Common::ArchiveMemberList &list) const {
 	return list.size();
 }
 
-const Common::ArchiveMemberPtr FastFile::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr FastFile::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *FastFile::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *FastFile::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!_stream)
 		return nullptr;
 
diff --git a/engines/trecision/fastfile.h b/engines/trecision/fastfile.h
index e318384301..37c0c8522f 100644
--- a/engines/trecision/fastfile.h
+++ b/engines/trecision/fastfile.h
@@ -47,10 +47,10 @@ public:
 	Common::SeekableReadStream *createReadStreamForCompressedMember(const Common::String &name);
 
 	// Common::Archive API implementation
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 
 private:
 	Common::SeekableReadStreamEndian *_stream;
diff --git a/engines/ultima/shared/engine/data_archive.cpp b/engines/ultima/shared/engine/data_archive.cpp
index a464c681d2..e88b8d1358 100644
--- a/engines/ultima/shared/engine/data_archive.cpp
+++ b/engines/ultima/shared/engine/data_archive.cpp
@@ -116,7 +116,8 @@ bool UltimaDataArchive::load(const Common::String &subfolder,
 
 /*-------------------------------------------------------------------*/
 
-bool UltimaDataArchive::hasFile(const Common::String &name) const {
+bool UltimaDataArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!name.hasPrefixIgnoreCase(_publicFolder))
 		return false;
 
@@ -159,14 +160,16 @@ int UltimaDataArchive::listMembers(Common::ArchiveMemberList &list) const {
 	return result;
 }
 
-const Common::ArchiveMemberPtr UltimaDataArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr UltimaDataArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *UltimaDataArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *UltimaDataArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (hasFile(name)) {
 		Common::String filename = innerToPublic(name);
 		return _zip->createReadStreamForMember(filename);
@@ -179,14 +182,16 @@ Common::SeekableReadStream *UltimaDataArchive::createReadStreamForMember(const C
 
 #ifndef RELEASE_BUILD
 
-const Common::ArchiveMemberPtr UltimaDataArchiveProxy::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr UltimaDataArchiveProxy::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *UltimaDataArchiveProxy::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *UltimaDataArchiveProxy::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (hasFile(name))
 		return getNode(name).createReadStream();
 
diff --git a/engines/ultima/shared/engine/data_archive.h b/engines/ultima/shared/engine/data_archive.h
index e95d7b60b2..5b807b28b5 100644
--- a/engines/ultima/shared/engine/data_archive.h
+++ b/engines/ultima/shared/engine/data_archive.h
@@ -72,7 +72,7 @@ public:
 	 * Patterns are not allowed, as this is meant to be a quick File::exists()
 	 * replacement.
 	 */
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 
 	/**
 	 * Add all members of the Archive matching the specified pattern to list.
@@ -94,7 +94,7 @@ public:
 	/**
 	 * Returns a ArchiveMember representation of the given file.
 	 */
-	const Common::ArchiveMemberPtr getMember(const Common::String &name)
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path)
 		const override;
 
 	/**
@@ -103,7 +103,7 @@ public:
 	 * @return the newly created input stream
 	 */
 	Common::SeekableReadStream *createReadStreamForMember(
-		const Common::String &name) const override;
+		const Common::Path &path) const override;
 };
 
 #ifndef RELEASE_BUILD
@@ -136,7 +136,8 @@ public:
 	 * Patterns are not allowed, as this is meant to be a quick File::exists()
 	 * replacement.
 	 */
-	bool hasFile(const Common::String &name) const override {
+	bool hasFile(const Common::Path &path) const override {
+		Common::String name = path.toString();
 		return name.hasPrefixIgnoreCase(_publicFolder) && getNode(name).exists();
 	}
 
@@ -164,7 +165,7 @@ public:
 	/**
 	 * Returns a ArchiveMember representation of the given file.
 	 */
-	const Common::ArchiveMemberPtr getMember(const Common::String &name)
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path)
 		const override;
 
 	/**
@@ -173,7 +174,7 @@ public:
 	 * @return the newly created input stream
 	 */
 	Common::SeekableReadStream *createReadStreamForMember(
-		const Common::String &name) const override;
+		const Common::Path &path) const override;
 };
 
 #endif
diff --git a/engines/ultima/shared/engine/resources.cpp b/engines/ultima/shared/engine/resources.cpp
index 63a0d25915..4087b5ea4c 100644
--- a/engines/ultima/shared/engine/resources.cpp
+++ b/engines/ultima/shared/engine/resources.cpp
@@ -55,7 +55,8 @@ void Resources::addResource(const Common::String &name, const byte *data, size_t
 	Common::copy(data, data + size, &lr._data[0]);
 }
 
-bool Resources::hasFile(const Common::String &name) const {
+bool Resources::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	for (uint idx = 0; idx < _localResources.size(); ++idx)
 		if (!_localResources[idx]._name.compareToIgnoreCase(name))
 			return true;
@@ -71,14 +72,16 @@ int Resources::listMembers(Common::ArchiveMemberList &list) const {
 	return _localResources.size();
 }
 
-const Common::ArchiveMemberPtr Resources::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr Resources::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *Resources::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *Resources::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	for (uint idx = 0; idx < _localResources.size(); ++idx) {
 		const LocalResource &lr = _localResources[idx];
 		if (!lr._name.compareToIgnoreCase(name))
diff --git a/engines/ultima/shared/engine/resources.h b/engines/ultima/shared/engine/resources.h
index 972d12f747..9db48060a9 100644
--- a/engines/ultima/shared/engine/resources.h
+++ b/engines/ultima/shared/engine/resources.h
@@ -168,7 +168,7 @@ public:
 	 * Patterns are not allowed, as this is meant to be a quick File::exists()
 	 * replacement.
 	 */
-	bool hasFile(const Common::String &name) const  override;
+	bool hasFile(const Common::Path &path) const  override;
 
 	/**
 	 * Add all members of the Archive to list.
@@ -181,14 +181,14 @@ public:
 	/**
 	 * Returns a ArchiveMember representation of the given file.
 	 */
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const  override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const  override;
 
 	/**
 	 * Create a stream bound to a member with the specified name in the
 	 * archive. If no member with this name exists, 0 is returned.
 	 * @return the newly created input stream
 	 */
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const  override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const  override;
 };
 
 } // End of namespace Shared
diff --git a/engines/wintermute/base/file/base_package.cpp b/engines/wintermute/base/file/base_package.cpp
index 604d1e95c3..daf66b5bf1 100644
--- a/engines/wintermute/base/file/base_package.cpp
+++ b/engines/wintermute/base/file/base_package.cpp
@@ -247,7 +247,8 @@ PackageSet::~PackageSet() {
 	_packages.clear();
 }
 
-bool PackageSet::hasFile(const Common::String &name) const {
+bool PackageSet::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	Common::String upcName = name;
 	upcName.toUppercase();
 	Common::HashMap<Common::String, Common::ArchiveMemberPtr>::const_iterator it;
@@ -267,7 +268,8 @@ int PackageSet::listMembers(Common::ArchiveMemberList &list) const {
 	return count;
 }
 
-const Common::ArchiveMemberPtr PackageSet::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr PackageSet::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	Common::String upcName = name;
 	upcName.toUppercase();
 	Common::HashMap<Common::String, Common::ArchiveMemberPtr>::const_iterator it;
@@ -275,7 +277,8 @@ const Common::ArchiveMemberPtr PackageSet::getMember(const Common::String &name)
 	return Common::ArchiveMemberPtr(it->_value);
 }
 
-Common::SeekableReadStream *PackageSet::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *PackageSet::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	Common::String upcName = name;
 	upcName.toUppercase();
 	Common::HashMap<Common::String, Common::ArchiveMemberPtr>::const_iterator it;
diff --git a/engines/wintermute/base/file/base_package.h b/engines/wintermute/base/file/base_package.h
index 2b047227b9..e1cd7a56bd 100644
--- a/engines/wintermute/base/file/base_package.h
+++ b/engines/wintermute/base/file/base_package.h
@@ -55,7 +55,7 @@ public:
 	 * Patterns are not allowed, as this is meant to be a quick File::exists()
 	 * replacement.
 	 */
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 
 	/**
 	 * Add all members of the Archive to list.
@@ -68,14 +68,14 @@ public:
 	/**
 	 * Returns a ArchiveMember representation of the given file.
 	 */
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
 
 	/**
 	 * Create a stream bound to a member with the specified name in the
 	 * archive. If no member with this name exists, 0 is returned.
 	 * @return the newly created input stream
 	 */
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 
 	int getPriority() const { return _priority; }
 	uint32 getVersion() const { return _version; }
diff --git a/engines/xeen/files.cpp b/engines/xeen/files.cpp
index 5d8e3b7e4f..fc89bad4f4 100644
--- a/engines/xeen/files.cpp
+++ b/engines/xeen/files.cpp
@@ -121,7 +121,8 @@ void BaseCCArchive::saveIndex(Common::WriteStream &stream) {
 	delete[] rawIndex;
 }
 
-bool BaseCCArchive::hasFile(const Common::String &name) const {
+bool BaseCCArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	CCEntry ccEntry;
 	return getHeaderEntry(name, ccEntry);
 }
@@ -143,7 +144,8 @@ bool BaseCCArchive::getHeaderEntry(uint16 id, CCEntry &ccEntry) const {
 	return false;
 }
 
-const Common::ArchiveMemberPtr BaseCCArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr BaseCCArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!hasFile(name))
 		return Common::ArchiveMemberPtr();
 
@@ -193,7 +195,8 @@ bool CCArchive::getHeaderEntry(const Common::String &resourceName, CCEntry &ccEn
 	return BaseCCArchive::getHeaderEntry(resName, ccEntry);
 }
 
-Common::SeekableReadStream *CCArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *CCArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	CCEntry ccEntry;
 
 	if (getHeaderEntry(name, ccEntry)) {
@@ -465,7 +468,8 @@ SaveArchive::~SaveArchive() {
 	delete[] _data;
 }
 
-Common::SeekableReadStream *SaveArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *SaveArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 
 	// If the given resource has already been perviously "written" to the
 	// save manager, then return that new resource
diff --git a/engines/xeen/files.h b/engines/xeen/files.h
index c677f07dde..a43fd8a43f 100644
--- a/engines/xeen/files.h
+++ b/engines/xeen/files.h
@@ -295,9 +295,9 @@ public:
 	BaseCCArchive() {}
 
 	// Archive implementation
-	bool hasFile(const Common::String &name) const override;
+	bool hasFile(const Common::Path &path) const override;
 	int listMembers(Common::ArchiveMemberList &list) const override;
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
 };
 
 /**
@@ -316,7 +316,7 @@ public:
 	~CCArchive() override;
 
 	// Archive implementation
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 };
 
 class SaveArchive : public BaseCCArchive {
@@ -338,7 +338,7 @@ public:
 	/**
 	 * Archive implementation
 	 */
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 
 	/**
 	 * Archive implementation
diff --git a/engines/zvision/file/zfs_archive.cpp b/engines/zvision/file/zfs_archive.cpp
index 3a385cd8fd..7dd41a6465 100644
--- a/engines/zvision/file/zfs_archive.cpp
+++ b/engines/zvision/file/zfs_archive.cpp
@@ -104,7 +104,8 @@ Common::String ZfsArchive::readEntryName(Common::SeekableReadStream *stream) con
 	return Common::String(buffer);
 }
 
-bool ZfsArchive::hasFile(const Common::String &name) const {
+bool ZfsArchive::hasFile(const Common::Path &path) const {
+	Common::String name = path.toString();
 	return _entryHeaders.contains(name);
 }
 
@@ -119,14 +120,16 @@ int ZfsArchive::listMembers(Common::ArchiveMemberList &list) const {
 	return matches;
 }
 
-const Common::ArchiveMemberPtr ZfsArchive::getMember(const Common::String &name) const {
+const Common::ArchiveMemberPtr ZfsArchive::getMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!_entryHeaders.contains(name))
 		return Common::ArchiveMemberPtr();
 
 	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
-Common::SeekableReadStream *ZfsArchive::createReadStreamForMember(const Common::String &name) const {
+Common::SeekableReadStream *ZfsArchive::createReadStreamForMember(const Common::Path &path) const {
+	Common::String name = path.toString();
 	if (!_entryHeaders.contains(name)) {
 		return 0;
 	}
diff --git a/engines/zvision/file/zfs_archive.h b/engines/zvision/file/zfs_archive.h
index 1711e2e359..cdcd6026c3 100644
--- a/engines/zvision/file/zfs_archive.h
+++ b/engines/zvision/file/zfs_archive.h
@@ -65,7 +65,7 @@ public:
 	 * Patterns are not allowed, as this is meant to be a quick File::exists()
 	 * replacement.
 	 */
-	bool hasFile(const Common::String &fileName) const override;
+	bool hasFile(const Common::Path &path) const override;
 
 	/**
 	 * Add all members of the Archive to list.
@@ -78,7 +78,7 @@ public:
 	/**
 	 * Returns a ArchiveMember representation of the given file.
 	 */
-	const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
 
 	/**
 	 * Create a stream bound to a member with the specified name in the
@@ -86,7 +86,7 @@ public:
 	 *
 	 * @return    The newly created input stream
 	 */
-	Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 
 private:
 	const Common::String _fileName;


Commit: 0d65c2fd127b42d1ddb00caa3848cb19e045f31c
    https://github.com/scummvm/scummvm/commit/0d65c2fd127b42d1ddb00caa3848cb19e045f31c
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
ALL: Use Path type in File functions

Changed paths:
    common/file.cpp
    common/file.h
    engines/pink/file.cpp
    engines/pink/file.h
    engines/scumm/file.cpp
    engines/scumm/file.h
    engines/scumm/file_nes.cpp
    engines/scumm/file_nes.h
    engines/titanic/support/simple_file.cpp
    engines/titanic/support/simple_file.h
    engines/ultima/shared/core/file.cpp
    engines/ultima/shared/core/file.h
    engines/xeen/files.cpp
    engines/xeen/files.h


diff --git a/common/file.cpp b/common/file.cpp
index d421e993e5..81993179ca 100644
--- a/common/file.cpp
+++ b/common/file.cpp
@@ -38,25 +38,25 @@ File::~File() {
 	close();
 }
 
-bool File::open(const String &filename) {
+bool File::open(const Path &filename) {
 	return open(filename, SearchMan);
 }
 
-bool File::open(const String &filename, Archive &archive) {
+bool File::open(const Path &filename, Archive &archive) {
 	assert(!filename.empty());
 	assert(!_handle);
 
 	SeekableReadStream *stream = nullptr;
 
 	if ((stream = archive.createReadStreamForMember(filename))) {
-		debug(8, "Opening hashed: %s", filename.c_str());
+		debug(8, "Opening hashed: %s", filename.toString().c_str());
 	} else if ((stream = archive.createReadStreamForMember(filename + "."))) {
 		// WORKAROUND: Bug #2548: "SIMON1: Game Detection fails"
 		// sometimes instead of "GAMEPC" we get "GAMEPC." (note trailing dot)
-		debug(8, "Opening hashed: %s.", filename.c_str());
+		debug(8, "Opening hashed: %s.", filename.toString().c_str());
 	}
 
-	return open(stream, filename);
+	return open(stream, filename.toString());
 }
 
 bool File::open(const FSNode &node) {
@@ -87,7 +87,7 @@ bool File::open(SeekableReadStream *stream, const String &name) {
 }
 
 
-bool File::exists(const String &filename) {
+bool File::exists(const Path &filename) {
 	if (SearchMan.hasFile(filename)) {
 		return true;
 	} else if (SearchMan.hasFile(filename + ".")) {
diff --git a/common/file.h b/common/file.h
index a731e12e4f..be1c544cdd 100644
--- a/common/file.h
+++ b/common/file.h
@@ -64,7 +64,7 @@ public:
 	 * @param	filename	The file to check for.
 	 * @return	True if the file exists, false otherwise.
 	 */
-	static bool exists(const String &filename);
+	static bool exists(const Path &filename);
 
 	/**
 	 * Try to open the file with the given file name, by searching SearchMan.
@@ -73,7 +73,7 @@ public:
 	 * @param	filename	Name of the file to open.
 	 * @return	True if the file was opened successfully, false otherwise.
 	 */
-	virtual bool open(const String &filename);
+	virtual bool open(const Path &filename);
 
 	/**
 	 * Try to open the file with the given file name from within the given archive.
@@ -83,7 +83,7 @@ public:
 	 * @param	archive		Archive in which to search for the file.
 	 * @return	True if the file was opened successfully, false otherwise.
 	 */
-	virtual bool open(const String &filename, Archive &archive);
+	virtual bool open(const Path &filename, Archive &archive);
 
 	/**
 	 * Try to open the file corresponding to the given node. Will check whether the
diff --git a/engines/pink/file.cpp b/engines/pink/file.cpp
index 4a147454b0..3dbebbd74d 100644
--- a/engines/pink/file.cpp
+++ b/engines/pink/file.cpp
@@ -50,7 +50,7 @@ OrbFile::~OrbFile() {
 	delete[] _table;
 }
 
-bool OrbFile::open(const Common::String &name) {
+bool OrbFile::open(const Common::Path &name) {
 	if (!File::open(name) || readUint32BE() != MKTAG('O', 'R', 'B', '\0'))
 		return false;
 
@@ -122,7 +122,7 @@ void OrbFile::seekToObject(const char *name) {
 	seek(desc->objectsOffset);
 }
 
-bool BroFile::open(const Common::String &name) {
+bool BroFile::open(const Common::Path &name) {
 	if (!File::open(name) || readUint32BE() != MKTAG('B', 'R', 'O', '\0'))
 		return false;
 
diff --git a/engines/pink/file.h b/engines/pink/file.h
index 469bb01e80..230e7a220b 100644
--- a/engines/pink/file.h
+++ b/engines/pink/file.h
@@ -53,7 +53,7 @@ class OrbFile : public Common::File {
 public:
 	OrbFile();
 	~OrbFile() override;
-	bool open(const Common::String &name) override;
+	bool open(const Common::Path &name) override;
 
 public:
 	void loadGame(PinkEngine *game);
@@ -77,7 +77,7 @@ private:
 class BroFile : public Common::File {
 public:
 	BroFile() : _timestamp(0) {}
-	bool open(const Common::String &name) override;
+	bool open(const Common::Path &name) override;
 	uint32 getTimestamp() { return _timestamp; }
 
 private:
diff --git a/engines/scumm/file.cpp b/engines/scumm/file.cpp
index 384c7becdd..e8db237f26 100644
--- a/engines/scumm/file.cpp
+++ b/engines/scumm/file.cpp
@@ -50,7 +50,7 @@ void ScummFile::resetSubfile() {
 	seek(0, SEEK_SET);
 }
 
-bool ScummFile::open(const Common::String &filename) {
+bool ScummFile::open(const Common::Path &filename) {
 	if (File::open(filename)) {
 		resetSubfile();
 		return true;
@@ -187,8 +187,8 @@ uint32 ScummFile::read(void *dataPtr, uint32 dataSize) {
 #pragma mark --- ScummSteamFile ---
 #pragma mark -
 
-bool ScummSteamFile::open(const Common::String &filename) {
-	if (filename.equalsIgnoreCase(_indexFile.indexFileName)) {
+bool ScummSteamFile::open(const Common::Path &filename) {
+	if (filename.toString().equalsIgnoreCase(_indexFile.indexFileName)) {
 		return openWithSubRange(_indexFile.executableName, _indexFile.start, _indexFile.len);
 	} else {
 		// Regular non-bundled file
@@ -323,7 +323,7 @@ bool ScummDiskImage::openDisk(char num) {
 	return true;
 }
 
-bool ScummDiskImage::open(const Common::String &filename) {
+bool ScummDiskImage::open(const Common::Path &filename) {
 	uint16 signature;
 
 	// check signature
diff --git a/engines/scumm/file.h b/engines/scumm/file.h
index d4b1ad9fea..bb549e5917 100644
--- a/engines/scumm/file.h
+++ b/engines/scumm/file.h
@@ -38,7 +38,7 @@ public:
 	BaseScummFile() : _encbyte(0) {}
 	void setEnc(byte value) { _encbyte = value; }
 
-	bool open(const Common::String &filename) override = 0;
+	bool open(const Common::Path &filename) override = 0;
 	virtual bool openSubFile(const Common::String &filename) = 0;
 
 	int64 pos() const override = 0;
@@ -64,7 +64,7 @@ protected:
 public:
 	ScummFile();
 
-	bool open(const Common::String &filename) override;
+	bool open(const Common::Path &filename) override;
 	bool openSubFile(const Common::String &filename) override;
 
 	void clearErr() override { _myEos = false; BaseScummFile::clearErr(); }
@@ -109,7 +109,7 @@ private:
 public:
 	ScummDiskImage(const char *disk1, const char *disk2, GameSettings game);
 
-	bool open(const Common::String &filename) override;
+	bool open(const Common::Path &filename) override;
 	bool openSubFile(const Common::String &filename) override;
 
 	void close() override;
@@ -138,7 +138,7 @@ private:
 public:
 	ScummSteamFile(const SteamIndexFile &indexFile) : ScummFile(), _indexFile(indexFile) {}
 
-	bool open(const Common::String &filename) override;
+	bool open(const Common::Path &filename) override;
 };
 
 } // End of namespace Scumm
diff --git a/engines/scumm/file_nes.cpp b/engines/scumm/file_nes.cpp
index c8f3d39c7a..02654e0bf3 100644
--- a/engines/scumm/file_nes.cpp
+++ b/engines/scumm/file_nes.cpp
@@ -1361,7 +1361,7 @@ bool ScummNESFile::generateIndex() {
 	return true;
 }
 
-bool ScummNESFile::open(const Common::String &filename) {
+bool ScummNESFile::open(const Common::Path &filename) {
 
 	if (_ROMset == kROMsetNum) {
 		Common::String md5str;
diff --git a/engines/scumm/file_nes.h b/engines/scumm/file_nes.h
index 0f8c9c2eed..4a687818c1 100644
--- a/engines/scumm/file_nes.h
+++ b/engines/scumm/file_nes.h
@@ -79,7 +79,7 @@ private:
 public:
 	ScummNESFile();
 
-	bool open(const Common::String &filename) override;
+	bool open(const Common::Path &filename) override;
 	bool openSubFile(const Common::String &filename) override;
 
 	void close() override;
diff --git a/engines/titanic/support/simple_file.cpp b/engines/titanic/support/simple_file.cpp
index 83d731f7f2..e04e780af3 100644
--- a/engines/titanic/support/simple_file.cpp
+++ b/engines/titanic/support/simple_file.cpp
@@ -36,9 +36,9 @@ CString readStringFromStream(Common::SeekableReadStream *s) {
 
 /*------------------------------------------------------------------------*/
 
-bool File::open(const Common::String &filename) {
+bool File::open(const Common::Path &filename) {
 	if (!Common::File::open(filename))
-		error("Could not open file - %s", filename.c_str());
+		error("Could not open file - %s", filename.toString().c_str());
 	return true;
 }
 
diff --git a/engines/titanic/support/simple_file.h b/engines/titanic/support/simple_file.h
index e3d1d798dc..7c8aa10662 100644
--- a/engines/titanic/support/simple_file.h
+++ b/engines/titanic/support/simple_file.h
@@ -41,7 +41,7 @@ class DecompressorData;
  */
 class File : public Common::File {
 public:
-	bool open(const Common::String &filename) override;
+	bool open(const Common::Path &filename) override;
 };
 
 /**
diff --git a/engines/ultima/shared/core/file.cpp b/engines/ultima/shared/core/file.cpp
index aeb225163f..3944b3b412 100644
--- a/engines/ultima/shared/core/file.cpp
+++ b/engines/ultima/shared/core/file.cpp
@@ -28,6 +28,7 @@ namespace Ultima {
 namespace Shared {
 
 #define ERROR error("Could not open file - %s", name.c_str())
+#define PATH_ERROR error("Could not open file - %s", name.toString().c_str())
 
 File::File(const Common::String &name) : Common::File(), _filesize(-1) {
 	close();
@@ -36,19 +37,19 @@ File::File(const Common::String &name) : Common::File(), _filesize(-1) {
 		ERROR;
 }
 
-bool File::open(const Common::String &name) {
+bool File::open(const Common::Path &name) {
 	close();
 
 	if (!Common::File::open(name))
-		ERROR;
+		PATH_ERROR;
 	return true;
 }
 
-bool File::open(const Common::String &name, Common::Archive &archive) {
+bool File::open(const Common::Path &name, Common::Archive &archive) {
 	close();
 
 	if (!Common::File::open(name, archive))
-		ERROR;
+		PATH_ERROR;
 	return true;
 }
 
diff --git a/engines/ultima/shared/core/file.h b/engines/ultima/shared/core/file.h
index 647cdb3cc2..0ce7d60dad 100644
--- a/engines/ultima/shared/core/file.h
+++ b/engines/ultima/shared/core/file.h
@@ -43,14 +43,14 @@ public:
 	 * Open the file with the given filename, by searching SearchMan.
 	 * @param	name	the name of the file to open
 	 */
-	bool open(const Common::String &name) override;
+	bool open(const Common::Path &name) override;
 
 	/**
 	 * Open the file with the given filename from within the given archive.
 	 * @param	name	the name of the file to open
 	 * @param	archive		the archive in which to search for the file
 	 */
-	bool open(const Common::String &name, Common::Archive &archive) override;
+	bool open(const Common::Path &name, Common::Archive &archive) override;
 
 	/**
 	 * Open the file corresponding to the give node.
diff --git a/engines/xeen/files.cpp b/engines/xeen/files.cpp
index fc89bad4f4..a0d57e858a 100644
--- a/engines/xeen/files.cpp
+++ b/engines/xeen/files.cpp
@@ -324,21 +324,21 @@ File::File(const Common::String &filename, int ccMode) {
 	File::open(filename, ccMode);
 }
 
-bool File::open(const Common::String &filename) {
+bool File::open(const Common::Path &filename) {
 	if (!_currentSave || !Common::File::open(filename, *_currentSave)) {
 		if (!Common::File::open(filename, *_currentArchive)) {
 			// Could not find in current archive, so try intro.cc or in folder
 			if (!Common::File::open(filename))
-				error("Could not open file - %s", filename.c_str());
+				error("Could not open file - %s", filename.toString().c_str());
 		}
 	}
 
 	return true;
 }
 
-bool File::open(const Common::String &filename, Common::Archive &archive) {
+bool File::open(const Common::Path &filename, Common::Archive &archive) {
 	if (!Common::File::open(filename, archive))
-		error("Could not open file - %s", filename.c_str());
+		error("Could not open file - %s", filename.toString().c_str());
 	return true;
 }
 
diff --git a/engines/xeen/files.h b/engines/xeen/files.h
index a43fd8a43f..c46cf3b2db 100644
--- a/engines/xeen/files.h
+++ b/engines/xeen/files.h
@@ -144,12 +144,12 @@ public:
 	/**
 	 * Opens the given file, throwing an error if it can't be opened
 	 */
-	bool open(const Common::String &filename) override;
+	bool open(const Common::Path &filename) override;
 
 	/**
 	 * Opens the given file, throwing an error if it can't be opened
 	 */
-	bool open(const Common::String &filename, Common::Archive &archive) override;
+	bool open(const Common::Path &filename, Common::Archive &archive) override;
 
 	/**
 	 * Opens the given file, throwing an error if it can't be opened


Commit: 48ce80a32c2def332362a30e044b56e08a540086
    https://github.com/scummvm/scummvm/commit/48ce80a32c2def332362a30e044b56e08a540086
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
AGS: Fix String -> Path conversions

Changed paths:
    engines/ags/engine/ac/listbox.cpp
    engines/ags/shared/util/directory.cpp


diff --git a/engines/ags/engine/ac/listbox.cpp b/engines/ags/engine/ac/listbox.cpp
index 46a54d65f8..e8604c0144 100644
--- a/engines/ags/engine/ac/listbox.cpp
+++ b/engines/ags/engine/ac/listbox.cpp
@@ -82,7 +82,7 @@ void FillDirList(std::set<String> &files, const String &path) {
 		return;
 	}
 
-	Common::FSDirectory dir(dirName);
+	Common::FSDirectory dir(dirName.GetCStr());
 	Common::ArchiveMemberList fileList;
 	dir.listMatchingMembers(fileList, filePattern);
 	for (Common::ArchiveMemberList::iterator iter = fileList.begin(); iter != fileList.end(); ++iter) {
diff --git a/engines/ags/shared/util/directory.cpp b/engines/ags/shared/util/directory.cpp
index d525cbc910..7e0c322909 100644
--- a/engines/ags/shared/util/directory.cpp
+++ b/engines/ags/shared/util/directory.cpp
@@ -92,7 +92,7 @@ String GetCurrentDirectory() {
 }
 
 static bool GetFilesImpl(const String &dir_path, std::vector<String> &files, bool isDirectories) {
-	Common::FSNode fsNode(dir_path);
+	Common::FSNode fsNode(dir_path.GetCStr());
 	Common::FSList fsList;
 
 	fsNode.getChildren(fsList,
@@ -120,7 +120,7 @@ FindFile::~FindFile() {
 
 FindFile FindFile::Open(const String &path, const String &wildcard, bool do_file, bool do_dir) {
 	FindFile ff;
-	ff._folder = Common::FSNode(path);
+	ff._folder = Common::FSNode(path.GetCStr());
 
 	Common::FSNode::ListMode mode = Common::FSNode::kListAll;
 	if (do_file && !do_dir)


Commit: 909595176a78f82e669b4ec3d011c4323860313d
    https://github.com/scummvm/scummvm/commit/909595176a78f82e669b4ec3d011c4323860313d
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
COMMON: Use Path type in MacResManager functions

Changed paths:
    common/macresman.cpp
    common/macresman.h
    engines/director/archive.cpp
    engines/pegasus/surface.cpp
    engines/wage/world.cpp
    gui/debugger.cpp


diff --git a/common/macresman.cpp b/common/macresman.cpp
index 49c4545b7d..83dbe66408 100644
--- a/common/macresman.cpp
+++ b/common/macresman.cpp
@@ -115,11 +115,11 @@ String MacResManager::computeResForkMD5AsString(uint32 length) const {
 	return computeStreamMD5AsString(resForkStream, MIN<uint32>(length, _resForkSize));
 }
 
-bool MacResManager::open(const String &fileName) {
+bool MacResManager::open(const Path &fileName) {
 	return open(fileName, SearchMan);
 }
 
-bool MacResManager::open(const String &fileName, Archive &archive) {
+bool MacResManager::open(const Path &fileName, Archive &archive) {
 	close();
 
 #ifdef MACOSX
@@ -185,7 +185,7 @@ bool MacResManager::open(const String &fileName, Archive &archive) {
 	return false;
 }
 
-bool MacResManager::exists(const String &fileName) {
+bool MacResManager::exists(const Path &fileName) {
 	// Try the file name by itself
 	if (File::exists(fileName))
 		return true;
@@ -216,7 +216,7 @@ void MacResManager::listFiles(StringArray &files, const String &pattern) {
 	SearchMan.listMatchingMembers(memberList, pattern);
 	SearchMan.listMatchingMembers(memberList, pattern + ".rsrc");
 	SearchMan.listMatchingMembers(memberList, pattern + ".bin");
-	SearchMan.listMatchingMembers(memberList, constructAppleDoubleName(pattern));
+	SearchMan.listMatchingMembers(memberList, constructAppleDoubleName(pattern).toString());
 
 	for (ArchiveMemberList::const_iterator i = memberList.begin(), end = memberList.end(); i != end; ++i) {
 		String filename = (*i)->getName();
@@ -254,7 +254,7 @@ void MacResManager::listFiles(StringArray &files, const String &pattern) {
 
 		// Strip AppleDouble '._' prefix if applicable.
 		bool isAppleDoubleName = false;
-		const String filenameAppleDoubleStripped = disassembleAppleDoubleName(filename, &isAppleDoubleName);
+		const String filenameAppleDoubleStripped = disassembleAppleDoubleName(filename, &isAppleDoubleName).toString();
 
 		if (isAppleDoubleName) {
 			SeekableReadStream *stream = (*i)->createReadStream();
@@ -606,39 +606,41 @@ void MacResManager::readMap() {
 	}
 }
 
-String MacResManager::constructAppleDoubleName(String name) {
+Path MacResManager::constructAppleDoubleName(Path name) {
 	// Insert "._" before the last portion of a path name
-	for (int i = name.size() - 1; i >= 0; i--) {
+	String rawName = name.rawString();
+	for (int i = rawName.size() - 1; i >= 0; i--) {
 		if (i == 0) {
-			name.insertChar('_', 0);
-			name.insertChar('.', 0);
-		} else if (name[i] == '/') {
-			name.insertChar('_', i + 1);
-			name.insertChar('.', i + 1);
+			rawName.insertChar('_', 0);
+			rawName.insertChar('.', 0);
+		} else if (rawName[i] == DIR_SEPARATOR) {
+			rawName.insertChar('_', i + 1);
+			rawName.insertChar('.', i + 1);
 			break;
 		}
 	}
 
-	return name;
+	return Path(rawName, DIR_SEPARATOR);
 }
 
-String MacResManager::disassembleAppleDoubleName(String name, bool *isAppleDouble) {
+Path MacResManager::disassembleAppleDoubleName(Path name, bool *isAppleDouble) {
 	if (isAppleDouble) {
 		*isAppleDouble = false;
 	}
 
 	// Remove "._" before the last portion of a path name.
-	for (int i = name.size() - 1; i >= 0; --i) {
+	String rawName = name.rawString();
+	for (int i = rawName.size() - 1; i >= 0; --i) {
 		if (i == 0) {
-			if (name.size() > 2 && name[0] == '.' && name[1] == '_') {
-				name.erase(0, 2);
+			if (rawName.size() > 2 && rawName[0] == '.' && rawName[1] == '_') {
+				rawName.erase(0, 2);
 				if (isAppleDouble) {
 					*isAppleDouble = true;
 				}
 			}
-		} else if (name[i] == '/') {
-			if ((uint)(i + 2) < name.size() && name[i + 1] == '.' && name[i + 2] == '_') {
-				name.erase(i + 1, 2);
+		} else if (rawName[i] == DIR_SEPARATOR) {
+			if ((uint)(i + 2) < rawName.size() && rawName[i + 1] == '.' && rawName[i + 2] == '_') {
+				rawName.erase(i + 1, 2);
 				if (isAppleDouble) {
 					*isAppleDouble = true;
 				}
@@ -647,7 +649,7 @@ String MacResManager::disassembleAppleDoubleName(String name, bool *isAppleDoubl
 		}
 	}
 
-	return name;
+	return Path(rawName, DIR_SEPARATOR);
 }
 
 void MacResManager::dumpRaw() {
@@ -666,7 +668,7 @@ void MacResManager::dumpRaw() {
 				dataSize = len;
 			}
 
-			Common::String filename = Common::String::format("./dumps/%s-%s-%d", _baseFileName.c_str(), tag2str(_resTypes[i].id), j);
+			Common::String filename = Common::String::format("./dumps/%s-%s-%d", _baseFileName.toString().c_str(), tag2str(_resTypes[i].id), j);
 			_stream->read(data, len);
 
 			if (!out.open(filename)) {
diff --git a/common/macresman.h b/common/macresman.h
index 5ab2b4d6b7..f03b558008 100644
--- a/common/macresman.h
+++ b/common/macresman.h
@@ -75,7 +75,7 @@ public:
 	 * @note This will check for the raw resource fork, MacBinary, and AppleDouble formats.
 	 * @return True on success
 	 */
-	bool open(const String &fileName);
+	bool open(const Path &fileName);
 
 	/**
 	 * Open a Mac data/resource fork pair from within the given archive.
@@ -85,14 +85,14 @@ public:
 	 * @note This will check for the raw resource fork, MacBinary, and AppleDouble formats.
 	 * @return True on success
 	 */
-	bool open(const String &fileName, Archive &archive);
+	bool open(const Path &fileName, Archive &archive);
 
 	/**
 	 * See if a Mac data/resource fork pair exists.
 	 * @param fileName The base file name of the file
 	 * @return True if either a data fork or resource fork with this name exists
 	 */
-	static bool exists(const String &fileName);
+	static bool exists(const Path &fileName);
 
 	/**
 	 * List all filenames matching pattern for opening with open().
@@ -178,9 +178,9 @@ public:
 	 * Get the base file name of the data/resource fork pair
 	 * @return The base file name of the data/resource fork pair
 	 */
-	String getBaseFileName() const { return _baseFileName; }
+	Path getBaseFileName() const { return _baseFileName; }
 
-	void setBaseFileName(Common::String str) { _baseFileName = str; }
+	void setBaseFileName(Common::Path str) { _baseFileName = str; }
 
 	/**
 	 * Return list of resource IDs with specified type ID
@@ -222,15 +222,15 @@ public:
 
 private:
 	SeekableReadStream *_stream;
-	String _baseFileName;
+	Path _baseFileName;
 
 	bool load(SeekableReadStream &stream);
 
 	bool loadFromRawFork(SeekableReadStream &stream);
 	bool loadFromAppleDouble(SeekableReadStream &stream);
 
-	static String constructAppleDoubleName(String name);
-	static String disassembleAppleDoubleName(String name, bool *isAppleDouble);
+	static Path constructAppleDoubleName(Path name);
+	static Path disassembleAppleDoubleName(Path name, bool *isAppleDouble);
 
 	/**
 	 * Do a sanity check whether the given stream is a raw resource fork.
diff --git a/engines/director/archive.cpp b/engines/director/archive.cpp
index a01cd7df1f..e269c2ef9e 100644
--- a/engines/director/archive.cpp
+++ b/engines/director/archive.cpp
@@ -230,7 +230,7 @@ bool MacArchive::openFile(const Common::String &fileName) {
 		return false;
 	}
 
-	_pathName = _resFork->getBaseFileName();
+	_pathName = _resFork->getBaseFileName().toString();
 	if (_pathName.hasSuffix(".bin")) {
 		for (int i = 0; i < 4; i++)
 			_pathName.deleteLastChar();
diff --git a/engines/pegasus/surface.cpp b/engines/pegasus/surface.cpp
index 8ff2a3a9ce..6a624397a7 100644
--- a/engines/pegasus/surface.cpp
+++ b/engines/pegasus/surface.cpp
@@ -92,10 +92,10 @@ void Surface::getImageFromPICTFile(const Common::String &fileName) {
 void Surface::getImageFromPICTResource(Common::MacResManager *resFork, uint16 id) {
 	Common::SeekableReadStream *res = resFork->getResource(MKTAG('P', 'I', 'C', 'T'), id);
 	if (!res)
-		error("Could not open PICT resource %d from '%s'", id, resFork->getBaseFileName().c_str());
+		error("Could not open PICT resource %d from '%s'", id, resFork->getBaseFileName().toString().c_str());
 
 	if (!getImageFromPICTStream(res))
-		error("Failed to load PICT resource %d from '%s'", id, resFork->getBaseFileName().c_str());
+		error("Failed to load PICT resource %d from '%s'", id, resFork->getBaseFileName().toString().c_str());
 
 	delete res;
 }
diff --git a/engines/wage/world.cpp b/engines/wage/world.cpp
index 713207070c..6a84ce956e 100644
--- a/engines/wage/world.cpp
+++ b/engines/wage/world.cpp
@@ -140,7 +140,7 @@ bool World::loadWorld(Common::MacResManager *resMan) {
 	if ((resArray = resMan->getResIDArray(MKTAG('V','E','R','S'))).size() == 0)
 		return false;
 
-	_name = resMan->getBaseFileName();
+	_name = resMan->getBaseFileName().toString();
 
 	if (resArray.size() > 1)
 		warning("Too many VERS resources");
@@ -160,7 +160,7 @@ bool World::loadWorld(Common::MacResManager *resMan) {
 		res->skip(3);
 		_aboutMessage = res->readPascalString();
 
-		if (!scumm_stricmp(resMan->getBaseFileName().c_str(), "Scepters"))
+		if (!scumm_stricmp(resMan->getBaseFileName().toString().c_str(), "Scepters"))
 			res->skip(1); // ????
 
 		_soundLibrary1 = res->readPascalString();
diff --git a/gui/debugger.cpp b/gui/debugger.cpp
index 788256982b..7e0ef99381 100644
--- a/gui/debugger.cpp
+++ b/gui/debugger.cpp
@@ -693,17 +693,17 @@ bool Debugger::cmdMd5Mac(int argc, const char **argv) {
 			debugPrintf("Resource file '%s' not found\n", filename.c_str());
 		} else {
 			if (!macResMan.hasResFork() && !macResMan.hasDataFork()) {
-				debugPrintf("'%s' has neither data not resource fork\n", macResMan.getBaseFileName().c_str());
+				debugPrintf("'%s' has neither data not resource fork\n", macResMan.getBaseFileName().toString().c_str());
 			} else {
 				// The resource fork is probably the most relevant one.
 				if (macResMan.hasResFork()) {
 					Common::String md5 = macResMan.computeResForkMD5AsString(length);
-					debugPrintf("%s  %s (resource)  %d\n", md5.c_str(), macResMan.getBaseFileName().c_str(), macResMan.getResForkDataSize());
+					debugPrintf("%s  %s (resource)  %d\n", md5.c_str(), macResMan.getBaseFileName().toString().c_str(), macResMan.getResForkDataSize());
 				}
 				if (macResMan.hasDataFork()) {
 					Common::SeekableReadStream *stream = macResMan.getDataFork();
 					Common::String md5 = Common::computeStreamMD5AsString(*stream, length);
-					debugPrintf("%s  %s (data)  %d\n", md5.c_str(), macResMan.getBaseFileName().c_str(), (int32)stream->size());
+					debugPrintf("%s  %s (data)  %d\n", md5.c_str(), macResMan.getBaseFileName().toString().c_str(), (int32)stream->size());
 				}
 			}
 			macResMan.close();


Commit: 17297ea7ef5eda86fac8f7b272ad5abeec103879
    https://github.com/scummvm/scummvm/commit/17297ea7ef5eda86fac8f7b272ad5abeec103879
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
COMMON: Use Path type in punycode_decodepath

Changed paths:
    common/punycode.cpp
    common/punycode.h
    engines/director/director.cpp


diff --git a/common/punycode.cpp b/common/punycode.cpp
index dbef1db48a..4c5917dec3 100644
--- a/common/punycode.cpp
+++ b/common/punycode.cpp
@@ -352,17 +352,17 @@ String punycode_decodefilename(const String src1) {
 	return dst;
 }
 
-String punycode_decodepath(const String src) {
-	StringTokenizer tok(src, "/");
+Path punycode_decodepath(const Path &src) {
+	StringTokenizer tok(src.rawString(), Common::String(DIR_SEPARATOR));
 	String res;
 
 	while (!tok.empty()) {
 		res += punycode_decodefilename(tok.nextToken());
 		if (!tok.empty())
-			res += '/';
+			res += DIR_SEPARATOR;
 	}
 
-	return res;
+	return Path(res, DIR_SEPARATOR);
 }
 
 } // end of namespace Common
diff --git a/common/punycode.h b/common/punycode.h
index 63838657bb..d713de09ef 100644
--- a/common/punycode.h
+++ b/common/punycode.h
@@ -44,6 +44,7 @@
 #ifndef COMMON_PUNYCODE_H
 #define COMMON_PUNYCODE_H
 
+#include "common/path.h"
 #include "common/str.h"
 
 namespace Common {
@@ -69,7 +70,7 @@ String punycode_decodefilename(const String src1);
 /**
  * Convert path with '/' as separators from Punycode
  */
-String punycode_decodepath(const String src);
+Path punycode_decodepath(const Path &src);
 
 bool punycode_hasprefix(const String src);
 
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index 57f60e3ae6..6b76e7a327 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -272,7 +272,7 @@ void DirectorEngine::parseOptions() {
 			}
 
 			if (Common::punycode_hasprefix(_options.startMovie.startMovie))
-				_options.startMovie.startMovie = Common::punycode_decodepath(_options.startMovie.startMovie);
+				_options.startMovie.startMovie = Common::punycode_decodepath(_options.startMovie.startMovie).toString();
 
 			debug(2, "parseOptions(): Movie is: %s, frame is: %d", _options.startMovie.startMovie.c_str(), _options.startMovie.startFrame);
 		} else if (key == "startup") {


Commit: 02aace0598c61b02e14fbdd8f580f4e81d81d7b5
    https://github.com/scummvm/scummvm/commit/02aace0598c61b02e14fbdd8f580f4e81d81d7b5
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
DIRECTOR: Use ':' as directory separator

Changed paths:
    engines/director/archive.cpp
    engines/director/director.cpp
    engines/director/director.h
    engines/director/lingo/lingo-funcs.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/resource.cpp
    engines/director/score.cpp
    engines/director/sound.cpp
    engines/director/util.cpp
    engines/director/window.cpp


diff --git a/engines/director/archive.cpp b/engines/director/archive.cpp
index e269c2ef9e..b6783c57a5 100644
--- a/engines/director/archive.cpp
+++ b/engines/director/archive.cpp
@@ -49,7 +49,7 @@ Common::String Archive::getFileName() const { return Director::getFileName(_path
 bool Archive::openFile(const Common::String &fileName) {
 	Common::File *file = new Common::File();
 
-	if (!file->open(fileName)) {
+	if (!file->open(Common::Path(fileName, g_director->_dirSeparator))) {
 		warning("Archive::openFile(): Error opening file %s", fileName.c_str());
 		delete file;
 		return false;
@@ -225,12 +225,12 @@ bool MacArchive::openFile(const Common::String &fileName) {
 
 	Common::String fName = fileName;
 
-	if (!_resFork->open(fName) || !_resFork->hasResFork()) {
+	if (!_resFork->open(Common::Path(fName, g_director->_dirSeparator)) || !_resFork->hasResFork()) {
 		close();
 		return false;
 	}
 
-	_pathName = _resFork->getBaseFileName().toString();
+	_pathName = _resFork->getBaseFileName().toString(g_director->_dirSeparator);
 	if (_pathName.hasSuffix(".bin")) {
 		for (int i = 0; i < 4; i++)
 			_pathName.deleteLastChar();
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index 6b76e7a327..ab5b1fea57 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -102,6 +102,7 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
 	_playbackPaused = false;
 	_skipFrameAdvance = false;
 	_centerStage = true;
+	_dirSeparator = ':';
 
 	_surface = nullptr;
 }
@@ -272,7 +273,7 @@ void DirectorEngine::parseOptions() {
 			}
 
 			if (Common::punycode_hasprefix(_options.startMovie.startMovie))
-				_options.startMovie.startMovie = Common::punycode_decodepath(_options.startMovie.startMovie).toString();
+				_options.startMovie.startMovie = Common::punycode_decodepath(_options.startMovie.startMovie).toString(_dirSeparator);
 
 			debug(2, "parseOptions(): Movie is: %s, frame is: %d", _options.startMovie.startMovie.c_str(), _options.startMovie.startFrame);
 		} else if (key == "startup") {
diff --git a/engines/director/director.h b/engines/director/director.h
index 9c6da3c54b..2ac178ec37 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -255,6 +255,7 @@ public:
 	bool _playbackPaused;
 	bool _skipFrameAdvance;
 	bool _centerStage;
+	char _dirSeparator;
 
 	Common::HashMap<Common::String, Archive *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _openResFiles;
 
diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index 52b9945389..4acf0dc6a3 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -296,7 +296,7 @@ void Lingo::func_play(Datum &frame, Datum &movie) {
 	}
 
 	if (movie.type != VOID) {
-		ref.movie = unixToMacPath(_vm->getCurrentMovie()->_movieArchive->getPathName());
+		ref.movie = _vm->getCurrentMovie()->_movieArchive->getPathName();
 	}
 	ref.frameI = _vm->getCurrentMovie()->getScore()->getCurrentFrame();
 
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index b84e9fbcf6..caa5c15fde 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -691,7 +691,7 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 	case kTheMoviePath:
 	case kThePathName:
 		d.type = STRING;
-		d.u.s = new Common::String(unixToMacPath(_vm->getCurrentPath()));
+		d.u.s = new Common::String(_vm->getCurrentPath());
 		break;
 	case kTheMultiSound:
 		// We always support multiple sound channels!
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 6c85870893..9ebe005476 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -206,7 +206,7 @@ void Window::loadEXE(const Common::String movie) {
 		warning("No LINGO.INI");
 	}
 
-	Common::SeekableReadStream *exeStream = SearchMan.createReadStreamForMember(movie);
+	Common::SeekableReadStream *exeStream = SearchMan.createReadStreamForMember(Common::Path(movie, g_director->_dirSeparator));
 	if (!exeStream)
 		error("Failed to open EXE '%s'", g_director->getEXEName().c_str());
 
@@ -382,7 +382,7 @@ void Window::loadMac(const Common::String movie) {
 		// The RIFX is located in the data fork of the executable
 		_macBinary = new Common::MacResManager();
 
-		if (!_macBinary->open(movie) || !_macBinary->hasDataFork())
+		if (!_macBinary->open(Common::Path(movie, g_director->_dirSeparator)) || !_macBinary->hasDataFork())
 			error("Failed to open Mac binary '%s'", movie.c_str());
 
 		Common::SeekableReadStream *dataFork = _macBinary->getDataFork();
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 39352966ae..cf0616a561 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -622,7 +622,7 @@ void Score::screenShot() {
 	const Graphics::PixelFormat requiredFormat_4byte(4, 8, 8, 8, 8, 0, 8, 16, 24);
 	Graphics::Surface *newSurface = rawSurface.convertTo(requiredFormat_4byte, _vm->getPalette());
 	Common::String currentPath = _vm->getCurrentPath().c_str();
-	Common::replace(currentPath, "/", "-"); // exclude '/' from screenshot filename prefix
+	Common::replace(currentPath, Common::String(g_director->_dirSeparator), "-"); // exclude dir separator from screenshot filename prefix
 	Common::String prefix = Common::String::format("%s%s", currentPath.c_str(), _movie->getMacName().c_str());
 	Common::String filename = dumpScriptName(prefix.c_str(), kMovieScript, _framesRan, "png");
 
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 0affc4333d..816dc7d98f 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -709,7 +709,7 @@ Audio::AudioStream *AudioFileDecoder::getAudioStream(bool looping, DisposeAfterU
 		return nullptr;
 
 	Common::File *file = new Common::File();
-	if (!file->open(_path)) {
+	if (!file->open(Common::Path(_path, g_director->_dirSeparator))) {
 		warning("Failed to open %s", _path.c_str());
 		return nullptr;
 	}
diff --git a/engines/director/util.cpp b/engines/director/util.cpp
index b845e93d44..724a8f2775 100644
--- a/engines/director/util.cpp
+++ b/engines/director/util.cpp
@@ -220,7 +220,7 @@ Common::String convertPath(Common::String &path) {
 	if (path.empty())
 		return path;
 
-	if (!path.contains(':') && !path.contains('/') && !path.contains('\\') && !path.contains('@')) {
+	if (!path.contains(':') && !path.contains('\\') && !path.contains('@')) {
 		return path;
 	}
 
@@ -228,10 +228,10 @@ Common::String convertPath(Common::String &path) {
 	uint32 idx = 0;
 
 	if (path.hasPrefix("::")) { // Parent directory
-		res = "..\\";
+		res = "..:";
 		idx = 2;
 	} else if (path.hasPrefix("@:")) { // Root of the game
-		res = ".\\";
+		res = ".:";
 		idx = 2;
 	} else if (path.size() >= 3
 					&& Common::isAlpha(path[0])
@@ -239,30 +239,22 @@ Common::String convertPath(Common::String &path) {
 					&& path[2] == '\\') { // Windows drive letter
 		idx = 3;
 	} else {
-		res = ".\\";
+		res = ".:";
 
 		if (path[0] == ':')
 			idx = 1;
 	}
 
-	while (idx != path.size()) {
-		if (path[idx] == ':')
-			res += '\\';
+	while (idx < path.size()) {
+		if (path[idx] == ':' || path[idx] == '\\')
+			res += g_director->_dirSeparator;
 		else
 			res += path[idx];
 
 		idx++;
 	}
 
-	// And now convert everything to Unix style paths
-	Common::String res1;
-	for (idx = 0; idx < res.size(); idx++)
-		if (res[idx] == '\\')
-			res1 += '/';
-		else
-			res1 += res[idx];
-
-	return res1;
+	return res;
 }
 
 Common::String unixToMacPath(const Common::String &path) {
@@ -280,7 +272,7 @@ Common::String unixToMacPath(const Common::String &path) {
 
 Common::String getPath(Common::String path, Common::String cwd) {
 	const char *s;
-	if ((s = strrchr(path.c_str(), '/'))) {
+	if ((s = strrchr(path.c_str(), g_director->_dirSeparator))) {
 		return Common::String(path.c_str(), s + 1);
 	}
 
@@ -292,12 +284,12 @@ bool testPath(Common::String &path, bool directory) {
 		Common::FSNode d = Common::FSNode(*g_director->getGameDataDir());
 
 		// check for the game data dir
-		if (!path.contains("/") && path.equalsIgnoreCase(d.getName())) {
+		if (!path.contains(g_director->_dirSeparator) && path.equalsIgnoreCase(d.getName())) {
 			path = "";
 			return true;
 		}
 
-		Common::StringTokenizer directory_list(path, "/");
+		Common::StringTokenizer directory_list(path, Common::String(g_director->_dirSeparator));
 
 		if (d.getChild(directory_list.nextToken()).exists()) {
 			// then this part is for the "relative to current directory"
@@ -313,7 +305,7 @@ bool testPath(Common::String &path, bool directory) {
 	}
 
 	Common::File f;
-	if (f.open(path)) {
+	if (f.open(Common::Path(path, g_director->_dirSeparator))) {
 		if (f.size())
 			return true;
 		f.close();
@@ -332,7 +324,7 @@ Common::String pathMakeRelative(Common::String path, bool recursive, bool addext
 
 	debug(2, "pathMakeRelative(): s1 %s -> %s", path.c_str(), initialPath.c_str());
 
-	initialPath = Common::normalizePath(g_director->getCurrentPath() + initialPath, '/');
+	initialPath = Common::normalizePath(g_director->getCurrentPath() + initialPath, g_director->_dirSeparator);
 	Common::String convPath = initialPath;
 
 	debug(2, "pathMakeRelative(): s2 %s", convPath.c_str());
@@ -346,8 +338,8 @@ Common::String pathMakeRelative(Common::String path, bool recursive, bool addext
 	// Now try to search the file
 	bool opened = false;
 
-	while (convPath.contains('/')) {
-		int pos = convPath.find('/');
+	while (convPath.contains(g_director->_dirSeparator)) {
+		int pos = convPath.find(g_director->_dirSeparator);
 		convPath = Common::String(&convPath.c_str()[pos + 1]);
 
 		debug(2, "pathMakeRelative(): s3 try %s", convPath.c_str());
@@ -372,8 +364,8 @@ Common::String pathMakeRelative(Common::String path, bool recursive, bool addext
 			return initialPath;
 
 		// Now try to search the file
-		while (convPath.contains('/')) {
-			int pos = convPath.find('/');
+		while (convPath.contains(g_director->_dirSeparator)) {
+			int pos = convPath.find(g_director->_dirSeparator);
 			convPath = Common::String(&convPath.c_str()[pos + 1]);
 
 			debug(2, "pathMakeRelative(): s5 try %s", convPath.c_str());
@@ -400,7 +392,7 @@ Common::String pathMakeRelative(Common::String path, bool recursive, bool addext
 			Common::String component;
 
 			while (*ptr) {
-				if (*ptr == '/') {
+				if (*ptr == g_director->_dirSeparator) {
 					if (component.equals(".")) {
 						convPath += component;
 					} else {
@@ -408,7 +400,7 @@ Common::String pathMakeRelative(Common::String path, bool recursive, bool addext
 					}
 
 					component.clear();
-					convPath += '/';
+					convPath += g_director->_dirSeparator;
 				} else {
 					component += *ptr;
 				}
@@ -475,8 +467,8 @@ Common::String testExtensions(Common::String component, Common::String initialPa
 }
 
 Common::String getFileName(Common::String path) {
-	while (path.contains('/')) {
-		int pos = path.find('/');
+	while (path.contains(g_director->_dirSeparator)) {
+		int pos = path.find(g_director->_dirSeparator);
 		path = Common::String(&path.c_str()[pos + 1]);
 	}
 	return path;
@@ -522,7 +514,7 @@ Common::String stripMacPath(const char *name) {
 	const char *ptr = name;
 
 	while (ptr <= end) {
-		if (myIsAlnum(*ptr) || myIsFATChar(*ptr) || *ptr == '/') {
+		if (myIsAlnum(*ptr) || myIsFATChar(*ptr) || *ptr == g_director->_dirSeparator) {
 			res += *ptr;
 		}
 		ptr++;
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 94e6f5c549..79dbf8eebf 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -413,20 +413,20 @@ bool Window::setNextMovie(Common::String &movieFilenameRaw) {
 			if (*p >= 0x20 && *p <= 0x7f)
 				cleanedFilename += (char) *p;
 
-		if (resMan.open(movieFilename)) {
+		if (resMan.open(Common::Path(movieFilename, _vm->_dirSeparator))) {
 			fileExists = true;
 			cleanedFilename = movieFilename;
-		} else if (!movieFilename.equals(cleanedFilename) && resMan.open(cleanedFilename)) {
+		} else if (!movieFilename.equals(cleanedFilename) && resMan.open(Common::Path(cleanedFilename, _vm->_dirSeparator))) {
 			fileExists = true;
 		}
 	} else {
 		Common::File file;
 		cleanedFilename = movieFilename + ".MMM";
 
-		if (file.open(movieFilename)) {
+		if (file.open(Common::Path(movieFilename, _vm->_dirSeparator))) {
 			fileExists = true;
 			cleanedFilename = movieFilename;
-		} else if (!movieFilename.equals(cleanedFilename) && file.open(cleanedFilename)) {
+		} else if (!movieFilename.equals(cleanedFilename) && file.open(Common::Path(cleanedFilename, _vm->_dirSeparator))) {
 			fileExists = true;
 		}
 	}
@@ -483,7 +483,7 @@ bool Window::step() {
 		delete _currentMovie;
 		_currentMovie = nullptr;
 
-		Archive *mov = openMainArchive(_currentPath + Common::lastPathComponent(_nextMovie.movie, '/'));
+		Archive *mov = openMainArchive(_currentPath + Common::lastPathComponent(_nextMovie.movie, g_director->_dirSeparator));
 
 		if (!mov) {
 			warning("nextMovie: No movie is loaded");
@@ -589,7 +589,7 @@ Common::String Window::getSharedCastPath() {
 
 	for (uint i = 0; i < namesToTry.size(); i++) {
 		Common::File f;
-		if (f.open(_currentPath + namesToTry[i])) {
+		if (f.open(Common::Path(_currentPath + namesToTry[i], _vm->_dirSeparator))) {
 			f.close();
 			return _currentPath + namesToTry[i];
 		}


Commit: 8501ce8e26d907af2d999092944c677d8335ca06
    https://github.com/scummvm/scummvm/commit/8501ce8e26d907af2d999092944c677d8335ca06
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
COMMON: Convert names to printable in FSDirectory warnings

Unit separator, a control character, is used as a directory separator,
so this is needed now.

Changed paths:
    common/fs.cpp


diff --git a/common/fs.cpp b/common/fs.cpp
index e296ce32aa..4e9e78934d 100644
--- a/common/fs.cpp
+++ b/common/fs.cpp
@@ -240,10 +240,10 @@ const ArchiveMemberPtr FSDirectory::getMember(const Path &path) const {
 	FSNode *node = lookupCache(_fileCache, name);
 
 	if (!node || !node->exists()) {
-		warning("FSDirectory::getMember: '%s' does not exist", name.c_str());
+		warning("FSDirectory::getMember: '%s' does not exist", Common::toPrintable(name).c_str());
 		return ArchiveMemberPtr();
 	} else if (node->isDirectory()) {
-		warning("FSDirectory::getMember: '%s' is a directory", name.c_str());
+		warning("FSDirectory::getMember: '%s' is a directory", Common::toPrintable(name).c_str());
 		return ArchiveMemberPtr();
 	}
 
@@ -260,7 +260,7 @@ SeekableReadStream *FSDirectory::createReadStreamForMember(const Path &path) con
 		return nullptr;
 	SeekableReadStream *stream = node->createReadStream();
 	if (!stream)
-		warning("FSDirectory::createReadStreamForMember: Can't create stream for file '%s'", name.c_str());
+		warning("FSDirectory::createReadStreamForMember: Can't create stream for file '%s'", Common::toPrintable(name).c_str());
 
 	return stream;
 }
@@ -303,12 +303,12 @@ void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const Path& pr
 				// Always warn in this case as it's when there are 2 directories at the same place with different case
 				// That means a problem in user installation as lookups are always done case insensitive
 				warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring sub-directory '%s'",
-				        name.c_str());
+				        Common::toPrintable(name).c_str());
 			} else {
 				if (_subDirCache.contains(lowercaseName)) {
 					if (!_ignoreClashes) {
 						warning("FSDirectory::cacheDirectory: name clash when building subDirCache with subdirectory '%s'",
-						        name.c_str());
+						        Common::toPrintable(name).c_str());
 					}
 				}
 				cacheDirectoryRecursive(*it, depth - 1, _flat ? prefix : lowercaseName + DIR_SEPARATOR);
@@ -318,7 +318,7 @@ void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const Path& pr
 			if (_fileCache.contains(lowercaseName)) {
 				if (!_ignoreClashes) {
 					warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring file '%s'",
-					        name.c_str());
+					        Common::toPrintable(name).c_str());
 				}
 			} else {
 				_fileCache[lowercaseName] = *it;


Commit: 56087578c7b3fa7fd806c48451ad57cde6e7a580
    https://github.com/scummvm/scummvm/commit/56087578c7b3fa7fd806c48451ad57cde6e7a580
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
DIRECTOR: LINGO: Update patcher paths

Changed paths:
    engines/director/lingo/lingo-patcher.cpp


diff --git a/engines/director/lingo/lingo-patcher.cpp b/engines/director/lingo/lingo-patcher.cpp
index 90986354b6..e449962f92 100644
--- a/engines/director/lingo/lingo-patcher.cpp
+++ b/engines/director/lingo/lingo-patcher.cpp
@@ -43,108 +43,108 @@ struct ScriptPatch {
 	const char *replace;
 } const scriptPatches[] = {
 	// Garbage at end of script
-	{"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP/UpForeECall", kScoreScript, 12, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP:UpForeECall", kScoreScript, 12, 0,
 			2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
-	{"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP/UpForeECall", kScoreScript, 12, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP:UpForeECall", kScoreScript, 12, 0,
 			3, "Channels 17 to 18", ""},
-	{"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP/UpForeECall", kScoreScript, 12, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "WARLOCKSHIP:UpForeECall", kScoreScript, 12, 0,
 			4, "Frames 150 to 160", ""},
 
 	// Garbage at end of script
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HE.Aft", kScoreScript, 8, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HE.Aft", kScoreScript, 8, 0,
 			2, "SS Warlock:DATA:WARLOCKSHIP:HangStairsFore", ""},
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HE.Aft", kScoreScript, 8, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HE.Aft", kScoreScript, 8, 0,
 			3, "Channels 4 to 5", ""},
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HE.Aft", kScoreScript, 8, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HE.Aft", kScoreScript, 8, 0,
 			4, "Frames 20 to 20", ""},
 
 	// Garbage at end of script
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/ENG/D10", kScoreScript, 8, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:ENG:D10", kScoreScript, 8, 0,
 			2, "SS Warlock:ENG.Fold:C9", ""},
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/ENG/D10", kScoreScript, 8, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:ENG:D10", kScoreScript, 8, 0,
 			3, "Channels 19 to 20", ""},
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/ENG/D10", kScoreScript, 8, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:ENG:D10", kScoreScript, 8, 0,
 			4, "Frames 165 to 180", ""},
 
 	// Garbage at end of script
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.c2", kScoreScript, 10, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.c2", kScoreScript, 10, 0,
 			2, "Frames 150 to 160", ""},
 
 	// Garbage at end of script
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.ForeECall", kScoreScript, 12, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.ForeECall", kScoreScript, 12, 0,
 			2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.ForeECall", kScoreScript, 12, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.ForeECall", kScoreScript, 12, 0,
 			3, "Channels 17 to 18", ""},
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.ForeECall", kScoreScript, 12, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.ForeECall", kScoreScript, 12, 0,
 			4, "Frames 150 to 160", ""},
 
 	// Garbage at end of script
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.B2", kScoreScript, 9, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.B2", kScoreScript, 9, 0,
 			2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.B2", kScoreScript, 9, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.B2", kScoreScript, 9, 0,
 			3, "Channels 17 to 18", ""},
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/Up.B2", kScoreScript, 9, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:Up.B2", kScoreScript, 9, 0,
 			4, "Frames 150 to 160", ""},
 
 	// Garbage at end of script
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/BELSHAZZAR/STELLA/ORIGIN", kScoreScript, 12, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:BELSHAZZAR:STELLA:ORIGIN", kScoreScript, 12, 0,
 			2, "Frames 1 to 1", ""},
 
 	// Garbage at end of script
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HangHallAft", kScoreScript, 7, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HangHallAft", kScoreScript, 7, 0,
 			2, "SS Warlock:DATA:WARLOCKSHIP:HangStairsFore", ""},
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HangHallAft", kScoreScript, 7, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HangHallAft", kScoreScript, 7, 0,
 			3, "Channels 4 to 5", ""},
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/WARLOCKSHIP/HangHallAft", kScoreScript, 7, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:WARLOCKSHIP:HangHallAft", kScoreScript, 7, 0,
 			4, "Frames 20 to 20", ""},
 
 	// Stray 'then' (obvious copy/paste error)
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/K/KT/OutMarauderKT", kMovieScript, 14, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:K:KT:OutMarauderKT", kMovieScript, 14, 0,
 			23, "set Spacesuit = 0 then", "set Spacesuit = 0"},
 
 	// Missing '&'
-	{"warlock", nullptr, kPlatformMacintosh, "DATA/NAV/Shared Cast", kMovieScript, 510, 0,
+	{"warlock", nullptr, kPlatformMacintosh, "DATA:NAV:Shared Cast", kMovieScript, 510, 0,
 			19, "alert \"Failed Save.\" & return & \"Error message number: \" string ( filer )",
 				"alert \"Failed Save.\" & return & \"Error message number: \" & string ( filer )"},
 
 	// Garbage at end of script
-	{"warlock", "", kPlatformWindows, "WRLCKSHP/UpForeECall", kScoreScript, 12, 0,
+	{"warlock", "", kPlatformWindows, "WRLCKSHP:UpForeECall", kScoreScript, 12, 0,
 			2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
-	{"warlock", "", kPlatformWindows, "WRLCKSHP/UpForeECall", kScoreScript, 12, 0,
+	{"warlock", "", kPlatformWindows, "WRLCKSHP:UpForeECall", kScoreScript, 12, 0,
 			3, "Channels 17 to 18", ""},
-	{"warlock", "", kPlatformWindows, "WRLCKSHP/UpForeECall", kScoreScript, 12, 0,
+	{"warlock", "", kPlatformWindows, "WRLCKSHP:UpForeECall", kScoreScript, 12, 0,
 			4, "Frames 150 to 160", ""},
 
 	// Missing '&'
-	{"warlock", nullptr, kPlatformUnknown, "NAV/Shared Cast", kMovieScript, 510, 0,
+	{"warlock", nullptr, kPlatformUnknown, "NAV:Shared Cast", kMovieScript, 510, 0,
 			23, "alert \"Failed Save.\" & return & \"Error message number: \" string ( filer )",
 				"alert \"Failed Save.\" & return & \"Error message number: \" & string ( filer )"},
 
 
 	// Patching dead loop which was fixed in v2
-	{"lzone", "", kPlatformMacintosh, "DATA/R-A/Ami-00", kScoreScript, 3, 0,
+	{"lzone", "", kPlatformMacintosh, "DATA:R-A:Ami-00", kScoreScript, 3, 0,
 			2, "continue", "go \"OUT\""},
 
 	// Garbage at end of statements
-	{"lzone", "", kPlatformMacintosh, "DATA/R-E/ZD2-LAS", kScoreScript, 7, 0,
+	{"lzone", "", kPlatformMacintosh, "DATA:R-E:ZD2-LAS", kScoreScript, 7, 0,
 			4, "go to the frame 0", "go to the frame"},
-	{"lzone", "", kPlatformMacintosh, "DATA/R-E/zd1-con1", kScoreScript, 27, 0,
+	{"lzone", "", kPlatformMacintosh, "DATA:R-E:zd1-con1", kScoreScript, 27, 0,
 			1, "go to the frame 0", "go to the frame"},
-	{"lzone", "", kPlatformMacintosh, "DATA/R-E/zd1-con1", kScoreScript, 30, 0,
+	{"lzone", "", kPlatformMacintosh, "DATA:R-E:zd1-con1", kScoreScript, 30, 0,
 			4, "go the frame 0", "go to the frame"},
-	{"lzone", "", kPlatformMacintosh, "DATA/R-G/st-c", kScoreScript, 14, 0,
+	{"lzone", "", kPlatformMacintosh, "DATA:R-G:st-c", kScoreScript, 14, 0,
 			1, "go to the frame 0", "go to the frame"},
-	{"lzone", "", kPlatformMacintosh, "DATA/R-G/st-d.mo", kScoreScript, 4, 0,
+	{"lzone", "", kPlatformMacintosh, "DATA:R-G:st-d.mo", kScoreScript, 4, 0,
 			1, "go to the frame 0", "go to the frame"},
-	{"lzone", "", kPlatformMacintosh, "DATA/R-F/ARCH-U.D-1", kScoreScript, 8, 0,
+	{"lzone", "", kPlatformMacintosh, "DATA:R-F:ARCH-U.D-1", kScoreScript, 8, 0,
 			1, "GO \"SPACE\" OF MOVIE \"L-ZONE:DATA:R-G:ST-A2\",\"242,197\"",
 			   "GO \"SPACE\" OF MOVIE \"L-ZONE:DATA:R-G:ST-A2\""},
 
-	{"lingoexpo", "", kPlatformMacintosh, "Lingo Expo/Navigator", kMovieScript, 9, 0,
+	{"lingoexpo", "", kPlatformMacintosh, "Lingo Expo:Navigator", kMovieScript, 9, 0,
 			97, "  append(codeExampleList,\"6,301,302,303,304,305,306\")  - KIOSK SCRIPTS",
 				"  append(codeExampleList,\"6,301,302,303,304,305,306\")"},
 
-	{"jman", "", kPlatformWindows, "mmm/Mars Space Game 05", kMovieScript, 10, 0,
+	{"jman", "", kPlatformWindows, "mmm:Mars Space Game 05", kMovieScript, 10, 0,
 			68, "set DamageParameter = (gProcessorSpeed/2) + 7)", "set DamageParameter = (gProcessorSpeed/2) + 7"},
 
 	{nullptr, nullptr, kPlatformUnknown, nullptr, kNoneScript, 0, 0, 0, nullptr, nullptr}


Commit: 9a22c59b67ce6895477066a289b5b9882d8688f2
    https://github.com/scummvm/scummvm/commit/9a22c59b67ce6895477066a289b5b9882d8688f2
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
WIN32: Fix compilation

Changed paths:
    backends/platform/sdl/win32/win32.cpp


diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp
index f7156f35b7..91676914df 100644
--- a/backends/platform/sdl/win32/win32.cpp
+++ b/backends/platform/sdl/win32/win32.cpp
@@ -370,12 +370,12 @@ int Win32ResourceArchive::listMembers(Common::ArchiveMemberList &list) const {
 
 const Common::ArchiveMemberPtr Win32ResourceArchive::getMember(const Common::Path &path) const {
 	Common::String name = path.toString();
-	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name.toString(), this));
+	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
 }
 
 Common::SeekableReadStream *Win32ResourceArchive::createReadStreamForMember(const Common::Path &path) const {
 	Common::String name = path.toString();
-	TCHAR *tName = Win32::stringToTchar(name.toString());
+	TCHAR *tName = Win32::stringToTchar(name);
 	HRSRC resource = FindResource(NULL, tName, MAKEINTRESOURCE(256));
 	free(tName);
 


Commit: 6020f24661d9769c0810980b3e1392a250291e22
    https://github.com/scummvm/scummvm/commit/6020f24661d9769c0810980b3e1392a250291e22
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
COMMON: Create punycode_encodepath

Changed paths:
    common/punycode.cpp
    common/punycode.h


diff --git a/common/punycode.cpp b/common/punycode.cpp
index 4c5917dec3..7d271a1ed7 100644
--- a/common/punycode.cpp
+++ b/common/punycode.cpp
@@ -59,6 +59,8 @@ namespace Common {
 #define INITIAL_BIAS 72
 #define SMAX 0x7fff
 
+#define SPECIAL_SYMBOLS "/\":*[]+|\\?%<>,;="
+
 static uint32 adapt_bias(uint32 delta, unsigned n_points, int is_first) {
 	uint32 k;
 
@@ -196,7 +198,7 @@ bool punycode_hasprefix(const String src) {
 
 bool punycode_needEncode(const String src) {
 	for (uint si = 0; si < src.size(); si++) {
-		if (src[si] & 0x80 || src[si] < 0x20) {
+		if (src[si] & 0x80 || src[si] < 0x20 || strchr(SPECIAL_SYMBOLS, src[si])) {
 			return true;
 		}
 	}
@@ -304,7 +306,7 @@ String punycode_encodefilename(const String src) {
 			dst += '\x81';
 			dst += '\x79';
 		// Encode special symbols and non-printables
-		} else if (strchr("/\":*[]+|\\?%<>,;=", src[i]) || (byte)src[i] < 0x20) {
+		} else if (strchr(SPECIAL_SYMBOLS, src[i]) || (byte)src[i] < 0x20) {
 			dst += '\x81';
 			dst += (byte)src[i] + '\x80';
 		} else {
@@ -365,4 +367,22 @@ Path punycode_decodepath(const Path &src) {
 	return Path(res, DIR_SEPARATOR);
 }
 
+Path punycode_encodepath(const Path &src) {
+	StringTokenizer tok(src.rawString(), Common::String(DIR_SEPARATOR));
+	String res;
+
+	while (!tok.empty()) {
+		String part = tok.nextToken();
+		if (punycode_needEncode(part))
+			res += punycode_encodefilename(part);
+		else
+			res += part;
+
+		if (!tok.empty())
+			res += DIR_SEPARATOR;
+	}
+
+	return Path(res, DIR_SEPARATOR);
+}
+
 } // end of namespace Common
diff --git a/common/punycode.h b/common/punycode.h
index d713de09ef..3933f9d9a0 100644
--- a/common/punycode.h
+++ b/common/punycode.h
@@ -72,6 +72,11 @@ String punycode_decodefilename(const String src1);
  */
 Path punycode_decodepath(const Path &src);
 
+/**
+ * Convert path to Punycode with '/' as separators
+ */
+Path punycode_encodepath(const Path &src);
+
 bool punycode_hasprefix(const String src);
 
 bool punycode_needEncode(const String src);


Commit: e6c696031f378187e693d0916ded13e5c99ca125
    https://github.com/scummvm/scummvm/commit/e6c696031f378187e693d0916ded13e5c99ca125
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
DIRECTOR: Punycode dump file names

Changed paths:
    engines/director/archive.cpp
    engines/director/cast.cpp
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/resource.cpp
    engines/director/util.cpp
    engines/director/util.h


diff --git a/engines/director/archive.cpp b/engines/director/archive.cpp
index b6783c57a5..beb53ad199 100644
--- a/engines/director/archive.cpp
+++ b/engines/director/archive.cpp
@@ -500,7 +500,7 @@ bool RIFXArchive::openStream(Common::SeekableReadStream *stream, uint32 startOff
 		Common::DumpFile out;
 
 		char buf[256];
-		sprintf(buf, "./dumps/%s-%08x", g_director->getEXEName().c_str(), startOffset);
+		sprintf(buf, "./dumps/%s-%08x", encodePathForDump(g_director->getEXEName()).c_str(), startOffset);
 
 		if (out.open(buf, true)) {
 			out.write(dumpData, sz);
@@ -559,7 +559,7 @@ bool RIFXArchive::openStream(Common::SeekableReadStream *stream, uint32 startOff
 			else
 				prepend = "stream";
 
-			Common::String filename = Common::String::format("./dumps/%s-%s-%d", prepend.c_str(), tag2str(_resources[i]->tag), _resources[i]->index);
+			Common::String filename = Common::String::format("./dumps/%s-%s-%d", encodePathForDump(prepend).c_str(), tag2str(_resources[i]->tag), _resources[i]->index);
 			resStream->read(data, len);
 
 			if (!out.open(filename, true)) {
@@ -716,7 +716,7 @@ bool RIFXArchive::readAfterburnerMap(Common::SeekableReadStreamEndian &stream, u
 		Common::DumpFile out;
 
 		char buf[256];
-		sprintf(buf, "./dumps/%s-%s", g_director->getEXEName().c_str(), "ABMP");
+		sprintf(buf, "./dumps/%s-%s", encodePathForDump(g_director->getEXEName()).c_str(), "ABMP");
 
 		if (out.open(buf, true)) {
 			byte *data = (byte *)malloc(abmpStream->size());
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 080ef37168..f5730580e6 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -1088,7 +1088,7 @@ void Cast::loadScriptText(Common::SeekableReadStreamEndian &stream, uint16 id) {
 
 void Cast::dumpScript(const char *script, ScriptType type, uint16 id) {
 	Common::DumpFile out;
-	Common::String buf = dumpScriptName(_macName.c_str(), type, id, "txt");
+	Common::String buf = dumpScriptName(encodePathForDump(_macName).c_str(), type, id, "txt");
 
 	if (!out.open(buf, true)) {
 		warning("Cast::dumpScript(): Can not open dump file %s", buf.c_str());
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 517a5a7941..2e6cd1a49c 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -1177,7 +1177,7 @@ ScriptContext *LingoCompiler::compileLingoV4(Common::SeekableReadStreamEndian &s
 	bool skipdump = false;
 
 	if (ConfMan.getBool("dump_scripts")) {
-		Common::String buf = dumpScriptName(archName.c_str(), scriptType, castId, "lscr");
+		Common::String buf = dumpScriptName(encodePathForDump(archName).c_str(), scriptType, castId, "lscr");
 
 		if (!out.open(buf, true)) {
 			warning("Lingo::addCodeV4(): Can not open dump file %s", buf.c_str());
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 9ebe005476..7d10575392 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -282,7 +282,7 @@ void Window::loadEXEv3(Common::SeekableReadStream *stream) {
 			byte *buf = (byte *)malloc(mmmSize);
 			stream->read(buf, mmmSize);
 			stream->seek(riffOffset);
-			Common::String fname = Common::String::format("./dumps/%s", mmmFileName.c_str());
+			Common::String fname = Common::String::format("./dumps/%s", encodePathForDump(mmmFileName).c_str());
 
 
 			if (!out.open(fname.c_str(), true)) {
diff --git a/engines/director/util.cpp b/engines/director/util.cpp
index 724a8f2775..9faec568fc 100644
--- a/engines/director/util.cpp
+++ b/engines/director/util.cpp
@@ -23,6 +23,7 @@
 #include "common/file.h"
 #include "common/keyboard.h"
 #include "common/memstream.h"
+#include "common/punycode.h"
 #include "common/tokenizer.h"
 #include "common/zlib.h"
 
@@ -811,4 +812,8 @@ int compareStrings(const Common::String &s1, const Common::String &s2) {
 	return c1 - c2;
 }
 
+Common::String encodePathForDump(const Common::String &path) {
+	return punycode_encodepath(Common::Path(path, g_director->_dirSeparator)).toString();
+}
+
 } // End of namespace Director
diff --git a/engines/director/util.h b/engines/director/util.h
index a67893a035..346f0a8bd0 100644
--- a/engines/director/util.h
+++ b/engines/director/util.h
@@ -91,6 +91,8 @@ int charToNum(Common::u32char_type_t ch);
 Common::u32char_type_t numToChar(int num);
 int compareStrings(const Common::String &s1, const Common::String &s2);
 
+Common::String encodePathForDump(const Common::String &path);
+
 } // End of namespace Director
 
 #endif


Commit: 2eca1126c5f22b2025c6597c3544b9696545a814
    https://github.com/scummvm/scummvm/commit/2eca1126c5f22b2025c6597c3544b9696545a814
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
VIDEO: Use Path type in VideoDecoder functions

Changed paths:
    common/quicktime.cpp
    common/quicktime.h
    video/qt_decoder.cpp
    video/qt_decoder.h
    video/video_decoder.cpp
    video/video_decoder.h


diff --git a/common/quicktime.cpp b/common/quicktime.cpp
index 1c1690bc13..7b84b3aaea 100644
--- a/common/quicktime.cpp
+++ b/common/quicktime.cpp
@@ -59,7 +59,7 @@ QuickTimeParser::~QuickTimeParser() {
 	delete _resFork;
 }
 
-bool QuickTimeParser::parseFile(const String &filename) {
+bool QuickTimeParser::parseFile(const Path &filename) {
 	if (!_resFork->open(filename) || !_resFork->hasDataFork())
 		return false;
 
diff --git a/common/quicktime.h b/common/quicktime.h
index 4d8af4db6f..9d91027043 100644
--- a/common/quicktime.h
+++ b/common/quicktime.h
@@ -33,6 +33,7 @@
 
 #include "common/array.h"
 #include "common/scummsys.h"
+#include "common/path.h"
 #include "common/stream.h"
 #include "common/rational.h"
 #include "common/types.h"
@@ -62,7 +63,7 @@ public:
 	 * Load a QuickTime file
 	 * @param filename	the filename to load
 	 */
-	bool parseFile(const String &filename);
+	bool parseFile(const Path &filename);
 
 	/**
 	 * Load a QuickTime file from a SeekableReadStream
diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp
index 7e6de67c9d..1644dc9f5c 100644
--- a/video/qt_decoder.cpp
+++ b/video/qt_decoder.cpp
@@ -57,7 +57,7 @@ QuickTimeDecoder::~QuickTimeDecoder() {
 	close();
 }
 
-bool QuickTimeDecoder::loadFile(const Common::String &filename) {
+bool QuickTimeDecoder::loadFile(const Common::Path &filename) {
 	if (!Common::QuickTimeParser::parseFile(filename))
 		return false;
 
diff --git a/video/qt_decoder.h b/video/qt_decoder.h
index 1ec8bd876d..3b1e461b84 100644
--- a/video/qt_decoder.h
+++ b/video/qt_decoder.h
@@ -63,7 +63,7 @@ public:
 	QuickTimeDecoder();
 	virtual ~QuickTimeDecoder();
 
-	bool loadFile(const Common::String &filename);
+	bool loadFile(const Common::Path &filename);
 	bool loadStream(Common::SeekableReadStream *stream);
 	void close();
 	uint16 getWidth() const { return _width; }
diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp
index 5bef77450b..1a7219be7e 100644
--- a/video/video_decoder.cpp
+++ b/video/video_decoder.cpp
@@ -82,7 +82,7 @@ void VideoDecoder::close() {
 	_canSetDither = true;
 }
 
-bool VideoDecoder::loadFile(const Common::String &filename) {
+bool VideoDecoder::loadFile(const Common::Path &filename) {
 	Common::File *file = new Common::File();
 
 	if (!file->open(filename)) {
diff --git a/video/video_decoder.h b/video/video_decoder.h
index ec0804ce86..58e895dc62 100644
--- a/video/video_decoder.h
+++ b/video/video_decoder.h
@@ -26,6 +26,7 @@
 #include "audio/mixer.h"
 #include "audio/timestamp.h"	// TODO: Move this to common/ ?
 #include "common/array.h"
+#include "common/path.h"
 #include "common/rational.h"
 #include "common/str.h"
 #include "graphics/pixelformat.h"
@@ -66,7 +67,7 @@ public:
 	 * @param filename	the filename to load
 	 * @return whether loading the file succeeded
 	 */
-	virtual bool loadFile(const Common::String &filename);
+	virtual bool loadFile(const Common::Path &filename);
 
 	/**
 	 * Load a video from a generic read stream. The ownership of the


Commit: cedc5678ac0c40cd39daccffd7c699ab27f597c6
    https://github.com/scummvm/scummvm/commit/cedc5678ac0c40cd39daccffd7c699ab27f597c6
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
DIRECTOR: Fix loading video

Changed paths:
    engines/director/cast.cpp
    engines/director/castmember.cpp


diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index f5730580e6..229bbe50df 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -678,7 +678,7 @@ Common::String Cast::getVideoPath(int castId) {
 		Common::String filename = _castsInfo[castId]->fileName;
 		Common::String directory = _castsInfo[castId]->directory;
 
-		res = directory + "\\" + filename;
+		res = directory + g_director->_dirSeparator + filename;
 	} else {
 		warning("STUB: Cast::getVideoPath(%d): unsupported non-zero MooV block", castId);
 	}
diff --git a/engines/director/castmember.cpp b/engines/director/castmember.cpp
index c323095a3d..1eef937d76 100644
--- a/engines/director/castmember.cpp
+++ b/engines/director/castmember.cpp
@@ -358,7 +358,7 @@ bool DigitalVideoCastMember::loadVideo(Common::String path) {
 	_video = new Video::QuickTimeDecoder();
 
 	debugC(2, kDebugLoading | kDebugImages, "Loading video %s", path.c_str());
-	bool result = _video->loadFile(path);
+	bool result = _video->loadFile(Common::Path(path, g_director->_dirSeparator));
 
 	if (result && g_director->_pixelformat.bytesPerPixel == 1) {
 		// Director supports playing back RGB and paletted video in 256 colour mode.


Commit: 8c4ecf6cc5303e235e4d013d2c2e2e98ef824495
    https://github.com/scummvm/scummvm/commit/8c4ecf6cc5303e235e4d013d2c2e2e98ef824495
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
COMMON: Add Doxygen comments to path.h

Changed paths:
    common/path.h


diff --git a/common/path.h b/common/path.h
index 128fc8ab3b..d1bdafceee 100644
--- a/common/path.h
+++ b/common/path.h
@@ -28,46 +28,131 @@
 
 namespace Common {
 
+/**
+ * @defgroup common_path Path
+ * @ingroup common
+ *
+ * @brief API for working with paths.
+ *
+ * @{
+ */
+
 const char DIR_SEPARATOR = '\x1f'; // unit separator
 
+/**
+ * Simple path class. Allows simple conversion to/from path strings with
+ * arbitrary directory separators, providing a common representation.
+ * 
+ * Internally, this is just a simple wrapper around a String, using
+ * '\x1f' (unit separator) as a directory separator. As this is not
+ * a printable character, it should not appear in file names, unlike
+ * '/', '\', or ':', which are allowed on certain platforms.
+ */
 class Path {
 private:
 	String _str;
 
 public:
+	/** Construct a new empty path. */
 	Path() {}
+
+	/** Construct a copy of the given path. */
 	Path(const Path &path);
+
+	/**
+	 * Construct a new path from the given NULL-terminated C string.
+	 * 
+	 * @param str       A NULL-terminated C string representing a path,
+	 *                  e.g. "foo/bar/baz"
+	 * @param separator The directory separator used in the path string.
+	 *                  Defaults to '/'.
+	 */
 	Path(const char *str, char separator = '/');
+
+	/**
+	 * Construct a new path from the given String.
+	 * 
+	 * @param str       A String representing a path, e.g. "foo/bar/baz"
+	 * @param separator The directory separator used in the path string.
+	 *                  Defaults to '/'.
+	 */
 	Path(const String &str, char separator = '/');
+
+	/** Construct a path consisting of the given character. */
 	Path(char c, char separator = '/');
 
 private:
 	void setString(const char *str, char separator = '/');
 
 public:
+	/**
+	 * Returns the unmodified, internal representation of the path,
+	 * using '\x1f' as a directory separator.
+	 */
 	const String &rawString() const { return _str; }
+
+	/**
+	 * Converts a path to a string using the given directory separator.
+	 * 
+	 * @param separator The character used to separate directory names.
+	 *                  Defaults to '/'.
+	 */
 	String toString(char separator = '/') const;
 
+	/** Check whether this path is identical to path @p x. */
 	bool operator==(const Path &x) const;
+
+	/** Check whether this path is different than path @p x. */
 	bool operator!=(const Path &x) const;
 
+	/** Return if this path is empty */
 	bool empty() const;
 
+	/** Assign a given path to this path. */
 	Path &operator=(const Path &str);
+
+	/** @overload */
 	Path &operator=(const char *str);
+
+	/** @overload */
 	Path &operator=(const String &str);
+
+	/** @overload */
 	Path &operator=(char c);
+
+	/**
+	 * Append the given path to this path. Does not automatically
+	 * add a directory separator.
+	 */
 	Path &operator+=(const Path &str);
+
+	/** @overload */
 	Path &operator+=(const char *str);
+
+	/** @overload */
 	Path &operator+=(const String &str);
+
+	/** @overload */
 	Path &operator+=(char c);
 };
 
+/**
+ * Concatenate paths @p x and @p y. Does not automatically
+ * add a directory separator between them.
+ */
 Path operator+(const Path &x, const Path &y);
+
+/** @overload */
 Path operator+(const Path &x, const String &y);
+
+/** @overload */
 Path operator+(const Path &x, const char *y);
+
+/** @overload */
 Path operator+(const Path &x, char y);
 
+/** @} */
+
 } // End of namespace Common
 
 #endif


Commit: 763d2813a0c5711341d47f3d7d427d5fc874ac30
    https://github.com/scummvm/scummvm/commit/763d2813a0c5711341d47f3d7d427d5fc874ac30
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
COMMON: Replace Path's += with append/join

Changed paths:
    common/file.cpp
    common/macresman.cpp
    common/path.cpp
    common/path.h


diff --git a/common/file.cpp b/common/file.cpp
index 81993179ca..eec0283910 100644
--- a/common/file.cpp
+++ b/common/file.cpp
@@ -50,7 +50,7 @@ bool File::open(const Path &filename, Archive &archive) {
 
 	if ((stream = archive.createReadStreamForMember(filename))) {
 		debug(8, "Opening hashed: %s", filename.toString().c_str());
-	} else if ((stream = archive.createReadStreamForMember(filename + "."))) {
+	} else if ((stream = archive.createReadStreamForMember(filename.append(".")))) {
 		// WORKAROUND: Bug #2548: "SIMON1: Game Detection fails"
 		// sometimes instead of "GAMEPC" we get "GAMEPC." (note trailing dot)
 		debug(8, "Opening hashed: %s.", filename.toString().c_str());
@@ -90,7 +90,7 @@ bool File::open(SeekableReadStream *stream, const String &name) {
 bool File::exists(const Path &filename) {
 	if (SearchMan.hasFile(filename)) {
 		return true;
-	} else if (SearchMan.hasFile(filename + ".")) {
+	} else if (SearchMan.hasFile(filename.append("."))) {
 		// WORKAROUND: Bug #2548: "SIMON1: Game Detection fails"
 		// sometimes instead of "GAMEPC" we get "GAMEPC." (note trailing dot)
 		return true;
diff --git a/common/macresman.cpp b/common/macresman.cpp
index 83dbe66408..8262636d5a 100644
--- a/common/macresman.cpp
+++ b/common/macresman.cpp
@@ -140,7 +140,7 @@ bool MacResManager::open(const Path &fileName, Archive &archive) {
 #endif
 
 	// Prefer standalone files first, starting with raw forks
-	SeekableReadStream *stream = archive.createReadStreamForMember(fileName + ".rsrc");
+	SeekableReadStream *stream = archive.createReadStreamForMember(fileName.append(".rsrc"));
 	if (stream && loadFromRawFork(*stream)) {
 		_baseFileName = fileName;
 		return true;
@@ -156,7 +156,7 @@ bool MacResManager::open(const Path &fileName, Archive &archive) {
 	delete stream;
 
 	// Check .bin for MacBinary next
-	stream = archive.createReadStreamForMember(fileName + ".bin");
+	stream = archive.createReadStreamForMember(fileName.append(".bin"));
 	if (stream && loadFromMacBinary(*stream)) {
 		_baseFileName = fileName;
 		return true;
@@ -191,12 +191,12 @@ bool MacResManager::exists(const Path &fileName) {
 		return true;
 
 	// Try the .rsrc extension
-	if (File::exists(fileName + ".rsrc"))
+	if (File::exists(fileName.append(".rsrc")))
 		return true;
 
 	// Check if we have a MacBinary file
 	File tempFile;
-	if (tempFile.open(fileName + ".bin") && isMacBinary(tempFile))
+	if (tempFile.open(fileName.append(".bin")) && isMacBinary(tempFile))
 		return true;
 
 	// Check if we have an AppleDouble file
diff --git a/common/path.cpp b/common/path.cpp
index 4b138633e5..933fb08e81 100644
--- a/common/path.cpp
+++ b/common/path.cpp
@@ -29,25 +29,11 @@ Path::Path(const Path &path) {
 }
 
 Path::Path(const char *str, char separator) {
-	setString(str, separator);
+	set(str, separator);
 }
 
 Path::Path(const String &str, char separator) {
-	setString(str.c_str(), separator);
-}
-
-Path::Path(char c, char separator) {
-	const char str[] = { c, '\0' };
-	setString(str, separator);
-}
-
-void Path::setString(const char *str, char separator) {
-	for (; *str; str++) {
-		if (*str == separator)
-			_str += DIR_SEPARATOR;
-		else
-			_str += *str;
-	}
+	set(str.c_str(), separator);
 }
 
 String Path::toString(char separator) const {
@@ -79,62 +65,97 @@ Path &Path::operator=(const Path &path) {
 }
 
 Path &Path::operator=(const char *str) {
-	setString(str);
+	set(str);
 	return *this;
 }
 
 Path &Path::operator=(const String &str) {
-	setString(str.c_str());
+	set(str.c_str());
 	return *this;
 }
 
-Path &Path::operator=(char c) {
-	const char str[] = { c, '\0' };
-	setString(str);
-	return *this;
+void Path::set(const char *str, char separator) {
+	_str.clear();
+	appendInPlace(str, separator);
 }
 
-Path &Path::operator+=(const Path &path) {
-	_str += path.rawString();
+Path &Path::appendInPlace(const Path &x) {
+	_str += x.rawString();
 	return *this;
 }
 
-Path &Path::operator+=(const char *str) {
-	_str += Path(str).rawString();
+Path &Path::appendInPlace(const String &str, char separator) {
+	appendInPlace(str.c_str(), separator);
 	return *this;
 }
 
-Path &Path::operator+=(const String &str) {
-	_str += Path(str).rawString();
+Path &Path::appendInPlace(const char *str, char separator) {
+	for (; *str; str++) {
+		if (*str == separator)
+			_str += DIR_SEPARATOR;
+		else
+			_str += *str;
+	}
 	return *this;
 }
 
-Path &Path::operator+=(char c) {
-	_str += Path(c).rawString();
-	return *this;
+Path Path::append(const Path &x) const {
+	Path temp(*this);
+	temp.appendInPlace(x);
+	return temp;
 }
 
-Path operator+(const Path &x, const Path &y) {
-	Path temp(x);
-	temp += y;
-	return temp;
+Path Path::append(const String &str, char separator) const {
+	return append(str.c_str(), separator);
 }
 
-Path operator+(const Path &x, const String &y) {
-	Path temp(x);
-	temp += y;
+Path Path::append(const char *str, char separator) const {
+	Path temp(*this);
+	temp.appendInPlace(str, separator);
 	return temp;
 }
 
-Path operator+(const Path &x, const char *y) {
-	Path temp(x);
-	temp += y;
+Path &Path::joinInPlace(const Path &x) {
+	if (x.empty())
+		return *this;
+
+	if (!_str.empty() && _str.lastChar() != DIR_SEPARATOR && x.rawString().firstChar() != DIR_SEPARATOR)
+		_str += DIR_SEPARATOR;
+
+	_str += x.rawString();
+
+	return *this;
+}
+
+Path &Path::joinInPlace(const String &str, char separator) {
+	return joinInPlace(str.c_str(), separator);
+}
+
+Path &Path::joinInPlace(const char *str, char separator) {
+	if (*str == '\0')
+		return *this;
+
+	if (!_str.empty() && _str.lastChar() != DIR_SEPARATOR && *str != separator)
+		_str += DIR_SEPARATOR;
+
+	appendInPlace(str, separator);
+
+	return *this;
+}
+
+Path Path::join(const Path &x) const {
+	Path temp(*this);
+	temp.joinInPlace(x);
 	return temp;
 }
 
-Path operator+(const Path &x, char y) {
-	Path temp(x);
-	temp += y;
+Path Path::join(const String &str, char separator) const {
+	return join(str.c_str(), separator);
+}
+
+Path Path::join(const char *str, char separator) const {
+	Path temp(*this);
+	temp.joinInPlace(str, DIR_SEPARATOR);
 	return temp;
 }
 
diff --git a/common/path.h b/common/path.h
index d1bdafceee..3dad9e87fb 100644
--- a/common/path.h
+++ b/common/path.h
@@ -78,13 +78,6 @@ public:
 	 */
 	Path(const String &str, char separator = '/');
 
-	/** Construct a path consisting of the given character. */
-	Path(char c, char separator = '/');
-
-private:
-	void setString(const char *str, char separator = '/');
-
-public:
 	/**
 	 * Returns the unmodified, internal representation of the path,
 	 * using '\x1f' as a directory separator.
@@ -117,39 +110,57 @@ public:
 	/** @overload */
 	Path &operator=(const String &str);
 
+	void set(const char *str, char separator = '/');
+
+	/**
+	 * Appends the given path to this path (in-place).
+	 * Does not automatically add a directory separator.
+	 */
+	Path &appendInPlace(const Path &x);
+
+	/** @overload */
+	Path &appendInPlace(const String &str, char separator = '/');
+
 	/** @overload */
-	Path &operator=(char c);
+	Path &appendInPlace(const char *str, char separator = '/');
 
 	/**
-	 * Append the given path to this path. Does not automatically
-	 * add a directory separator.
+	 * Returns this path with the given path appended (out-of-place).
+	 * Does not automatically add a directory separator.
 	 */
-	Path &operator+=(const Path &str);
+	Path append(const Path &x) const;
 
 	/** @overload */
-	Path &operator+=(const char *str);
+	Path append(const String &str, char separator = '/') const;
 
 	/** @overload */
-	Path &operator+=(const String &str);
+	Path append(const char *str, char separator = '/') const;
+
+
+	/**
+	 * Joins the given path to this path (in-place).
+	 * Automatically adds a directory separator.
+	 */
+	Path &joinInPlace(const Path &x);
 
 	/** @overload */
-	Path &operator+=(char c);
-};
+	Path &joinInPlace(const String &str, char separator = '/');
 
-/**
- * Concatenate paths @p x and @p y. Does not automatically
- * add a directory separator between them.
- */
-Path operator+(const Path &x, const Path &y);
+	/** @overload */
+	Path &joinInPlace(const char *str, char separator = '/');
 
-/** @overload */
-Path operator+(const Path &x, const String &y);
+	/**
+	 * Returns this path joined with the given path (out-of-place).
+	 * Automatically adds a directory separator.
+	 */
+	Path join(const Path &x) const;
 
-/** @overload */
-Path operator+(const Path &x, const char *y);
+	/** @overload */
+	Path join(const String &str, char separator = '/') const;
 
-/** @overload */
-Path operator+(const Path &x, char y);
+	/** @overload */
+	Path join(const char *str, char separator = '/') const;
+};
 
 /** @} */
 


Commit: ed41e12fd260ce23f4742eda1490f5adad58d7f1
    https://github.com/scummvm/scummvm/commit/ed41e12fd260ce23f4742eda1490f5adad58d7f1
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
ANDROID: Pass Path to hasFile instead of String

hasFile was changed to take a Path, so converting it to a String and
converting it back didn't make much sense.

Changed paths:
    backends/platform/android/asset-archive.cpp


diff --git a/backends/platform/android/asset-archive.cpp b/backends/platform/android/asset-archive.cpp
index 9a0f602eab..8cc837ba9e 100644
--- a/backends/platform/android/asset-archive.cpp
+++ b/backends/platform/android/asset-archive.cpp
@@ -163,11 +163,10 @@ const Common::ArchiveMemberPtr AndroidAssetArchive::getMember(const Common::Path
 }
 
 Common::SeekableReadStream *AndroidAssetArchive::createReadStreamForMember(const Common::Path &path) const {
-	Common::String name = path.toString();
-	if (!hasFile(name)) {
+	if (!hasFile(path)) {
 		return nullptr;
 	}
-	return new AssetInputStream(_am, name);
+	return new AssetInputStream(_am, path.toString());
 }
 
 #endif


Commit: d2b42b52d1e0f495931dc2b51a7f995be8766d89
    https://github.com/scummvm/scummvm/commit/d2b42b52d1e0f495931dc2b51a7f995be8766d89
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
COMMON: Use Path functions in FSNode constructor

Path has an empty() function and equality operator. No need to convert
to a String first.

Changed paths:
    common/fs.cpp


diff --git a/common/fs.cpp b/common/fs.cpp
index 4e9e78934d..3365dea2dc 100644
--- a/common/fs.cpp
+++ b/common/fs.cpp
@@ -39,12 +39,11 @@ FSNode::FSNode(const Path &p) {
 	assert(g_system);
 	FilesystemFactory *factory = g_system->getFilesystemFactory();
 	AbstractFSNode *tmp = nullptr;
-	String s = p.toString();
 
-	if (s.empty() || s == ".")
+	if (p.empty() || p == Path("."))
 		tmp = factory->makeCurrentDirectoryFileNode();
 	else
-		tmp = factory->makeFileNodePath(s);
+		tmp = factory->makeFileNodePath(p.toString());
 	_realNode = SharedPtr<AbstractFSNode>(tmp);
 }
 


Commit: d6f255cfff14341d4e56c49c7ddc389f198c01b3
    https://github.com/scummvm/scummvm/commit/d6f255cfff14341d4e56c49c7ddc389f198c01b3
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
DIRECTOR: Fix start movie path conversion

Paths containing punycode don't necessarily *start* with punycode.

Changed paths:
    engines/director/director.cpp


diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index ab5b1fea57..6c513de3f0 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -272,8 +272,7 @@ void DirectorEngine::parseOptions() {
 					_options.startMovie.startFrame = atoi(tail.c_str());
 			}
 
-			if (Common::punycode_hasprefix(_options.startMovie.startMovie))
-				_options.startMovie.startMovie = Common::punycode_decodepath(_options.startMovie.startMovie).toString(_dirSeparator);
+			_options.startMovie.startMovie = Common::punycode_decodepath(_options.startMovie.startMovie).toString(_dirSeparator);
 
 			debug(2, "parseOptions(): Movie is: %s, frame is: %d", _options.startMovie.startMovie.c_str(), _options.startMovie.startFrame);
 		} else if (key == "startup") {


Commit: eaee94eab8788b17a58c0efa1094ae128ba78886
    https://github.com/scummvm/scummvm/commit/eaee94eab8788b17a58c0efa1094ae128ba78886
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T10:44:37+02:00

Commit Message:
DIRECTOR: Set dir separator before parsing options

The directory separator is used when parsing the options.

Changed paths:
    engines/director/director.cpp


diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index 6c513de3f0..28b086b341 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -58,6 +58,8 @@ DirectorEngine *g_director;
 DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
 	g_director = this;
 
+	_dirSeparator = ':';
+
 	parseOptions();
 
 	// Setup mixer
@@ -102,7 +104,6 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
 	_playbackPaused = false;
 	_skipFrameAdvance = false;
 	_centerStage = true;
-	_dirSeparator = ':';
 
 	_surface = nullptr;
 }




More information about the Scummvm-git-logs mailing list