[Scummvm-git-logs] scummvm master -> 414d2d6952b2248558b14570299aa7f938f09aa6

spleen1981 noreply at scummvm.org
Mon Aug 17 08:20:16 UTC 2026


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

Summary:
d11c1c1dbe LIBRETRO: fix index out of bound
935378548d LIBRETRO: fix RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE handling per API contract
08077889d5 LIBRETRO: add SAF support and use libretro VFS
f7519c9150 LIBRETRO: BUILD: sync with libretro-common
576d1cf084 LIBRETRO: BUILD: sync libretro-deps
46a14961b3 LIBRETRO: add getDefaultDir
702d2f628a LIBRETRO: reset last browsed path to default if is /
603dc6653e LIBRETRO: add use of RETRO_ENVIRONMENT_GET_VFS_AUTHORIZED_LOCATIONS
75d9049057 LIBRETRO: add use of RETRO_ENVIRONMENT_GET_FILE_BROWSER_START_DIRECTORY
a5e2c0f387 LIBRETRO: BUILD: sync with libretro-common
3aefd831b9 LIBRETRO: add Browsing Mode core setting
d7fb0de22d LIBRETRO: add android storage information
940c6287c0 LIBRETRO: add consistency check for last browsed path
414d2d6952 LIBRETRO: add URI parser for authorized paths labels


Commit: d11c1c1dbe16123c95a842669332a3571bb48fd1
    https://github.com/scummvm/scummvm/commit/d11c1c1dbe16123c95a842669332a3571bb48fd1
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2026-08-17T10:08:09+02:00

Commit Message:
LIBRETRO: fix index out of bound

Changed paths:
    backends/platform/libretro/src/libretro-core.cpp


diff --git a/backends/platform/libretro/src/libretro-core.cpp b/backends/platform/libretro/src/libretro-core.cpp
index 9627e4870e7..e6c13f1350f 100644
--- a/backends/platform/libretro/src/libretro-core.cpp
+++ b/backends/platform/libretro/src/libretro-core.cpp
@@ -660,7 +660,7 @@ uint16 retro_setting_get_audio_samples_buffer_size(void) {
 	for (uint16 v : allowed) {
 		if (pow2 <= v) return v;
 	}
-	return allowed[sizeof(allowed)/sizeof(allowed[0])];
+	return allowed[ARRAYSIZE(allowed) - 1];
 }
 
 void init_command_params(void) {


Commit: 935378548d03322c62d870e8890863c428f94c26
    https://github.com/scummvm/scummvm/commit/935378548d03322c62d870e8890863c428f94c26
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2026-08-17T10:08:45+02:00

Commit Message:
LIBRETRO: fix RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE handling per API contract

Changed paths:
    backends/platform/libretro/src/libretro-core.cpp


diff --git a/backends/platform/libretro/src/libretro-core.cpp b/backends/platform/libretro/src/libretro-core.cpp
index e6c13f1350f..97c9eaa79ab 100644
--- a/backends/platform/libretro/src/libretro-core.cpp
+++ b/backends/platform/libretro/src/libretro-core.cpp
@@ -1145,7 +1145,9 @@ void retro_run(void) {
 
 	/* Setting RA's video or audio driver to null will disable video/audio bits */
 	int audio_video_enable = 0;
-	environ_cb(RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE, &audio_video_enable);
+	if (!environ_cb(RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE, &audio_video_enable))
+		/* If this flag is not supported, the core assumes that the frontend will not skip any steps, as per API contract */
+		audio_video_enable = RETRO_AV_ENABLE_VIDEO | RETRO_AV_ENABLE_AUDIO;
 
 	if (g_system) {
 		/* Switch to ScummVM thread */


Commit: 08077889d5f0feb6b6fa2e4e2bf5767548cc5a9e
    https://github.com/scummvm/scummvm/commit/08077889d5f0feb6b6fa2e4e2bf5767548cc5a9e
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2026-08-17T10:09:28+02:00

Commit Message:
LIBRETRO: add SAF support and use libretro VFS

Changed paths:
    backends/platform/libretro/dependencies.mk
    backends/platform/libretro/include/libretro-fs.h
    backends/platform/libretro/jni/Android.mk
    backends/platform/libretro/src/libretro-core.cpp
    backends/platform/libretro/src/libretro-fs.cpp


diff --git a/backends/platform/libretro/dependencies.mk b/backends/platform/libretro/dependencies.mk
index 715f8f333f8..ea62246d8b7 100644
--- a/backends/platform/libretro/dependencies.mk
+++ b/backends/platform/libretro/dependencies.mk
@@ -46,6 +46,10 @@ OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/file/file_path_io.o \
 	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/streams/file_stream.o \
 	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/features/features_cpu.o
 
+ifeq ($(USE_LIBRETRO_SAF),1)
+OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/vfs/vfs_implementation_saf.o
+endif
+
 
 ifeq ($(USE_LIBCO), 1)
 OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/libco/libco.o
diff --git a/backends/platform/libretro/include/libretro-fs.h b/backends/platform/libretro/include/libretro-fs.h
index 7541d540ee8..65eed0a1849 100644
--- a/backends/platform/libretro/include/libretro-fs.h
+++ b/backends/platform/libretro/include/libretro-fs.h
@@ -61,7 +61,7 @@ public:
 	LibRetroFilesystemNode(const Common::String &path);
 
 	virtual bool exists() const {
-		return access(_path.c_str(), F_OK) == 0;
+		return _isValid;
 	}
 	virtual Common::U32String getDisplayName() const {
 		return _displayName;
diff --git a/backends/platform/libretro/jni/Android.mk b/backends/platform/libretro/jni/Android.mk
index 5cb6ab7f035..0c2ef19d2d1 100644
--- a/backends/platform/libretro/jni/Android.mk
+++ b/backends/platform/libretro/jni/Android.mk
@@ -3,6 +3,7 @@ ROOT_PATH   := $(LOCAL_PATH)/..
 TARGET_NAME := scummvm
 HAVE_OPENGLES2 := 1
 USE_IMGUI := 0
+USE_LIBRETRO_SAF := 1
 
 # Reset flags not reset to Makefile.common
 DEFINES   :=
@@ -38,6 +39,11 @@ LOCAL_SRC_FILES       := $(DETECT_OBJS:%.o=$(SCUMMVM_PATH)/%.cpp)  $(OBJS_DEPS:%
 LOCAL_C_INCLUDES      := $(subst -I,,$(INCLUDES))
 LOCAL_CPPFLAGS        := $(COREFLAGS) -std=c++11
 LOCAL_CFLAGS          := $(COREFLAGS)
+ifeq ($(USE_LIBRETRO_SAF),1)
+LOCAL_CFLAGS          += -DANDROID -DHAVE_SAF -DLIBRETRO_FS_DEBUG
+LOCAL_CPPFLAGS        += -DANDROID -DHAVE_SAF -DLIBRETRO_FS_DEBUG
+endif
+
 LOCAL_LDFLAGS         := -Wl,-version-script=$(ROOT_PATH)/link.T
 LOCAL_LDLIBS          := -lz -llog
 LOCAL_CPP_FEATURES    := rtti
diff --git a/backends/platform/libretro/src/libretro-core.cpp b/backends/platform/libretro/src/libretro-core.cpp
index 97c9eaa79ab..1367a8d91c3 100644
--- a/backends/platform/libretro/src/libretro-core.cpp
+++ b/backends/platform/libretro/src/libretro-core.cpp
@@ -24,6 +24,8 @@
 #include "common/fs.h"
 #include "common/error.h"
 #include "streams/file_stream.h"
+#include <file/file_path.h>
+#include <retro_dirent.h>
 #include "graphics/surface.h"
 #ifdef _WIN32
 #include <direct.h>
@@ -794,6 +796,7 @@ void retro_set_input_state(retro_input_state_t cb) {
 
 void retro_set_environment(retro_environment_t cb) {
 	environ_cb = cb;
+
 	bool tmp = true;
 	bool has_categories;
 	environ_cb(RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME, &tmp);
@@ -922,6 +925,18 @@ void retro_init(void) {
 	else
 		retro_log_cb = NULL;
 
+	struct retro_vfs_interface_info vfs_iface;
+	vfs_iface.required_interface_version = STAT64_REQUIRED_VFS_VERSION;
+	vfs_iface.iface = nullptr;
+
+	bool vfs_ok = environ_cb(RETRO_ENVIRONMENT_GET_VFS_INTERFACE, &vfs_iface);
+
+	if (vfs_ok) {
+		filestream_vfs_init(&vfs_iface);
+		path_vfs_init(&vfs_iface);
+		dirent_vfs_init(&vfs_iface);
+	}
+
 	if (retro_log_cb)
 		retro_log_cb(RETRO_LOG_DEBUG, "ScummVM core version: %s\n", __GIT_VERSION);
 
diff --git a/backends/platform/libretro/src/libretro-fs.cpp b/backends/platform/libretro/src/libretro-fs.cpp
index 1934c21995f..8a392c7e6d2 100644
--- a/backends/platform/libretro/src/libretro-fs.cpp
+++ b/backends/platform/libretro/src/libretro-fs.cpp
@@ -27,31 +27,271 @@
 #define FORBIDDEN_SYMBOL_EXCEPTION_getenv
 #define FORBIDDEN_SYMBOL_EXCEPTION_strcat
 #define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
+#define FORBIDDEN_SYMBOL_EXCEPTION_strstr
 #define FORBIDDEN_SYMBOL_EXCEPTION_exit // Needed for IRIX's unistd.h
 
+#include <libretro.h>
 #include <file/file_path.h>
 #include <retro_dirent.h>
-#include <retro_stat.h>
+#include <streams/file_stream.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include "backends/platform/libretro/include/libretro-fs.h"
-#include "backends/fs/stdiostream.h"
 #include "common/algorithm.h"
+#include "common/stream.h"
+
+static bool libretroFsHasUriScheme(const Common::String &path) {
+	return strstr(path.c_str(), "://") != nullptr;
+}
+
+static Common::String libretroFsUriDisplayName(const Common::String &path) {
+	Common::String trimmed(path);
+
+	while (trimmed.size() > 1 && trimmed.lastChar() == '/')
+		trimmed.erase(trimmed.size() - 1);
+
+	Common::String name = Common::lastPathComponent(trimmed, '/');
+	return name.empty() ? trimmed : name;
+}
+
+static int libretroFsWhenceToVfs(int whence) {
+	switch (whence) {
+	case SEEK_SET:
+		return RETRO_VFS_SEEK_POSITION_START;
+	case SEEK_CUR:
+		return RETRO_VFS_SEEK_POSITION_CURRENT;
+	case SEEK_END:
+		return RETRO_VFS_SEEK_POSITION_END;
+	default:
+		return whence;
+	}
+}
+
+class LibRetroFileReadStream final : public Common::SeekableReadStream {
+public:
+	explicit LibRetroFileReadStream(RFILE *file)
+		: _file(file), _size(file ? filestream_get_size(file) : -1),
+		  _eos(false), _err(false) {
+	}
+
+	~LibRetroFileReadStream() override {
+		close();
+	}
+
+	uint32 read(void *dataPtr, uint32 dataSize) override {
+		if (!_file || !dataPtr) {
+			_err = true;
+			return 0;
+		}
+
+		if (dataSize == 0)
+			return 0;
+
+		int64_t ret = filestream_read(_file, dataPtr, dataSize);
+
+		if (ret < 0) {
+			_err = true;
+			return 0;
+		}
+
+		// Emulate fread()/feof() behaviour closely enough for ScummVM:
+		// EOF becomes observable after a read cannot satisfy the requested size.
+		if ((uint32)ret < dataSize)
+			_eos = true;
+
+		return (uint32)ret;
+	}
+
+	bool eos() const override {
+		return _eos;
+	}
+
+	bool err() const override {
+		return _err;
+	}
+
+	void clearErr() override {
+		_eos = false;
+		_err = false;
+	}
+
+	int64 pos() const override {
+		if (!_file)
+			return -1;
+
+		int64_t ret = filestream_tell(_file);
+		return ret < 0 ? -1 : ret;
+	}
+
+	int64 size() const override {
+		if (!_file)
+			return -1;
+
+		return _size >= 0 ? _size : filestream_get_size(_file);
+	}
+
+	bool seek(int64 offs, int whence = SEEK_SET) override {
+		if (!_file) {
+			_err = true;
+			return false;
+		}
+
+		int64_t ret = filestream_seek(_file, offs, libretroFsWhenceToVfs(whence));
+
+		if (ret < 0) {
+			_err = true;
+			return false;
+		}
+
+		// ScummVM's stream contract says a successful seek clears EOF.
+		_eos = false;
+		return true;
+	}
+
+private:
+	void close() {
+		if (_file) {
+			filestream_close(_file);
+			_file = nullptr;
+		}
+	}
+
+	RFILE *_file;
+	int64 _size;
+	bool _eos;
+	bool _err;
+};
+
+class LibRetroFileWriteStream final : public Common::SeekableWriteStream {
+public:
+	explicit LibRetroFileWriteStream(RFILE *file) : _file(file), _err(false) {
+	}
+
+	~LibRetroFileWriteStream() override {
+		close();
+	}
+
+	uint32 write(const void *dataPtr, uint32 dataSize) override {
+		if (!_file || !dataPtr) {
+			_err = true;
+			return 0;
+		}
+
+		if (dataSize == 0)
+			return 0;
+
+		int64_t ret = filestream_write(_file, dataPtr, dataSize);
+
+		if (ret < 0) {
+			_err = true;
+			return 0;
+		}
+
+		if ((uint32)ret < dataSize)
+			_err = true;
+
+		return (uint32)ret;
+	}
+
+	bool flush() override {
+		if (!_file) {
+			_err = true;
+			return false;
+		}
+
+		if (filestream_flush(_file) != 0) {
+			_err = true;
+			return false;
+		}
+
+		return true;
+	}
+
+	bool err() const override {
+		return _err;
+	}
+
+	void clearErr() override {
+		_err = false;
+	}
+
+	void finalize() override {
+		flush();
+	}
+
+	int64 pos() const override {
+		if (!_file)
+			return -1;
+
+		int64_t ret = filestream_tell(_file);
+		return ret < 0 ? -1 : ret;
+	}
+
+	int64 size() const override {
+		if (!_file)
+			return -1;
+
+		return filestream_get_size(_file);
+	}
+
+	bool seek(int64 offs, int whence = SEEK_SET) override {
+		if (!_file) {
+			_err = true;
+			return false;
+		}
+
+		if (filestream_seek(_file, offs, libretroFsWhenceToVfs(whence)) < 0) {
+			_err = true;
+			return false;
+		}
+
+		return true;
+	}
+
+private:
+	void close() {
+		if (_file) {
+			flush();
+			filestream_close(_file);
+			_file = nullptr;
+		}
+	}
+
+	RFILE *_file;
+	bool _err;
+};
 
 void LibRetroFilesystemNode::setFlags() {
 	const char *fspath = _path.c_str();
 
+	// Keep all filesystem state queries on libretro-common VFS.
+	// This is important on Android/SAF and also keeps POSIX paths consistent
+	// with the same VFS path used later by filestream_open().
 	_isValid = path_is_valid(fspath);
 	_isDirectory = path_is_directory(fspath);
-	_isReadable = access(fspath, R_OK) == 0;
-	_isWritable = access(_path.c_str(), W_OK) == 0;
+
+	// libretro-common exposes stat-style validity/directory queries here, but
+	// no portable readability/writability probes. Treat valid paths as readable
+	// for ScummVM's FSNode purposes and let createReadStream()/createWriteStream()
+	// be the definitive open check.
+	_isReadable = _isValid;
+	_isWritable = _isValid;
 }
 
 LibRetroFilesystemNode::LibRetroFilesystemNode(const Common::String &p) {
 	assert(p.size() > 0);
 
+	if (libretroFsHasUriScheme(p)) {
+		_path = p;
+		_displayName = libretroFsUriDisplayName(_path);
+		setFlags();
+		return;
+	}
+
 	// Expand "~/" to the value of the HOME env variable
 	if (p.hasPrefix("~/") || p.hasPrefix("~\\")) {
 		Common::String homeDir = getHomeDir();
@@ -72,7 +312,6 @@ LibRetroFilesystemNode::LibRetroFilesystemNode(const Common::String &p) {
 	// Normalize the path (that is, remove unneeded slashes etc.)
 	_path = Common::normalizePath(Common::String(portable_path), '/');
 	_displayName = Common::lastPathComponent(_path, '/');
-
 	setFlags();
 }
 
@@ -123,7 +362,6 @@ bool LibRetroFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode,
 
 		entry._isValid = true;
 		entry._isDirectory = retro_dirent_is_dir(dirp, entry._path.c_str());
-
 		// Skip files that are invalid for some reason (e.g. because we couldn't
 		// properly stat them).
 		if (!entry._isValid)
@@ -144,6 +382,50 @@ AbstractFSNode *LibRetroFilesystemNode::getParent() const {
 	if (_path == "/")
 		return 0; // The filesystem root has no parent
 
+	Common::String parentPath(_path);
+
+	if (libretroFsHasUriScheme(parentPath)) {
+		const char *pathStr = parentPath.c_str();
+		const char *scheme = strstr(pathStr, "://");
+		const uint schemeRootLen = scheme ? (uint)(scheme - pathStr) + 3 : 0;
+
+		// For hierarchical URI paths, keep the authority root intact.
+		// Example:
+		//   smb://server/share/game -> smb://server/share/
+		//   smb://server/share/     -> smb://server/
+		//   smb://server/           -> /
+		uint uriRootLen = schemeRootLen;
+		if (schemeRootLen > 0) {
+			const char *authorityEnd = strchr(pathStr + schemeRootLen, '/');
+			if (authorityEnd)
+				uriRootLen = (uint)(authorityEnd - pathStr) + 1;
+			else
+				uriRootLen = parentPath.size();
+		}
+
+		while (parentPath.size() > uriRootLen && parentPath.lastChar() == '/')
+			parentPath.erase(parentPath.size() - 1);
+
+		if (parentPath.size() <= uriRootLen) {
+			return makeNode("/");
+		}
+
+		size_t pos = parentPath.findLastOf('/');
+		if (pos == Common::String::npos || pos + 1 <= uriRootLen)
+			parentPath = parentPath.substr(0, uriRootLen);
+		else
+			parentPath = parentPath.substr(0, pos + 1);
+
+		AbstractFSNode *parent = makeNode(parentPath);
+
+		if (parent && parent->isDirectory() == false) {
+			delete parent;
+			return 0;
+		}
+
+		return parent;
+	}
+
 	const char *start = _path.c_str();
 	const char *end = start + _path.size();
 
@@ -156,20 +438,34 @@ AbstractFSNode *LibRetroFilesystemNode::getParent() const {
 		return 0;
 	}
 
-	AbstractFSNode *parent = makeNode(Common::String(start, end));
+	Common::String posixParentPath(start, end);
 
-	if (parent->isDirectory() == false)
+	AbstractFSNode *parent = makeNode(posixParentPath);
+
+	if (parent->isDirectory() == false) {
+		delete parent;
 		return 0;
+	}
 
 	return parent;
 }
 
 Common::SeekableReadStream *LibRetroFilesystemNode::createReadStream() {
-	return StdioStream::makeFromPath(getPath(), StdioStream::WriteMode_Read);
+	RFILE *file = filestream_open(getPath().c_str(), RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
+
+	if (!file)
+		return nullptr;
+	return new LibRetroFileReadStream(file);
 }
 
 Common::SeekableWriteStream *LibRetroFilesystemNode::createWriteStream(bool atomic) {
-	return StdioStream::makeFromPath(getPath(), atomic ? StdioStream::WriteMode_WriteAtomic : StdioStream::WriteMode_Write);
+	(void)atomic;
+	RFILE *file = filestream_open(getPath().c_str(), RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE);
+
+	if (!file)
+		return nullptr;
+
+	return new LibRetroFileWriteStream(file);
 }
 
 bool LibRetroFilesystemNode::createDirectory() {


Commit: f7519c91508f4d401b085c9ecb6f32898efaf58c
    https://github.com/scummvm/scummvm/commit/f7519c91508f4d401b085c9ecb6f32898efaf58c
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2026-08-17T10:09:57+02:00

Commit Message:
LIBRETRO: BUILD: sync with libretro-common

Changed paths:
    backends/platform/libretro/dependencies.mk


diff --git a/backends/platform/libretro/dependencies.mk b/backends/platform/libretro/dependencies.mk
index ea62246d8b7..1f90b7cbb39 100644
--- a/backends/platform/libretro/dependencies.mk
+++ b/backends/platform/libretro/dependencies.mk
@@ -11,7 +11,7 @@ DEPS_COMMIT_libretro-deps   := 7e6e34f0319f4c7448d72f0e949e76265ccf55a1
 
 DEPS_FOLDER_libretro-common := libretro-common
 DEPS_URL_libretro-common    := https://github.com/libretro/libretro-common
-DEPS_COMMIT_libretro-common := 70ed90c42ddea828f53dd1b984c6443ddb39dbd6
+DEPS_COMMIT_libretro-common := 692124dbd8a0b2f5526b48f3bc2026421754e3c5
 
 submodule_test  = $(if $(shell result=$$($(SCRIPTS_PATH)/configure_submodules.sh $(DEPS_URL_$(1)) $(DEPS_COMMIT_$(1)) $(DEPS_PATH) $(DEBUG_ALLOW_DIRTY_SUBMODULES) $(DEPS_FOLDER_$(1))) ; { [ -z $$result ] || [ ! $$result = 0 ] ; } && printf error),$(1))
 $(info Configuring submodules...)


Commit: 576d1cf08474f8d01493debed3121e20e9d8abf2
    https://github.com/scummvm/scummvm/commit/576d1cf08474f8d01493debed3121e20e9d8abf2
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2026-08-17T10:10:24+02:00

Commit Message:
LIBRETRO: BUILD: sync libretro-deps

Changed paths:
    backends/platform/libretro/dependencies.mk


diff --git a/backends/platform/libretro/dependencies.mk b/backends/platform/libretro/dependencies.mk
index 1f90b7cbb39..4ac9f221e7d 100644
--- a/backends/platform/libretro/dependencies.mk
+++ b/backends/platform/libretro/dependencies.mk
@@ -7,7 +7,7 @@ DEPS_SUBMODULES             := libretro-deps libretro-common
 
 DEPS_FOLDER_libretro-deps   := libretro-deps
 DEPS_URL_libretro-deps      := https://github.com/libretro/libretro-deps
-DEPS_COMMIT_libretro-deps   := 7e6e34f0319f4c7448d72f0e949e76265ccf55a1
+DEPS_COMMIT_libretro-deps   := bab7d258c451c0e7cba4b6a79f1b062c13efff38
 
 DEPS_FOLDER_libretro-common := libretro-common
 DEPS_URL_libretro-common    := https://github.com/libretro/libretro-common
@@ -214,16 +214,16 @@ this_lib_header := zlib.h
 this_lib_flags := -lz
 include $(ROOT_PATH)/sharedlib_test.mk
 ifneq ($(this_lib_available), yes)
+INCLUDES += -I$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz
 OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/deflate.o \
 	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/gzlib.o \
 	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/uncompr.o \
 	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/zutil.o \
 	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/inffast.o \
 	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/gzread.o \
-	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/crc32.o \
+	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/libz-crc32.o \
 	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/gzwrite.o \
 	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/inflate.o \
-	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/infback.o \
 	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/inftrees.o \
 	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/trees.o \
 	$(DEPS_PATH)/$(DEPS_FOLDER_libretro-deps)/libz/gzclose.o \


Commit: 46a14961b3d4599d8795536fe9e630882983c3ca
    https://github.com/scummvm/scummvm/commit/46a14961b3d4599d8795536fe9e630882983c3ca
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2026-08-17T10:10:48+02:00

Commit Message:
LIBRETRO: add getDefaultDir

Changed paths:
    backends/platform/libretro/include/libretro-fs.h
    backends/platform/libretro/src/libretro-fs-factory.cpp
    backends/platform/libretro/src/libretro-fs.cpp
    backends/platform/libretro/src/libretro-os-utils.cpp


diff --git a/backends/platform/libretro/include/libretro-fs.h b/backends/platform/libretro/include/libretro-fs.h
index 65eed0a1849..1dea0fd99af 100644
--- a/backends/platform/libretro/include/libretro-fs.h
+++ b/backends/platform/libretro/include/libretro-fs.h
@@ -91,6 +91,7 @@ public:
 	virtual bool createDirectory();
 
 	static Common::String getHomeDir(void);
+	static Common::String getDefaultDir(void);
 private:
 	/**
 	 * Tests and sets the _isValid and _isDirectory flags, using the stat() function.
diff --git a/backends/platform/libretro/src/libretro-fs-factory.cpp b/backends/platform/libretro/src/libretro-fs-factory.cpp
index 02ee0e7a80c..772b1c5e625 100644
--- a/backends/platform/libretro/src/libretro-fs-factory.cpp
+++ b/backends/platform/libretro/src/libretro-fs-factory.cpp
@@ -39,11 +39,7 @@ AbstractFSNode *LibRetroFilesystemFactory::makeCurrentDirectoryFileNode() const
 #ifdef PLAYSTATION3
 	return new LibRetroFilesystemNode("/");
 #else
-	char *cwd = getcwd(NULL, 0);
-	AbstractFSNode *node = cwd ? new LibRetroFilesystemNode(Common::String(cwd)) : NULL;
-	if (cwd)
-		free(cwd);
-	return node;
+	return new LibRetroFilesystemNode(LibRetroFilesystemNode::getDefaultDir());
 #endif
 }
 
diff --git a/backends/platform/libretro/src/libretro-fs.cpp b/backends/platform/libretro/src/libretro-fs.cpp
index 8a392c7e6d2..08dd4ef86d8 100644
--- a/backends/platform/libretro/src/libretro-fs.cpp
+++ b/backends/platform/libretro/src/libretro-fs.cpp
@@ -41,6 +41,7 @@
 #include <string.h>
 
 #include "backends/platform/libretro/include/libretro-fs.h"
+#include "backends/platform/libretro/include/libretro-core.h"
 #include "common/algorithm.h"
 #include "common/stream.h"
 
@@ -557,3 +558,26 @@ Common::String LibRetroFilesystemNode::getHomeDir(void) {
 
 	return path;
 }
+
+Common::String LibRetroFilesystemNode::getDefaultDir(void) {
+	Common::String homeDir(getHomeDir());
+
+	if (!homeDir.empty() && LibRetroFilesystemNode(homeDir).isDirectory())
+		return homeDir;
+
+	const char *systemDir = retro_get_system_dir();
+	if (systemDir && *systemDir) {
+		Common::String path(systemDir);
+		if (LibRetroFilesystemNode(path).isDirectory())
+			return path;
+	}
+
+	const char *saveDir = retro_get_save_dir();
+	if (saveDir && *saveDir) {
+		Common::String path(saveDir);
+		if (LibRetroFilesystemNode(path).isDirectory())
+			return path;
+	}
+
+	return Common::String("/");
+}
diff --git a/backends/platform/libretro/src/libretro-os-utils.cpp b/backends/platform/libretro/src/libretro-os-utils.cpp
index 4ff64a9d2c7..644df8cae20 100644
--- a/backends/platform/libretro/src/libretro-os-utils.cpp
+++ b/backends/platform/libretro/src/libretro-os-utils.cpp
@@ -190,7 +190,7 @@ void OSystem_libretro::setLibretroDir(const char *path, Common::String &var) {
 
 void OSystem_libretro::applyBackendSettings() {
 	/* ScummVM paths checks at startup and on settings applied */
-	Common::String s_homeDir(LibRetroFilesystemNode::getHomeDir());
+	Common::String s_homeDir(LibRetroFilesystemNode::getDefaultDir());
 	Common::String s_themeDir(s_systemDir + "/" + SCUMMVM_SYSTEM_SUBDIR + "/" + SCUMMVM_THEME_SUBDIR);
 	Common::String s_extraDir(s_systemDir + "/" + SCUMMVM_SYSTEM_SUBDIR + "/" + SCUMMVM_EXTRA_SUBDIR);
 	Common::String s_soundfontPath(s_extraDir + "/" + DEFAULT_SOUNDFONT_FILENAME);
@@ -201,8 +201,6 @@ void OSystem_libretro::applyBackendSettings() {
 		s_extraDir.clear();
 	if (! LibRetroFilesystemNode(s_soundfontPath).exists())
 		s_soundfontPath.clear();
-	if (s_homeDir.empty() || ! LibRetroFilesystemNode(s_homeDir).isDirectory())
-		s_homeDir = s_systemDir;
 
 	//Register default paths
 	if (! s_homeDir.empty()) {


Commit: 702d2f628a6cd08cede5797f4de1c8372ddc7612
    https://github.com/scummvm/scummvm/commit/702d2f628a6cd08cede5797f4de1c8372ddc7612
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2026-08-17T10:11:09+02:00

Commit Message:
LIBRETRO: reset last browsed path to default if is /

Changed paths:
    backends/platform/libretro/src/libretro-os-utils.cpp


diff --git a/backends/platform/libretro/src/libretro-os-utils.cpp b/backends/platform/libretro/src/libretro-os-utils.cpp
index 644df8cae20..e1e10381e99 100644
--- a/backends/platform/libretro/src/libretro-os-utils.cpp
+++ b/backends/platform/libretro/src/libretro-os-utils.cpp
@@ -170,8 +170,11 @@ bool OSystem_libretro::checkPathSetting(const char *setting, Common::String cons
 	Common::String setPath;
 	if (ConfMan.hasKey(setting))
 		setPath = Common::Path::fromConfig(ConfMan.get(setting)).toString();
-	if (setPath.empty() || !(isDirectory ? LibRetroFilesystemNode(setPath).isDirectory() : LibRetroFilesystemNode(setPath).exists()))
+	if (!strcmp(setting, "browser_lastpath") && setPath == "/" && !defaultPath.empty() && defaultPath != "/")
 		ConfMan.removeKey(setting, Common::ConfigManager::kApplicationDomain);
+	else if (setPath.empty() || !(isDirectory ? LibRetroFilesystemNode(setPath).isDirectory() : LibRetroFilesystemNode(setPath).exists()))
+		ConfMan.removeKey(setting, Common::ConfigManager::kApplicationDomain);
+
 	if (! ConfMan.hasKey(setting))
 		if (defaultPath.empty())
 			return false;


Commit: 603dc6653e85ae566d8c6535b01b06e3b4f36d0c
    https://github.com/scummvm/scummvm/commit/603dc6653e85ae566d8c6535b01b06e3b4f36d0c
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2026-08-17T10:11:26+02:00

Commit Message:
LIBRETRO: add use of RETRO_ENVIRONMENT_GET_VFS_AUTHORIZED_LOCATIONS

Changed paths:
    backends/platform/libretro/include/libretro-fs.h
    backends/platform/libretro/src/libretro-core.cpp
    backends/platform/libretro/src/libretro-fs-factory.cpp
    backends/platform/libretro/src/libretro-fs.cpp


diff --git a/backends/platform/libretro/include/libretro-fs.h b/backends/platform/libretro/include/libretro-fs.h
index 1dea0fd99af..34fba406196 100644
--- a/backends/platform/libretro/include/libretro-fs.h
+++ b/backends/platform/libretro/include/libretro-fs.h
@@ -92,6 +92,10 @@ public:
 
 	static Common::String getHomeDir(void);
 	static Common::String getDefaultDir(void);
+	static Common::String getAuthorizedRootPath(void);
+	static void clearAuthorizedLocations(void);
+	static void addAuthorizedLocation(const Common::String &path, const Common::String &label);
+	static bool hasAuthorizedLocations(void);
 private:
 	/**
 	 * Tests and sets the _isValid and _isDirectory flags, using the stat() function.
diff --git a/backends/platform/libretro/src/libretro-core.cpp b/backends/platform/libretro/src/libretro-core.cpp
index 1367a8d91c3..f5c5d0bccdf 100644
--- a/backends/platform/libretro/src/libretro-core.cpp
+++ b/backends/platform/libretro/src/libretro-core.cpp
@@ -56,8 +56,25 @@
 #include "backends/platform/libretro/include/libretro-threads.h"
 #include "backends/platform/libretro/include/libretro-core-options.h"
 #include "backends/platform/libretro/include/libretro-os.h"
+#include "backends/platform/libretro/include/libretro-fs.h"
 #include "backends/platform/libretro/include/libretro-mapper.h"
 
+#ifndef RETRO_ENVIRONMENT_GET_VFS_AUTHORIZED_LOCATIONS
+#define RETRO_ENVIRONMENT_GET_VFS_AUTHORIZED_LOCATIONS (93 | RETRO_ENVIRONMENT_EXPERIMENTAL)
+
+struct retro_vfs_authorized_location {
+	const char *path;
+	const char *label;
+	unsigned flags;
+};
+
+struct retro_vfs_authorized_locations {
+	const struct retro_vfs_authorized_location *locations;
+	size_t count;
+};
+#endif
+
+
 static struct retro_game_info game_buf;
 static struct retro_game_info *game_buf_ptr;
 
@@ -937,6 +954,26 @@ void retro_init(void) {
 		dirent_vfs_init(&vfs_iface);
 	}
 
+	LibRetroFilesystemNode::clearAuthorizedLocations();
+
+	{
+		struct retro_vfs_authorized_locations locations;
+		memset(&locations, 0, sizeof(locations));
+
+		if (environ_cb && environ_cb(RETRO_ENVIRONMENT_GET_VFS_AUTHORIZED_LOCATIONS, &locations) &&
+				locations.locations) {
+			for (size_t i = 0; i < locations.count; ++i) {
+				const char *path = locations.locations[i].path;
+				const char *label = locations.locations[i].label;
+
+				if (path && *path)
+					LibRetroFilesystemNode::addAuthorizedLocation(
+							Common::String(path),
+							label ? Common::String(label) : Common::String());
+			}
+		}
+	}
+
 	if (retro_log_cb)
 		retro_log_cb(RETRO_LOG_DEBUG, "ScummVM core version: %s\n", __GIT_VERSION);
 
diff --git a/backends/platform/libretro/src/libretro-fs-factory.cpp b/backends/platform/libretro/src/libretro-fs-factory.cpp
index 772b1c5e625..931d4f20f66 100644
--- a/backends/platform/libretro/src/libretro-fs-factory.cpp
+++ b/backends/platform/libretro/src/libretro-fs-factory.cpp
@@ -32,6 +32,9 @@
 #include "backends/platform/libretro/include/libretro-fs.h"
 
 AbstractFSNode *LibRetroFilesystemFactory::makeRootFileNode() const {
+	if (LibRetroFilesystemNode::hasAuthorizedLocations())
+		return new LibRetroFilesystemNode(LibRetroFilesystemNode::getAuthorizedRootPath());
+
 	return new LibRetroFilesystemNode("/");
 }
 
diff --git a/backends/platform/libretro/src/libretro-fs.cpp b/backends/platform/libretro/src/libretro-fs.cpp
index 08dd4ef86d8..14ed814a53d 100644
--- a/backends/platform/libretro/src/libretro-fs.cpp
+++ b/backends/platform/libretro/src/libretro-fs.cpp
@@ -43,8 +43,57 @@
 #include "backends/platform/libretro/include/libretro-fs.h"
 #include "backends/platform/libretro/include/libretro-core.h"
 #include "common/algorithm.h"
+#include "common/array.h"
 #include "common/stream.h"
 
+static const char *kLibRetroAuthorizedRootPath = "libretro-authorized:///";
+static const char *kLibRetroAuthorizedRootLabel = "RetroArch authorized locations";
+
+struct LibRetroAuthorizedLocation {
+	Common::String path;
+	Common::String label;
+};
+
+static Common::Array<LibRetroAuthorizedLocation> s_libretroAuthorizedLocations;
+
+static Common::String libretroFsStripTrailingSlash(Common::String path) {
+	while (path.size() > 1 && path.lastChar() == '/')
+		path.erase(path.size() - 1);
+
+	return path;
+}
+
+static bool libretroFsSamePath(const Common::String &a, const Common::String &b) {
+	return libretroFsStripTrailingSlash(a).equals(libretroFsStripTrailingSlash(b));
+}
+
+static bool libretroFsIsAuthorizedRoot(const Common::String &path) {
+	Common::String normalizedPath = libretroFsStripTrailingSlash(path);
+
+	for (uint i = 0; i < s_libretroAuthorizedLocations.size(); ++i) {
+		if (normalizedPath.equals(libretroFsStripTrailingSlash(s_libretroAuthorizedLocations[i].path)))
+			return true;
+	}
+
+	return false;
+}
+
+static bool libretroFsIsInsideAuthorizedLocation(const Common::String &path) {
+	Common::String normalizedPath = libretroFsStripTrailingSlash(path);
+
+	for (uint i = 0; i < s_libretroAuthorizedLocations.size(); ++i) {
+		Common::String root = libretroFsStripTrailingSlash(s_libretroAuthorizedLocations[i].path);
+
+		if (normalizedPath.equals(root))
+			return true;
+
+		if (normalizedPath.hasPrefix(root) && normalizedPath.size() > root.size() && normalizedPath[root.size()] == '/')
+			return true;
+	}
+
+	return false;
+}
+
 static bool libretroFsHasUriScheme(const Common::String &path) {
 	return strstr(path.c_str(), "://") != nullptr;
 }
@@ -286,6 +335,16 @@ void LibRetroFilesystemNode::setFlags() {
 LibRetroFilesystemNode::LibRetroFilesystemNode(const Common::String &p) {
 	assert(p.size() > 0);
 
+	if (p.equals(kLibRetroAuthorizedRootPath)) {
+		_path = p;
+		_displayName = kLibRetroAuthorizedRootLabel;
+		_isValid = true;
+		_isDirectory = true;
+		_isReadable = true;
+		_isWritable = false;
+		return;
+	}
+
 	if (libretroFsHasUriScheme(p)) {
 		_path = p;
 		_displayName = libretroFsUriDisplayName(_path);
@@ -336,6 +395,27 @@ AbstractFSNode *LibRetroFilesystemNode::getChild(const Common::String &n) const
 bool LibRetroFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
 	assert(_isDirectory);
 
+	if (_path.equals(kLibRetroAuthorizedRootPath)) {
+		if (mode == Common::FSNode::kListFilesOnly)
+			return true;
+
+		for (uint i = 0; i < s_libretroAuthorizedLocations.size(); ++i) {
+			LibRetroFilesystemNode *node = new LibRetroFilesystemNode(s_libretroAuthorizedLocations[i].path);
+
+			if (!node->isDirectory()) {
+				delete node;
+				continue;
+			}
+
+			if (!s_libretroAuthorizedLocations[i].label.empty())
+				node->_displayName = s_libretroAuthorizedLocations[i].label;
+
+			myList.push_back(node);
+		}
+
+		return true;
+	}
+
 	struct RDIR *dirp = retro_opendir(_path.c_str());
 
 	if (dirp == NULL)
@@ -380,9 +460,12 @@ bool LibRetroFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode,
 }
 
 AbstractFSNode *LibRetroFilesystemNode::getParent() const {
-	if (_path == "/")
+	if (_path == "/" || _path.equals(kLibRetroAuthorizedRootPath))
 		return 0; // The filesystem root has no parent
 
+	if (hasAuthorizedLocations() && libretroFsIsAuthorizedRoot(_path))
+		return makeNode(kLibRetroAuthorizedRootPath);
+
 	Common::String parentPath(_path);
 
 	if (libretroFsHasUriScheme(parentPath)) {
@@ -408,6 +491,9 @@ AbstractFSNode *LibRetroFilesystemNode::getParent() const {
 			parentPath.erase(parentPath.size() - 1);
 
 		if (parentPath.size() <= uriRootLen) {
+			if (hasAuthorizedLocations() && (parentPath.hasPrefix("saf://") || libretroFsIsInsideAuthorizedLocation(_path)))
+				return makeNode(kLibRetroAuthorizedRootPath);
+
 			return makeNode("/");
 		}
 
@@ -559,7 +645,46 @@ Common::String LibRetroFilesystemNode::getHomeDir(void) {
 	return path;
 }
 
+Common::String LibRetroFilesystemNode::getAuthorizedRootPath(void) {
+	return Common::String(kLibRetroAuthorizedRootPath);
+}
+
+void LibRetroFilesystemNode::clearAuthorizedLocations(void) {
+	s_libretroAuthorizedLocations.clear();
+}
+
+void LibRetroFilesystemNode::addAuthorizedLocation(const Common::String &path, const Common::String &label) {
+	if (path.empty())
+		return;
+
+	for (uint i = 0; i < s_libretroAuthorizedLocations.size(); ++i) {
+		if (libretroFsSamePath(s_libretroAuthorizedLocations[i].path, path))
+			return;
+	}
+
+	LibRetroFilesystemNode node(path);
+	if (!node.isDirectory())
+		return;
+
+	LibRetroAuthorizedLocation location;
+	location.path = path;
+
+	if (!label.empty())
+		location.label = label;
+	else
+		location.label = libretroFsUriDisplayName(path);
+
+	s_libretroAuthorizedLocations.push_back(location);
+}
+
+bool LibRetroFilesystemNode::hasAuthorizedLocations(void) {
+	return !s_libretroAuthorizedLocations.empty();
+}
+
 Common::String LibRetroFilesystemNode::getDefaultDir(void) {
+	if (hasAuthorizedLocations())
+		return s_libretroAuthorizedLocations[0].path;
+
 	Common::String homeDir(getHomeDir());
 
 	if (!homeDir.empty() && LibRetroFilesystemNode(homeDir).isDirectory())


Commit: 75d9049057d9a9a99c581414f1f2dca833975e45
    https://github.com/scummvm/scummvm/commit/75d9049057d9a9a99c581414f1f2dca833975e45
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2026-08-17T10:11:45+02:00

Commit Message:
LIBRETRO: add use of RETRO_ENVIRONMENT_GET_FILE_BROWSER_START_DIRECTORY

Changed paths:
    backends/platform/libretro/include/libretro-core.h
    backends/platform/libretro/src/libretro-core.cpp
    backends/platform/libretro/src/libretro-fs.cpp


diff --git a/backends/platform/libretro/include/libretro-core.h b/backends/platform/libretro/include/libretro-core.h
index c1e8bbdc083..f5b8818b2f7 100644
--- a/backends/platform/libretro/include/libretro-core.h
+++ b/backends/platform/libretro/include/libretro-core.h
@@ -29,6 +29,7 @@ void retro_osd_notification(const char *msg);
 int retro_get_input_device(void);
 const char *retro_get_core_dir(void);
 const char *retro_get_system_dir(void);
+const char *retro_get_file_browser_start_dir(void);
 const char *retro_get_save_dir(void);
 const char *retro_get_playlist_dir(void);
 
diff --git a/backends/platform/libretro/src/libretro-core.cpp b/backends/platform/libretro/src/libretro-core.cpp
index f5c5d0bccdf..93e2e48bdd3 100644
--- a/backends/platform/libretro/src/libretro-core.cpp
+++ b/backends/platform/libretro/src/libretro-core.cpp
@@ -884,6 +884,15 @@ const char *retro_get_system_dir(void) {
 	return sysdir;
 }
 
+const char *retro_get_file_browser_start_dir(void) {
+	const char *startdir = NULL;
+
+	if (!environ_cb || !environ_cb(RETRO_ENVIRONMENT_GET_FILE_BROWSER_START_DIRECTORY, &startdir))
+		return NULL;
+
+	return startdir;
+}
+
 const char *retro_get_save_dir(void) {
 	const char *savedir = NULL;
 
diff --git a/backends/platform/libretro/src/libretro-fs.cpp b/backends/platform/libretro/src/libretro-fs.cpp
index 14ed814a53d..9f7d91e5210 100644
--- a/backends/platform/libretro/src/libretro-fs.cpp
+++ b/backends/platform/libretro/src/libretro-fs.cpp
@@ -685,6 +685,13 @@ Common::String LibRetroFilesystemNode::getDefaultDir(void) {
 	if (hasAuthorizedLocations())
 		return s_libretroAuthorizedLocations[0].path;
 
+	const char *browserStartDir = retro_get_file_browser_start_dir();
+	if (browserStartDir && *browserStartDir) {
+		Common::String path(browserStartDir);
+		if (LibRetroFilesystemNode(path).isDirectory())
+			return path;
+	}
+
 	Common::String homeDir(getHomeDir());
 
 	if (!homeDir.empty() && LibRetroFilesystemNode(homeDir).isDirectory())


Commit: a5e2c0f38704c43edd69bebf9dd0a1556455091b
    https://github.com/scummvm/scummvm/commit/a5e2c0f38704c43edd69bebf9dd0a1556455091b
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2026-08-17T10:12:08+02:00

Commit Message:
LIBRETRO: BUILD: sync with libretro-common

Changed paths:
    backends/platform/libretro/dependencies.mk
    backends/platform/libretro/src/libretro-core.cpp


diff --git a/backends/platform/libretro/dependencies.mk b/backends/platform/libretro/dependencies.mk
index 4ac9f221e7d..b518997300f 100644
--- a/backends/platform/libretro/dependencies.mk
+++ b/backends/platform/libretro/dependencies.mk
@@ -11,7 +11,7 @@ DEPS_COMMIT_libretro-deps   := bab7d258c451c0e7cba4b6a79f1b062c13efff38
 
 DEPS_FOLDER_libretro-common := libretro-common
 DEPS_URL_libretro-common    := https://github.com/libretro/libretro-common
-DEPS_COMMIT_libretro-common := 692124dbd8a0b2f5526b48f3bc2026421754e3c5
+DEPS_COMMIT_libretro-common := 879c8d507b0b52e77e27d759239c2b5df1e26dfd
 
 submodule_test  = $(if $(shell result=$$($(SCRIPTS_PATH)/configure_submodules.sh $(DEPS_URL_$(1)) $(DEPS_COMMIT_$(1)) $(DEPS_PATH) $(DEBUG_ALLOW_DIRTY_SUBMODULES) $(DEPS_FOLDER_$(1))) ; { [ -z $$result ] || [ ! $$result = 0 ] ; } && printf error),$(1))
 $(info Configuring submodules...)
diff --git a/backends/platform/libretro/src/libretro-core.cpp b/backends/platform/libretro/src/libretro-core.cpp
index 93e2e48bdd3..d15e4d76114 100644
--- a/backends/platform/libretro/src/libretro-core.cpp
+++ b/backends/platform/libretro/src/libretro-core.cpp
@@ -59,22 +59,6 @@
 #include "backends/platform/libretro/include/libretro-fs.h"
 #include "backends/platform/libretro/include/libretro-mapper.h"
 
-#ifndef RETRO_ENVIRONMENT_GET_VFS_AUTHORIZED_LOCATIONS
-#define RETRO_ENVIRONMENT_GET_VFS_AUTHORIZED_LOCATIONS (93 | RETRO_ENVIRONMENT_EXPERIMENTAL)
-
-struct retro_vfs_authorized_location {
-	const char *path;
-	const char *label;
-	unsigned flags;
-};
-
-struct retro_vfs_authorized_locations {
-	const struct retro_vfs_authorized_location *locations;
-	size_t count;
-};
-#endif
-
-
 static struct retro_game_info game_buf;
 static struct retro_game_info *game_buf_ptr;
 


Commit: 3aefd831b94fa3ac51d316e2eaf399853bb3b418
    https://github.com/scummvm/scummvm/commit/3aefd831b94fa3ac51d316e2eaf399853bb3b418
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2026-08-17T10:19:01+02:00

Commit Message:
LIBRETRO: add Browsing Mode core setting

Changed paths:
    backends/platform/libretro/include/libretro-core-options-intl.h
    backends/platform/libretro/include/libretro-core-options.h
    backends/platform/libretro/include/libretro-core.h
    backends/platform/libretro/include/libretro-fs.h
    backends/platform/libretro/src/libretro-core.cpp
    backends/platform/libretro/src/libretro-fs-factory.cpp
    backends/platform/libretro/src/libretro-fs.cpp
    backends/platform/libretro/src/libretro-os-utils.cpp


diff --git a/backends/platform/libretro/include/libretro-core-options-intl.h b/backends/platform/libretro/include/libretro-core-options-intl.h
index ac8bfeffe87..37362bb3c3d 100644
--- a/backends/platform/libretro/include/libretro-core-options-intl.h
+++ b/backends/platform/libretro/include/libretro-core-options-intl.h
@@ -90,6 +90,11 @@ struct retro_core_option_v2_category option_cats_it[] = {
 		"Mappatura RetroPad",
 		"Configura la mappatura del RetroPad"
 	},
+	{
+		"system",
+		"Sistema",
+		"Configura le impostazioni di sistema"
+	},
 	{ NULL, NULL, NULL },
 };
 
@@ -534,6 +539,20 @@ struct retro_core_option_v2_definition option_defs_it[] = {
 		NULL,
 	},
 #endif
+	{
+		"scummvm_browsing_mode",
+		"Sistema > Modalità di navigazione",
+		"Modalità di navigazione",
+		"Seleziona come il file browser di ScummVM elenca le posizioni. 'Archiviazione autorizzata' mostra le cartelle autorizzate tramite il frontend (es. tree SAF di Android). 'File system locale' naviga i percorsi locali standard.",
+		NULL,
+		NULL,
+		{
+			{"local", "File system locale"},
+			{"authorized", "Archiviazione autorizzata"},
+			{NULL, NULL},
+		},
+		NULL
+	},
 	{ NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL },
 };
 struct retro_core_options_v2 options_it = {
diff --git a/backends/platform/libretro/include/libretro-core-options.h b/backends/platform/libretro/include/libretro-core-options.h
index dfb9ee36448..cdc8635b688 100644
--- a/backends/platform/libretro/include/libretro-core-options.h
+++ b/backends/platform/libretro/include/libretro-core-options.h
@@ -92,6 +92,11 @@ struct retro_core_option_v2_category option_cats_us[] = {
 		"RetroPad mapping",
 		"Configure RetroPad mapping"
 	},
+	{
+		"system",
+		"System",
+		"Configure system settings"
+	},
 	{ NULL, NULL, NULL },
 };
 
@@ -613,6 +618,24 @@ struct retro_core_option_v2_definition option_defs_us[] = {
 		"720"
 	},
 #endif
+	{
+		"scummvm_browsing_mode",
+		"System > Browsing mode",
+		"Browsing mode",
+		"Select how the ScummVM file browser lists locations. 'Authorized storage' shows the folders authorized through the frontend (e.g. Android SAF trees). 'Local filesystem' browses the standard local paths.",
+		NULL,
+		"system",
+		{
+			{"local", "Local filesystem"},
+			{"authorized", "Authorized storage"},
+			{NULL, NULL},
+		},
+#ifdef ANDROID
+		"authorized"
+#else
+		"local"
+#endif
+	},
 	{ NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL },
 };
 
diff --git a/backends/platform/libretro/include/libretro-core.h b/backends/platform/libretro/include/libretro-core.h
index f5b8818b2f7..85bf9f53457 100644
--- a/backends/platform/libretro/include/libretro-core.h
+++ b/backends/platform/libretro/include/libretro-core.h
@@ -35,6 +35,7 @@ const char *retro_get_playlist_dir(void);
 
 float retro_setting_get_frame_rate(void);
 uint16 retro_setting_get_sample_rate(void);
+bool retro_setting_get_browsing_mode_authorized(void);
 uint16 retro_setting_get_audio_samples_buffer_size(void);
 int retro_setting_get_analog_deadzone(void);
 bool retro_setting_get_analog_response_is_quadratic(void);
diff --git a/backends/platform/libretro/include/libretro-fs.h b/backends/platform/libretro/include/libretro-fs.h
index 34fba406196..3d2ad414941 100644
--- a/backends/platform/libretro/include/libretro-fs.h
+++ b/backends/platform/libretro/include/libretro-fs.h
@@ -96,6 +96,7 @@ public:
 	static void clearAuthorizedLocations(void);
 	static void addAuthorizedLocation(const Common::String &path, const Common::String &label);
 	static bool hasAuthorizedLocations(void);
+	static bool useAuthorizedRoot(void);
 private:
 	/**
 	 * Tests and sets the _isValid and _isDirectory flags, using the stat() function.
diff --git a/backends/platform/libretro/src/libretro-core.cpp b/backends/platform/libretro/src/libretro-core.cpp
index d15e4d76114..56fc7048724 100644
--- a/backends/platform/libretro/src/libretro-core.cpp
+++ b/backends/platform/libretro/src/libretro-core.cpp
@@ -107,6 +107,7 @@ static retro_time_t audio_last_time_usec = 0; // timestamp of the previous audio
 static int16 *audio_sample_buffer = NULL; // pointer to output buffer
 
 static bool input_bitmask_supported = false;
+static bool browsing_mode_authorized = false;
 static bool updating_variables = false;
 
 #ifdef USE_OPENGL
@@ -366,6 +367,17 @@ static void update_variables(void) {
 	} else
 		sample_rate = DEFAULT_SAMPLE_RATE;
 
+	var.key = "scummvm_browsing_mode";
+	var.value = NULL;
+	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+		browsing_mode_authorized = (strcmp(var.value, "authorized") == 0);
+	else
+#ifdef ANDROID
+		browsing_mode_authorized = true;
+#else
+		browsing_mode_authorized = false;
+#endif
+
 	var.key = "scummvm_mapper_up";
 	var.value = NULL;
 	if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
@@ -645,6 +657,10 @@ uint16 retro_setting_get_sample_rate(void) {
 	return sample_rate;
 }
 
+bool retro_setting_get_browsing_mode_authorized(void) {
+	return browsing_mode_authorized;
+}
+
 
 static uint32 next_pow2(uint32 x) {
 	if (x <= 1) return 1;
@@ -971,6 +987,13 @@ void retro_init(void) {
 		retro_log_cb(RETRO_LOG_DEBUG, "ScummVM core version: %s\n", __GIT_VERSION);
 
 	update_variables();
+
+	if (retro_setting_get_browsing_mode_authorized() && !LibRetroFilesystemNode::hasAuthorizedLocations()) {
+		if (retro_log_cb)
+			retro_log_cb(RETRO_LOG_WARN, "[scummvm] Browsing mode set to 'Authorized storage' but no authorized locations are available; falling back to local filesystem. Authorize folders from the frontend and restart the core.\n");
+		retro_osd_notification("No authorized storage available, using local filesystem.");
+	}
+
 	max_width = gui_width > max_width ? gui_width : max_width;
 	max_height = gui_height > max_height ? gui_height : max_height;
 
diff --git a/backends/platform/libretro/src/libretro-fs-factory.cpp b/backends/platform/libretro/src/libretro-fs-factory.cpp
index 931d4f20f66..fc2e1749ff1 100644
--- a/backends/platform/libretro/src/libretro-fs-factory.cpp
+++ b/backends/platform/libretro/src/libretro-fs-factory.cpp
@@ -32,7 +32,7 @@
 #include "backends/platform/libretro/include/libretro-fs.h"
 
 AbstractFSNode *LibRetroFilesystemFactory::makeRootFileNode() const {
-	if (LibRetroFilesystemNode::hasAuthorizedLocations())
+	if (LibRetroFilesystemNode::useAuthorizedRoot())
 		return new LibRetroFilesystemNode(LibRetroFilesystemNode::getAuthorizedRootPath());
 
 	return new LibRetroFilesystemNode("/");
diff --git a/backends/platform/libretro/src/libretro-fs.cpp b/backends/platform/libretro/src/libretro-fs.cpp
index 9f7d91e5210..107474c4546 100644
--- a/backends/platform/libretro/src/libretro-fs.cpp
+++ b/backends/platform/libretro/src/libretro-fs.cpp
@@ -45,9 +45,10 @@
 #include "common/algorithm.h"
 #include "common/array.h"
 #include "common/stream.h"
+#include "common/config-manager.h"
 
 static const char *kLibRetroAuthorizedRootPath = "libretro-authorized:///";
-static const char *kLibRetroAuthorizedRootLabel = "RetroArch authorized locations";
+static const char *kLibRetroAuthorizedRootLabel = "Authorized storage";
 
 struct LibRetroAuthorizedLocation {
 	Common::String path;
@@ -94,6 +95,8 @@ static bool libretroFsIsInsideAuthorizedLocation(const Common::String &path) {
 	return false;
 }
 
+static Common::String libretroFsPosixDefaultDir();
+
 static bool libretroFsHasUriScheme(const Common::String &path) {
 	return strstr(path.c_str(), "://") != nullptr;
 }
@@ -681,10 +684,7 @@ bool LibRetroFilesystemNode::hasAuthorizedLocations(void) {
 	return !s_libretroAuthorizedLocations.empty();
 }
 
-Common::String LibRetroFilesystemNode::getDefaultDir(void) {
-	if (hasAuthorizedLocations())
-		return s_libretroAuthorizedLocations[0].path;
-
+static Common::String libretroFsPosixDefaultDir() {
 	const char *browserStartDir = retro_get_file_browser_start_dir();
 	if (browserStartDir && *browserStartDir) {
 		Common::String path(browserStartDir);
@@ -692,7 +692,7 @@ Common::String LibRetroFilesystemNode::getDefaultDir(void) {
 			return path;
 	}
 
-	Common::String homeDir(getHomeDir());
+	Common::String homeDir(LibRetroFilesystemNode::getHomeDir());
 
 	if (!homeDir.empty() && LibRetroFilesystemNode(homeDir).isDirectory())
 		return homeDir;
@@ -713,3 +713,17 @@ Common::String LibRetroFilesystemNode::getDefaultDir(void) {
 
 	return Common::String("/");
 }
+
+bool LibRetroFilesystemNode::useAuthorizedRoot(void) {
+	if (!hasAuthorizedLocations())
+		return false;
+
+	return retro_setting_get_browsing_mode_authorized();
+}
+
+Common::String LibRetroFilesystemNode::getDefaultDir(void) {
+	if (useAuthorizedRoot())
+		return getAuthorizedRootPath();
+
+	return libretroFsPosixDefaultDir();
+}
diff --git a/backends/platform/libretro/src/libretro-os-utils.cpp b/backends/platform/libretro/src/libretro-os-utils.cpp
index e1e10381e99..6ba7c1c0ffa 100644
--- a/backends/platform/libretro/src/libretro-os-utils.cpp
+++ b/backends/platform/libretro/src/libretro-os-utils.cpp
@@ -219,7 +219,7 @@ void OSystem_libretro::applyBackendSettings() {
 
 	//Check current path settings
 	if (!checkPathSetting("savepath", s_saveDir)) {
-		ConfMan.setAndFlush("savepath", s_homeDir);
+		ConfMan.setAndFlush("savepath", s_systemDir);
 		retro_osd_notification("ScummVM save folder not found.");
 	}
 	if (!checkPathSetting("themepath", s_themeDir))
@@ -228,7 +228,7 @@ void OSystem_libretro::applyBackendSettings() {
 		retro_osd_notification("ScummVM extra folder not found. Some engines/features (e.g. Virtual Keyboard) will not work without relevant datafiles.");
 	checkPathSetting("soundfont", s_soundfontPath, false);
 	checkPathSetting("browser_lastpath", s_homeDir);
-	checkPathSetting("libretro_playlist_path", s_playlistDir.empty() ? s_homeDir : s_playlistDir);
+	checkPathSetting("libretro_playlist_path", s_playlistDir.empty() ? s_systemDir : s_playlistDir);
 	checkPathSetting("iconspath", "");
 }
 


Commit: d7fb0de22db85de22e1381c6a9085806c3bb42f9
    https://github.com/scummvm/scummvm/commit/d7fb0de22db85de22e1381c6a9085806c3bb42f9
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2026-08-17T10:19:01+02:00

Commit Message:
LIBRETRO: add android storage information

Changed paths:
    backends/platform/libretro/README.md
    backends/platform/libretro/src/libretro-os-utils.cpp


diff --git a/backends/platform/libretro/README.md b/backends/platform/libretro/README.md
index 66c97187201..84933dcbd7f 100644
--- a/backends/platform/libretro/README.md
+++ b/backends/platform/libretro/README.md
@@ -75,3 +75,23 @@ Operation status will be shown in the same dialog, while details will be given i
   - **Sample rate**: set core sample rate. Reducing the rate will slightly improve the performance on lower end devices. Changing this setting will reset the core.
 ### RetroPad mapping
 Settings to map each RetroPad key to ScummVM controls.
+
+## Android storage access
+On modern Android versions apps can only access folders explicitly authorized by the user through the system file picker (Storage Access Framework, SAF).
+
+The core can browse both the standard local filesystem and the folders authorized through the frontend (e.g. RetroArch). The starting location of the ScummVM file browser is controlled by the **Browsing mode** core option.
+
+### Browsing mode
+Available under the frontend core options (e.g. RetroArch `Quick Menu > Core Options > System`):
+
+  - **Authorized storage**: the file browser starts from a virtual root listing only the folders authorized through the frontend. Default on Android.
+  - **Local filesystem**: the file browser starts from the standard local path.
+
+### Authorizing folders
+  - Open the frontend file browser (e.g. in RetroArch, "Load Content") and use the option to open/add a new folder; the system file picker will appear.
+  - Grant access to the folder(s) containing your games and exit the file browser (no need to actually select any content at this time). The authorization is persistent across reboots.
+  - Start the core; the authorized folders will be listed by the ScummVM file browser when **Browsing mode** is set to `Authorized storage`.
+
+### Notes
+  - The authorized folder list is read when the core starts. If you authorize new folders while the core is running, restart (reload) the core to make them available.
+  - If **Browsing mode** is `Authorized storage` but no folders have been authorized, the core falls back to the local filesystem and shows a notification.
diff --git a/backends/platform/libretro/src/libretro-os-utils.cpp b/backends/platform/libretro/src/libretro-os-utils.cpp
index 6ba7c1c0ffa..36116345aea 100644
--- a/backends/platform/libretro/src/libretro-os-utils.cpp
+++ b/backends/platform/libretro/src/libretro-os-utils.cpp
@@ -269,6 +269,36 @@ static const char *const helpTabs[] = {
 	    "Operation status will be shown in the same dialog, while details will be given in frontend logs."
 	),
 
+#ifdef ANDROID
+	_s("Android storage"),
+	"",
+	_s(
+	    "## Android storage access\n"
+	    "On Android modern versions apps can only access folders that have been explicitly authorized by the user through the system file picker (Storage Access Framework, SAF).\n"
+	    "\n"
+	    "The core can browse both the standard local filesystem and the folders authorized through the frontend (e.g. RetroArch). The starting location of the file browser is controlled by the **Browsing mode** core option.\n"
+	    "\n"
+	    "## Browsing mode\n"
+	    "This core option is available in the frontend core options (e.g. RetroArch 'Quick Menu > Core Options > System').\n"
+	    "\n"
+	    "  - **Authorized storage**: the file browser starts from a virtual root listing only the folders authorized through the frontend. This is the default on Android.\n"
+	    "\n"
+	    "  - **Local filesystem**: the file browser starts from the standard local path.\n"
+	    "\n"
+	    "## Authorizing folders\n"
+	    "  - Open the frontend file browser (e.g. in RetroArch, 'Load Content') and use the option to open/add a folder; the system file picker will appear.\n"
+	    "\n"
+	    "  - Grant access to the folder(s) that contain your games and exit the file browser (no need to actually select any content at this time). The authorization is persistent across reboots.\n"
+	    "\n"
+	    "  - Start the core; the authorized folders will be listed by the ScummVM file browser when **Browsing mode** is set to 'Authorized storage'.\n"
+	    "\n"
+	    "## Notes\n"
+	    "  - The authorized folder list is read when the core starts. If you authorize new folders while the core is running, restart (reload) the core to make them available.\n"
+	    "\n"
+	    "  - If **Browsing mode** is set to 'Authorized storage' but no folders have been authorized, the core falls back to the local filesystem and shows a notification.\n"
+	),
+#endif
+
 	0 // End of list
 };
 


Commit: 940c6287c0ce6c3b91392ca1e34cb0c97ea2a911
    https://github.com/scummvm/scummvm/commit/940c6287c0ce6c3b91392ca1e34cb0c97ea2a911
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2026-08-17T10:19:01+02:00

Commit Message:
LIBRETRO: add consistency check for last browsed path

Changed paths:
    backends/platform/libretro/include/libretro-fs.h
    backends/platform/libretro/src/libretro-fs.cpp
    backends/platform/libretro/src/libretro-os-utils.cpp


diff --git a/backends/platform/libretro/include/libretro-fs.h b/backends/platform/libretro/include/libretro-fs.h
index 3d2ad414941..91bcc62b669 100644
--- a/backends/platform/libretro/include/libretro-fs.h
+++ b/backends/platform/libretro/include/libretro-fs.h
@@ -97,6 +97,7 @@ public:
 	static void addAuthorizedLocation(const Common::String &path, const Common::String &label);
 	static bool hasAuthorizedLocations(void);
 	static bool useAuthorizedRoot(void);
+	static bool isBrowserLastPathCompatible(const Common::String &path);
 private:
 	/**
 	 * Tests and sets the _isValid and _isDirectory flags, using the stat() function.
diff --git a/backends/platform/libretro/src/libretro-fs.cpp b/backends/platform/libretro/src/libretro-fs.cpp
index 107474c4546..c3fa0af24ee 100644
--- a/backends/platform/libretro/src/libretro-fs.cpp
+++ b/backends/platform/libretro/src/libretro-fs.cpp
@@ -721,6 +721,18 @@ bool LibRetroFilesystemNode::useAuthorizedRoot(void) {
 	return retro_setting_get_browsing_mode_authorized();
 }
 
+bool LibRetroFilesystemNode::isBrowserLastPathCompatible(const Common::String &path) {
+	if (path.empty())
+		return false;
+
+	bool isAuthorizedPath = path.equals(kLibRetroAuthorizedRootPath) || libretroFsIsInsideAuthorizedLocation(path);
+
+	if (useAuthorizedRoot())
+		return isAuthorizedPath;
+
+	return !isAuthorizedPath;
+}
+
 Common::String LibRetroFilesystemNode::getDefaultDir(void) {
 	if (useAuthorizedRoot())
 		return getAuthorizedRootPath();
diff --git a/backends/platform/libretro/src/libretro-os-utils.cpp b/backends/platform/libretro/src/libretro-os-utils.cpp
index 36116345aea..af046d2cf9b 100644
--- a/backends/platform/libretro/src/libretro-os-utils.cpp
+++ b/backends/platform/libretro/src/libretro-os-utils.cpp
@@ -227,7 +227,18 @@ void OSystem_libretro::applyBackendSettings() {
 	if (!checkPathSetting("extrapath", s_extraDir))
 		retro_osd_notification("ScummVM extra folder not found. Some engines/features (e.g. Virtual Keyboard) will not work without relevant datafiles.");
 	checkPathSetting("soundfont", s_soundfontPath, false);
-	checkPathSetting("browser_lastpath", s_homeDir);
+	{
+		Common::String lastPath;
+		if (ConfMan.hasKey("browser_lastpath"))
+			lastPath = Common::Path::fromConfig(ConfMan.get("browser_lastpath")).toString();
+
+		if (lastPath.empty() || !LibRetroFilesystemNode::isBrowserLastPathCompatible(lastPath)) {
+			if (s_homeDir.empty())
+				ConfMan.removeKey("browser_lastpath", Common::ConfigManager::kApplicationDomain);
+			else
+				ConfMan.setPath("browser_lastpath", Common::Path::fromConfig(s_homeDir));
+		}
+	}
 	checkPathSetting("libretro_playlist_path", s_playlistDir.empty() ? s_systemDir : s_playlistDir);
 	checkPathSetting("iconspath", "");
 }


Commit: 414d2d6952b2248558b14570299aa7f938f09aa6
    https://github.com/scummvm/scummvm/commit/414d2d6952b2248558b14570299aa7f938f09aa6
Author: Giovanni Cascione (ing.cascione at gmail.com)
Date: 2026-08-17T10:19:01+02:00

Commit Message:
LIBRETRO: add URI parser for authorized paths labels

Changed paths:
    backends/platform/libretro/src/libretro-fs.cpp


diff --git a/backends/platform/libretro/src/libretro-fs.cpp b/backends/platform/libretro/src/libretro-fs.cpp
index c3fa0af24ee..4cf79795282 100644
--- a/backends/platform/libretro/src/libretro-fs.cpp
+++ b/backends/platform/libretro/src/libretro-fs.cpp
@@ -101,6 +101,50 @@ static bool libretroFsHasUriScheme(const Common::String &path) {
 	return strstr(path.c_str(), "://") != nullptr;
 }
 
+static Common::String libretroFsPercentDecode(const Common::String &s) {
+	Common::String out;
+	for (uint i = 0; i < s.size(); ++i) {
+		if (s[i] == '%' && i + 2 < s.size()) {
+			char h1 = s[i + 1], h2 = s[i + 2];
+			int v1 = (h1 >= '0' && h1 <= '9') ? h1 - '0' : (h1 >= 'A' && h1 <= 'F') ? h1 - 'A' + 10 : (h1 >= 'a' && h1 <= 'f') ? h1 - 'a' + 10 : -1;
+			int v2 = (h2 >= '0' && h2 <= '9') ? h2 - '0' : (h2 >= 'A' && h2 <= 'F') ? h2 - 'A' + 10 : (h2 >= 'a' && h2 <= 'f') ? h2 - 'a' + 10 : -1;
+			if (v1 >= 0 && v2 >= 0) {
+				out += (char)((v1 << 4) | v2);
+				i += 2;
+				continue;
+			}
+		}
+		out += s[i];
+	}
+	return out;
+}
+
+static Common::String libretroFsSafDisplayName(const Common::String &path) {
+	Common::String decoded(path);
+	// SAF paths are double-encoded (e.g. %252F). Decode up to twice to reveal real separators.
+	for (int pass = 0; pass < 2; ++pass) {
+		if (decoded.contains('%'))
+			decoded = libretroFsPercentDecode(decoded);
+		else
+			break;
+	}
+
+	while (decoded.size() > 1 && decoded.lastChar() == '/')
+		decoded.erase(decoded.size() - 1);
+
+	// Take the part after the last '/'.
+	size_t slash = decoded.findLastOf('/');
+	if (slash != Common::String::npos)
+		decoded = decoded.substr(slash + 1);
+
+	// Take the part after the last ':' (e.g. 'primary:Games' -> 'Games').
+	size_t colon = decoded.findLastOf(':');
+	if (colon != Common::String::npos)
+		decoded = decoded.substr(colon + 1);
+
+	return decoded.empty() ? path : decoded;
+}
+
 static Common::String libretroFsUriDisplayName(const Common::String &path) {
 	Common::String trimmed(path);
 
@@ -672,10 +716,10 @@ void LibRetroFilesystemNode::addAuthorizedLocation(const Common::String &path, c
 	LibRetroAuthorizedLocation location;
 	location.path = path;
 
-	if (!label.empty())
-		location.label = label;
-	else
-		location.label = libretroFsUriDisplayName(path);
+	// The frontend may pass a generic label (e.g. "Removable storage") for all
+	// SAF trees; derive a readable name from the path instead.
+	(void)label;
+	location.label = libretroFsSafDisplayName(path);
 
 	s_libretroAuthorizedLocations.push_back(location);
 }




More information about the Scummvm-git-logs mailing list