Turn the VFS into a class, to be able to reuse it for other purposes.

This commit is contained in:
Henrik Rydgård 2023-03-06 14:23:56 +01:00
parent ebd8a63914
commit 3b39e9e068
29 changed files with 106 additions and 95 deletions

View File

@ -569,7 +569,7 @@ bool IniFile::Load(const Path &path)
bool IniFile::LoadFromVFS(const std::string &filename) {
size_t size;
uint8_t *data = VFSReadFile(filename.c_str(), &size);
uint8_t *data = g_VFS.ReadFile(filename.c_str(), &size);
if (!data)
return false;
std::string str((const char*)data, size);

View File

@ -8,7 +8,7 @@ namespace json {
JsonReader::JsonReader(const std::string &filename) {
size_t buf_size;
buffer_ = (char *)VFSReadFile(filename.c_str(), &buf_size);
buffer_ = (char *)g_VFS.ReadFile(filename.c_str(), &buf_size);
if (buffer_) {
parse();
} else {

View File

@ -126,7 +126,7 @@ int LoadZIMPtr(const uint8_t *zim, size_t datasize, int *width, int *height, int
int LoadZIM(const char *filename, int *width, int *height, int *format, uint8_t **image) {
size_t size;
uint8_t *buffer = VFSReadFile(filename, &size);
uint8_t *buffer = g_VFS.ReadFile(filename, &size);
if (!buffer) {
ERROR_LOG(IO, "Couldn't read data for '%s'", filename);
return 0;

View File

@ -73,7 +73,7 @@ Path I18NRepo::GetIniPath(const std::string &languageID) const {
bool I18NRepo::IniExists(const std::string &languageID) const {
File::FileInfo info;
if (!VFSGetFileInfo(GetIniPath(languageID).ToString().c_str(), &info))
if (!g_VFS.GetFileInfo(GetIniPath(languageID).ToString().c_str(), &info))
return false;
if (!info.exists)
return false;

View File

@ -1,3 +1,5 @@
#include <inttypes.h>
#include "Common/File/AndroidStorage.h"
#include "Common/StringUtils.h"
#include "Common/Log.h"

View File

@ -3,26 +3,20 @@
#include "Common/File/VFS/AssetReader.h"
#include "Common/File/AndroidStorage.h"
struct VFSEntry {
const char *prefix;
AssetReader *reader;
};
VFS g_VFS;
static VFSEntry entries[16];
static int num_entries = 0;
void VFSRegister(const char *prefix, AssetReader *reader) {
entries[num_entries].prefix = prefix;
entries[num_entries].reader = reader;
void VFS::Register(const char *prefix, AssetReader *reader) {
entries_[numEntries_].prefix = prefix;
entries_[numEntries_].reader = reader;
DEBUG_LOG(IO, "Registered VFS for prefix %s: %s", prefix, reader->toString().c_str());
num_entries++;
numEntries_++;
}
void VFSShutdown() {
for (int i = 0; i < num_entries; i++) {
delete entries[i].reader;
void VFS::Clear() {
for (int i = 0; i < numEntries_; i++) {
delete entries_[i].reader;
}
num_entries = 0;
numEntries_ = 0;
}
// TODO: Use Path more.
@ -38,7 +32,7 @@ static bool IsLocalAbsolutePath(const char *path) {
}
// The returned data should be free'd with delete[].
uint8_t *VFSReadFile(const char *filename, size_t *size) {
uint8_t *VFS::ReadFile(const char *filename, size_t *size) {
if (IsLocalAbsolutePath(filename)) {
// Local path, not VFS.
// INFO_LOG(IO, "Not a VFS path: %s . Reading local file.", filename);
@ -47,13 +41,13 @@ uint8_t *VFSReadFile(const char *filename, size_t *size) {
int fn_len = (int)strlen(filename);
bool fileSystemFound = false;
for (int i = 0; i < num_entries; i++) {
int prefix_len = (int)strlen(entries[i].prefix);
for (int i = 0; i < numEntries_; i++) {
int prefix_len = (int)strlen(entries_[i].prefix);
if (prefix_len >= fn_len) continue;
if (0 == memcmp(filename, entries[i].prefix, prefix_len)) {
if (0 == memcmp(filename, entries_[i].prefix, prefix_len)) {
fileSystemFound = true;
// INFO_LOG(IO, "Prefix match: %s (%s) -> %s", entries[i].prefix, filename, filename + prefix_len);
uint8_t *data = entries[i].reader->ReadAsset(filename + prefix_len, size);
uint8_t *data = entries_[i].reader->ReadAsset(filename + prefix_len, size);
if (data)
return data;
else
@ -67,7 +61,7 @@ uint8_t *VFSReadFile(const char *filename, size_t *size) {
return 0;
}
bool VFSGetFileListing(const char *path, std::vector<File::FileInfo> *listing, const char *filter) {
bool VFS::GetFileListing(const char *path, std::vector<File::FileInfo> *listing, const char *filter) {
if (IsLocalAbsolutePath(path)) {
// Local path, not VFS.
// INFO_LOG(IO, "Not a VFS path: %s . Reading local directory.", path);
@ -77,12 +71,12 @@ bool VFSGetFileListing(const char *path, std::vector<File::FileInfo> *listing, c
int fn_len = (int)strlen(path);
bool fileSystemFound = false;
for (int i = 0; i < num_entries; i++) {
int prefix_len = (int)strlen(entries[i].prefix);
for (int i = 0; i < numEntries_; i++) {
int prefix_len = (int)strlen(entries_[i].prefix);
if (prefix_len >= fn_len) continue;
if (0 == memcmp(path, entries[i].prefix, prefix_len)) {
if (0 == memcmp(path, entries_[i].prefix, prefix_len)) {
fileSystemFound = true;
if (entries[i].reader->GetFileListing(path + prefix_len, listing, filter)) {
if (entries_[i].reader->GetFileListing(path + prefix_len, listing, filter)) {
return true;
}
}
@ -94,7 +88,7 @@ bool VFSGetFileListing(const char *path, std::vector<File::FileInfo> *listing, c
return false;
}
bool VFSGetFileInfo(const char *path, File::FileInfo *info) {
bool VFS::GetFileInfo(const char *path, File::FileInfo *info) {
if (IsLocalAbsolutePath(path)) {
// Local path, not VFS.
// INFO_LOG(IO, "Not a VFS path: %s . Getting local file info.", path);
@ -103,19 +97,19 @@ bool VFSGetFileInfo(const char *path, File::FileInfo *info) {
bool fileSystemFound = false;
int fn_len = (int)strlen(path);
for (int i = 0; i < num_entries; i++) {
int prefix_len = (int)strlen(entries[i].prefix);
for (int i = 0; i < numEntries_; i++) {
int prefix_len = (int)strlen(entries_[i].prefix);
if (prefix_len >= fn_len) continue;
if (0 == memcmp(path, entries[i].prefix, prefix_len)) {
if (0 == memcmp(path, entries_[i].prefix, prefix_len)) {
fileSystemFound = true;
if (entries[i].reader->GetFileInfo(path + prefix_len, info))
if (entries_[i].reader->GetFileInfo(path + prefix_len, info))
return true;
else
continue;
}
}
if (!fileSystemFound) {
ERROR_LOG(IO, "Missing filesystem for %s", path);
ERROR_LOG(IO, "Missing filesystem for '%s'", path);
} // Otherwise, the file was just missing. No need to log.
return false;
}

View File

@ -10,12 +10,26 @@
class AssetReader;
void VFSRegister(const char *prefix, AssetReader *reader);
void VFSShutdown();
class VFS {
public:
void Register(const char *prefix, AssetReader *reader);
void Clear();
// Use delete [] to release the returned memory.
// Always allocates an extra zero byte at the end, so that it
// can be used for text like shader sources.
uint8_t *VFSReadFile(const char *filename, size_t *size);
bool VFSGetFileListing(const char *path, std::vector<File::FileInfo> *listing, const char *filter = 0);
bool VFSGetFileInfo(const char *filename, File::FileInfo *fileInfo);
// Use delete [] to release the returned memory.
// Always allocates an extra zero byte at the end, so that it
// can be used for text like shader sources.
uint8_t *ReadFile(const char *filename, size_t *size);
bool GetFileListing(const char *path, std::vector<File::FileInfo> *listing, const char *filter = 0);
bool GetFileInfo(const char *filename, File::FileInfo *fileInfo);
private:
struct VFSEntry {
const char *prefix;
AssetReader *reader;
};
VFSEntry entries_[16];
int numEntries_ = 0;
};
extern VFS g_VFS;

View File

@ -102,7 +102,7 @@ bool glsl_recompile(GLSLProgram *program, std::string *error_message) {
if (!program->vshader_source && !vsh_src) {
size_t sz;
vsh_src.reset((char *)VFSReadFile(program->vshader_filename, &sz));
vsh_src.reset((char *)g_VFS.ReadFile(program->vshader_filename, &sz));
}
if (!program->vshader_source && !vsh_src) {
ERROR_LOG(G3D, "File missing: %s", program->vshader_filename);
@ -113,7 +113,7 @@ bool glsl_recompile(GLSLProgram *program, std::string *error_message) {
}
if (!program->fshader_source && !fsh_src) {
size_t sz;
fsh_src.reset((char *)VFSReadFile(program->fshader_filename, &sz));
fsh_src.reset((char *)g_VFS.ReadFile(program->fshader_filename, &sz));
}
if (!program->fshader_source && !fsh_src) {
ERROR_LOG(G3D, "File missing: %s", program->fshader_filename);

View File

@ -148,7 +148,7 @@ bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, Imag
bool ManagedTexture::LoadFromFile(const std::string &filename, ImageFileType type, bool generateMips) {
generateMips_ = generateMips;
size_t fileSize;
uint8_t *buffer = VFSReadFile(filename.c_str(), &fileSize);
uint8_t *buffer = g_VFS.ReadFile(filename.c_str(), &fileSize);
if (!buffer) {
filename_.clear();
ERROR_LOG(IO, "Failed to read file '%s'", filename.c_str());

View File

@ -980,7 +980,7 @@ int VFSFileSystem::OpenFile(std::string filename, FileAccess access, const char
VERBOSE_LOG(FILESYS, "VFSFileSystem actually opening %s (%s)", fullNameC, filename.c_str());
size_t size;
u8 *data = VFSReadFile(fullNameC, &size);
u8 *data = g_VFS.ReadFile(fullNameC, &size);
if (!data) {
ERROR_LOG(FILESYS, "VFSFileSystem failed to open %s", filename.c_str());
return SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND;
@ -1001,7 +1001,7 @@ PSPFileInfo VFSFileSystem::GetFileInfo(std::string filename) {
std::string fullName = GetLocalPath(filename);
File::FileInfo fo;
if (VFSGetFileInfo(fullName.c_str(), &fo)) {
if (g_VFS.GetFileInfo(fullName.c_str(), &fo)) {
x.exists = fo.exists;
if (x.exists) {
x.size = fo.size;

View File

@ -569,7 +569,7 @@ namespace Reporting
return false;
#else
File::FileInfo fo;
if (!VFSGetFileInfo("flash0/font/jpn0.pgf", &fo))
if (!g_VFS.GetFileInfo("flash0/font/jpn0.pgf", &fo))
return false;
#endif

View File

@ -252,7 +252,7 @@ void __PPGeInit() {
if (loadedZIM) {
size_t atlas_data_size;
if (!g_ppge_atlas.IsMetadataLoaded()) {
uint8_t *atlas_data = VFSReadFile("ppge_atlas.meta", &atlas_data_size);
uint8_t *atlas_data = g_VFS.ReadFile("ppge_atlas.meta", &atlas_data_size);
if (atlas_data)
g_ppge_atlas.Load(atlas_data, atlas_data_size);
delete[] atlas_data;

View File

@ -237,7 +237,7 @@ static bool ServeDebuggerFile(const http::Request &request) {
return false;
size_t size;
uint8_t *data = VFSReadFile(filename, &size);
uint8_t *data = g_VFS.ReadFile(filename, &size);
if (!data)
return false;

View File

@ -70,7 +70,7 @@ void LoadPostShaderInfo(Draw::DrawContext *draw, const std::vector<Path> &direct
for (size_t d = 0; d < directories.size(); d++) {
std::vector<File::FileInfo> fileInfo;
VFSGetFileListing(directories[d].c_str(), &fileInfo, "ini:");
g_VFS.GetFileListing(directories[d].c_str(), &fileInfo, "ini:");
if (fileInfo.empty()) {
File::GetFilesInDir(directories[d], &fileInfo, "ini:");

View File

@ -212,7 +212,7 @@ void PresentationCommon::CalculatePostShaderUniforms(int bufferWidth, int buffer
static std::string ReadShaderSrc(const Path &filename) {
size_t sz = 0;
char *data = (char *)VFSReadFile(filename.c_str(), &sz);
char *data = (char *)g_VFS.ReadFile(filename.c_str(), &sz);
if (!data) {
return "";
}

View File

@ -260,7 +260,7 @@ void TextureCacheVulkan::NotifyConfigChanged() {
static std::string ReadShaderSrc(const Path &filename) {
size_t sz = 0;
char *data = (char *)VFSReadFile(filename.c_str(), &sz);
char *data = (char *)g_VFS.ReadFile(filename.c_str(), &sz);
if (!data)
return std::string();

View File

@ -29,7 +29,7 @@ SDLJoystick::SDLJoystick(bool init_SDL ) : registeredAsEventHandler(false) {
cout << "loading control pad mappings from " << dbPath << ": ";
size_t size;
u8 *mappingData = VFSReadFile(dbPath, &size);
u8 *mappingData = g_VFS.ReadFile(dbPath, &size);
if (mappingData) {
SDL_RWops *rw = SDL_RWFromConstMem(mappingData, size);
// 1 to free the rw after use

View File

@ -257,7 +257,7 @@ BackgroundAudio::~BackgroundAudio() {
BackgroundAudio::Sample *BackgroundAudio::LoadSample(const std::string &path) {
size_t bytes;
uint8_t *data = VFSReadFile(path.c_str(), &bytes);
uint8_t *data = g_VFS.ReadFile(path.c_str(), &bytes);
if (!data) {
return nullptr;
}

View File

@ -314,7 +314,7 @@ static bool ReadFileToString(IFileSystem *fs, const char *filename, std::string
static bool ReadVFSToString(const char *filename, std::string *contents, std::mutex *mtx) {
size_t sz;
uint8_t *data = VFSReadFile(filename, &sz);
uint8_t *data = g_VFS.ReadFile(filename, &sz);
if (data) {
if (mtx) {
std::lock_guard<std::mutex> lock(*mtx);

View File

@ -590,7 +590,7 @@ NewLanguageScreen::NewLanguageScreen(const std::string &title) : ListPopupScreen
auto &langValuesMapping = g_Config.GetLangValuesMapping();
std::vector<File::FileInfo> tempLangs;
VFSGetFileListing("lang", &tempLangs, "ini");
g_VFS.GetFileListing("lang", &tempLangs, "ini");
std::vector<std::string> listing;
int selected = -1;
int counter = 0;

View File

@ -467,27 +467,27 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
// We want this to be FIRST.
#if PPSSPP_PLATFORM(IOS) || PPSSPP_PLATFORM(MAC)
// Packed assets are included in app
VFSRegister("", new DirectoryAssetReader(Path(external_dir)));
g_VFS.Register("", new DirectoryAssetReader(Path(external_dir)));
#endif
#if defined(ASSETS_DIR)
VFSRegister("", new DirectoryAssetReader(Path(ASSETS_DIR)));
g_VFS.Register("", new DirectoryAssetReader(Path(ASSETS_DIR)));
#endif
#if !defined(MOBILE_DEVICE) && !defined(_WIN32) && !PPSSPP_PLATFORM(SWITCH)
VFSRegister("", new DirectoryAssetReader(File::GetExeDirectory() / "assets"));
VFSRegister("", new DirectoryAssetReader(File::GetExeDirectory()));
VFSRegister("", new DirectoryAssetReader(Path("/usr/local/share/ppsspp/assets")));
VFSRegister("", new DirectoryAssetReader(Path("/usr/local/share/games/ppsspp/assets")));
VFSRegister("", new DirectoryAssetReader(Path("/usr/share/ppsspp/assets")));
VFSRegister("", new DirectoryAssetReader(Path("/usr/share/games/ppsspp/assets")));
g_VFS.Register("", new DirectoryAssetReader(File::GetExeDirectory() / "assets"));
g_VFS.Register("", new DirectoryAssetReader(File::GetExeDirectory()));
g_VFS.Register("", new DirectoryAssetReader(Path("/usr/local/share/ppsspp/assets")));
g_VFS.Register("", new DirectoryAssetReader(Path("/usr/local/share/games/ppsspp/assets")));
g_VFS.Register("", new DirectoryAssetReader(Path("/usr/share/ppsspp/assets")));
g_VFS.Register("", new DirectoryAssetReader(Path("/usr/share/games/ppsspp/assets")));
#endif
#if PPSSPP_PLATFORM(SWITCH)
Path assetPath = Path(user_data_path) / "assets";
VFSRegister("", new DirectoryAssetReader(assetPath));
g_VFS.Register("", new DirectoryAssetReader(assetPath));
#else
VFSRegister("", new DirectoryAssetReader(Path("assets")));
g_VFS.Register("", new DirectoryAssetReader(Path("assets")));
#endif
VFSRegister("", new DirectoryAssetReader(Path(savegame_dir)));
g_VFS.Register("", new DirectoryAssetReader(Path(savegame_dir)));
#if (defined(MOBILE_DEVICE) || !defined(USING_QT_UI)) && !PPSSPP_PLATFORM(UWP)
if (host == nullptr) {
@ -777,7 +777,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
}
#elif defined(USING_QT_UI)
size_t fontSize = 0;
uint8_t *fontData = VFSReadFile("Roboto-Condensed.ttf", &fontSize);
uint8_t *fontData = g_VFS.ReadFile("Roboto-Condensed.ttf", &fontSize);
if (fontData) {
int fontID = QFontDatabase::addApplicationFontFromData(QByteArray((const char *)fontData, fontSize));
delete [] fontData;

View File

@ -84,7 +84,7 @@ static void LoadThemeInfo(const std::vector<Path> &directories) {
for (size_t d = 0; d < directories.size(); d++) {
std::vector<File::FileInfo> fileInfo;
VFSGetFileListing(directories[d].c_str(), &fileInfo, "ini:");
g_VFS.GetFileListing(directories[d].c_str(), &fileInfo, "ini:");
if (fileInfo.empty()) {
File::GetFilesInDir(directories[d], &fileInfo, "ini:");
@ -138,7 +138,7 @@ static void LoadThemeInfo(const std::vector<Path> &directories) {
tmpPath = (path / tmpPath).ToString();
File::FileInfo tmpInfo;
if (VFSGetFileInfo((tmpPath+".meta").c_str(), &tmpInfo) && VFSGetFileInfo((tmpPath+".zim").c_str(), &tmpInfo)) {
if (g_VFS.GetFileInfo((tmpPath + ".meta").c_str(), &tmpInfo) && g_VFS.GetFileInfo((tmpPath + ".zim").c_str(), &tmpInfo)) {
info.sUIAtlas = tmpPath;
}
}
@ -158,7 +158,7 @@ static UI::Style MakeStyle(uint32_t fg, uint32_t bg) {
static void LoadAtlasMetadata(Atlas &metadata, const char *filename, bool required) {
size_t atlas_data_size = 0;
const uint8_t *atlas_data = VFSReadFile(filename, &atlas_data_size);
const uint8_t *atlas_data = g_VFS.ReadFile(filename, &atlas_data_size);
bool load_success = atlas_data != nullptr && metadata.Load(atlas_data, atlas_data_size);
if (!load_success) {
if (required)

View File

@ -76,8 +76,8 @@ PPSSPP_UWPMain::PPSSPP_UWPMain(App ^app, const std::shared_ptr<DX::DeviceResourc
ctx_.reset(new UWPGraphicsContext(deviceResources));
const Path &exePath = File::GetExeDirectory();
VFSRegister("", new DirectoryAssetReader(exePath / "Content"));
VFSRegister("", new DirectoryAssetReader(exePath));
g_VFS.Register("", new DirectoryAssetReader(exePath / "Content"));
g_VFS.Register("", new DirectoryAssetReader(exePath));
wchar_t lcCountry[256];
@ -135,6 +135,7 @@ PPSSPP_UWPMain::~PPSSPP_UWPMain() {
ctx_->GetDrawContext()->HandleEvent(Draw::Event::LOST_BACKBUFFER, 0, 0, nullptr);
NativeShutdownGraphics();
NativeShutdown();
g_VFS.Clear();
// Deregister device notification
m_deviceResources->RegisterDeviceNotify(nullptr);

View File

@ -583,8 +583,8 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
#endif
const Path &exePath = File::GetExeDirectory();
VFSRegister("", new DirectoryAssetReader(exePath / "assets"));
VFSRegister("", new DirectoryAssetReader(exePath));
g_VFS.Register("", new DirectoryAssetReader(exePath / "assets"));
g_VFS.Register("", new DirectoryAssetReader(exePath));
langRegion = GetDefaultLangRegion();
osName = GetWindowsVersion() + " " + GetWindowsSystemArchitecture();
@ -796,7 +796,7 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
}
}
VFSShutdown();
g_VFS.Clear();
MainWindow::DestroyDebugWindows();
DialogManager::DestroyAll();

View File

@ -695,7 +695,7 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init
deviceType = jdeviceType;
std::string apkPath = GetJavaString(env, japkpath);
VFSRegister("", new ZipAssetReader(apkPath.c_str(), "assets/"));
g_VFS.Register("", new ZipAssetReader(apkPath.c_str(), "assets/"));
systemName = GetJavaString(env, jmodel);
langRegion = GetJavaString(env, jlangRegion);
@ -907,7 +907,7 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_shutdown(JNIEnv *, jclass) {
std::lock_guard<std::mutex> guard(renderLock);
inputBoxCallbacks.clear();
NativeShutdown();
VFSShutdown();
g_VFS.Clear();
}
{

View File

@ -482,13 +482,13 @@ int main(int argc, const char* argv[])
#if PPSSPP_PLATFORM(ANDROID)
// For some reason the debugger installs it with this name?
if (File::Exists(Path("/data/app/org.ppsspp.ppsspp-2.apk"))) {
VFSRegister("", new ZipAssetReader("/data/app/org.ppsspp.ppsspp-2.apk", "assets/"));
g_VFS.Register("", new ZipAssetReader("/data/app/org.ppsspp.ppsspp-2.apk", "assets/"));
}
if (File::Exists(Path("/data/app/org.ppsspp.ppsspp.apk"))) {
VFSRegister("", new ZipAssetReader("/data/app/org.ppsspp.ppsspp.apk", "assets/"));
g_VFS.Register("", new ZipAssetReader("/data/app/org.ppsspp.ppsspp.apk", "assets/"));
}
#elif !PPSSPP_PLATFORM(WINDOWS)
VFSRegister("", new DirectoryAssetReader(g_Config.flash0Directory / ".."));
g_VFS.Register("", new DirectoryAssetReader(g_Config.flash0Directory / ".."));
#endif
UpdateUIState(UISTATE_INGAME);
@ -557,7 +557,7 @@ int main(int argc, const char* argv[])
host = nullptr;
headlessHost = nullptr;
VFSShutdown();
g_VFS.Clear();
LogManager::Shutdown();
delete printfLogger;

View File

@ -100,9 +100,9 @@ private:
};
void SDLHeadlessHost::LoadNativeAssets() {
VFSRegister("", new DirectoryAssetReader(Path("assets")));
VFSRegister("", new DirectoryAssetReader(Path("")));
VFSRegister("", new DirectoryAssetReader(Path("..")));
g_VFS.Register("", new DirectoryAssetReader(Path("assets")));
g_VFS.Register("", new DirectoryAssetReader(Path("")));
g_VFS.Register("", new DirectoryAssetReader(Path("..")));
}
bool GLDummyGraphicsContext::InitFromRenderThread(std::string *errorMessage) {

View File

@ -68,11 +68,11 @@ HWND CreateHiddenWindow() {
void WindowsHeadlessHost::LoadNativeAssets()
{
VFSRegister("", new DirectoryAssetReader(Path("assets")));
VFSRegister("", new DirectoryAssetReader(Path("")));
VFSRegister("", new DirectoryAssetReader(Path("..")));
VFSRegister("", new DirectoryAssetReader(Path("../Windows/assets")));
VFSRegister("", new DirectoryAssetReader(Path("../Windows")));
g_VFS.Register("", new DirectoryAssetReader(Path("assets")));
g_VFS.Register("", new DirectoryAssetReader(Path("")));
g_VFS.Register("", new DirectoryAssetReader(Path("..")));
g_VFS.Register("", new DirectoryAssetReader(Path("../Windows/assets")));
g_VFS.Register("", new DirectoryAssetReader(Path("../Windows")));
}
void WindowsHeadlessHost::SendDebugOutput(const std::string &output)

View File

@ -1284,7 +1284,7 @@ void retro_init(void)
g_Config.bEnableNetworkChat = false;
g_Config.bDiscordPresence = false;
VFSRegister("", new DirectoryAssetReader(retro_base_dir));
g_VFS.Register("", new DirectoryAssetReader(retro_base_dir));
host = new LibretroHost();
}
@ -1486,7 +1486,7 @@ void retro_unload_game(void)
Libretro::EmuThreadStop();
PSP_Shutdown();
VFSShutdown();
g_VFS.Clear();
delete ctx;
ctx = nullptr;