From c2b8be4c4f2e986490dcd2bf86d810c4e030be7e Mon Sep 17 00:00:00 2001 From: Craig Carnell <1188869+cscd98@users.noreply.github.com> Date: Mon, 3 Aug 2026 10:40:11 +0100 Subject: [PATCH] libretro: add vfs aware file checks in retro_load_game --- Makefile.common | 1 + libretro/libretro.c | 21 ++++++++++++--------- libretro/libretro_vfs.c | 39 +++++++++++++++++++++++++++++++++++++++ libretro/libretro_vfs.h | 14 ++++++++++++++ 4 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 libretro/libretro_vfs.c create mode 100644 libretro/libretro_vfs.h diff --git a/Makefile.common b/Makefile.common index 72aef3abc..575dbb5aa 100644 --- a/Makefile.common +++ b/Makefile.common @@ -232,6 +232,7 @@ endif # Libretro SOURCES_C += $(LIBRETRO_DIR)/libretro.c \ + $(LIBRETRO_DIR)/libretro_vfs.c \ $(LIBRETRO_COMM_DIR)/memmap/memalign.c \ $(ROOT_DIR)/custom/mupen64plus-core/plugin/emulate_game_controller_via_libretro.c \ $(LIBRETRO_COMM_DIR)/audio/resampler/drivers/sinc_resampler.c \ diff --git a/libretro/libretro.c b/libretro/libretro.c index 76656668b..98d49377b 100644 --- a/libretro/libretro.c +++ b/libretro/libretro.c @@ -56,6 +56,7 @@ #include "device/rcp/pi/pi_controller.h" #include "device/pif/pif.h" #include "libretro_memory.h" +#include "libretro_vfs.h" #include "audio_plugin.h" @@ -646,6 +647,13 @@ void retro_set_environment(retro_environment_t cb) environ_cb(RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO, (void*)subsystems); environ_cb(RETRO_ENVIRONMENT_GET_CLEAR_ALL_THREAD_WAITS_CB, &environ_clear_thread_waits_cb); + struct retro_vfs_interface_info vfs_iface_info; + vfs_iface_info.required_interface_version = 3; + vfs_iface_info.iface = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VFS_INTERFACE, &vfs_iface_info)) + vfs_interface = vfs_iface_info.iface; + setup_variables(); } @@ -1891,12 +1899,11 @@ bool retro_load_game(const struct retro_game_info *game) newPath = (char*)calloc(1, strlen(gamePath)+5); strcpy(newPath, gamePath); strcat(newPath, ".ndd"); - FILE* fileTest = fopen(newPath, "r"); - if(!fileTest) + + if (!vfs_file_exists(newPath)) { free(newPath); } else { - fclose(fileTest); // Free'd later in Mupen Core retro_dd_path_img = newPath; } @@ -1908,14 +1915,12 @@ bool retro_load_game(const struct retro_game_info *game) newPath = (char *)calloc(1, strlen(gamePath) + 4); strcpy(newPath, gamePath); strcat(newPath, ".gb"); - FILE *fileTest = fopen(newPath, "r"); - if (!fileTest) + if (!vfs_file_exists(newPath)) { free(newPath); } else { - fclose(fileTest); // Free'd later in Mupen Core retro_transferpak_rom_path = newPath; @@ -1926,14 +1931,12 @@ bool retro_load_game(const struct retro_game_info *game) newPath = (char *)calloc(1, strlen(gamePath) + 5); strcpy(newPath, gamePath); strcat(newPath, ".sav"); - FILE *fileTest = fopen(newPath, "r"); - if (!fileTest) + if (!vfs_file_exists(newPath)) { free(newPath); } else { - fclose(fileTest); // Free'd later in Mupen Core retro_transferpak_ram_path = newPath; } diff --git a/libretro/libretro_vfs.c b/libretro/libretro_vfs.c new file mode 100644 index 000000000..7a1816ada --- /dev/null +++ b/libretro/libretro_vfs.c @@ -0,0 +1,39 @@ +#include "libretro_vfs.h" + +#include +#include + +struct retro_vfs_interface *vfs_interface = NULL; + +void *vfs_fopen(const char *path, bool write) +{ + if (vfs_interface) + { + unsigned access = write ? RETRO_VFS_FILE_ACCESS_WRITE + : RETRO_VFS_FILE_ACCESS_READ; + return (void*)vfs_interface->open(path, access, RETRO_VFS_FILE_ACCESS_HINT_NONE); + } + + return (void*)fopen(path, write ? "wb" : "rb"); +} + +bool vfs_file_exists(const char *path) +{ + void *fp = vfs_fopen(path, false); + if (!fp) + return false; + + vfs_fclose(fp); + return true; +} + +void vfs_fclose(void *fp) +{ + if (!fp) + return; + + if (vfs_interface) + vfs_interface->close((struct retro_vfs_file_handle*)fp); + else + fclose((FILE*)fp); +} diff --git a/libretro/libretro_vfs.h b/libretro/libretro_vfs.h new file mode 100644 index 000000000..0d1fb6052 --- /dev/null +++ b/libretro/libretro_vfs.h @@ -0,0 +1,14 @@ +#ifndef _LIBRETRO_VFS_H_ +#define _LIBRETRO_VFS_H_ + +#include + +#include "libretro.h" + +extern struct retro_vfs_interface *vfs_interface; + +void *vfs_fopen(const char *path, bool write); +bool vfs_file_exists(const char *path); +void vfs_fclose(void *fp); + +#endif