mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-11-04 20:44:02 +08:00 
			
		
		
		
	core: Port core to VfsFilesystem for file access
This commit is contained in:
		
							parent
							
								
									aaa8fdea52
								
							
						
					
					
						commit
						4b471f0554
					
				@ -89,7 +89,7 @@ System::ResultStatus System::SingleStep() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& filepath) {
 | 
			
		||||
    app_loader = Loader::GetLoader(std::make_shared<FileSys::RealVfsFile>(filepath));
 | 
			
		||||
    app_loader = Loader::GetLoader(virtual_filesystem->OpenFile(filepath, FileSys::Mode::Read));
 | 
			
		||||
 | 
			
		||||
    if (!app_loader) {
 | 
			
		||||
        LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
 | 
			
		||||
@ -174,6 +174,10 @@ System::ResultStatus System::Init(EmuWindow& emu_window) {
 | 
			
		||||
 | 
			
		||||
    CoreTiming::Init();
 | 
			
		||||
 | 
			
		||||
    // Create a default fs if one doesn't already exist.
 | 
			
		||||
    if (virtual_filesystem == nullptr)
 | 
			
		||||
        virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>();
 | 
			
		||||
 | 
			
		||||
    current_process = Kernel::Process::Create("main");
 | 
			
		||||
 | 
			
		||||
    cpu_barrier = std::make_shared<CpuBarrier>();
 | 
			
		||||
@ -186,7 +190,7 @@ System::ResultStatus System::Init(EmuWindow& emu_window) {
 | 
			
		||||
    service_manager = std::make_shared<Service::SM::ServiceManager>();
 | 
			
		||||
 | 
			
		||||
    Kernel::Init();
 | 
			
		||||
    Service::Init(service_manager);
 | 
			
		||||
    Service::Init(service_manager, virtual_filesystem);
 | 
			
		||||
    GDBStub::Init();
 | 
			
		||||
 | 
			
		||||
    renderer = VideoCore::CreateRenderer(emu_window);
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,8 @@
 | 
			
		||||
#include "core/memory.h"
 | 
			
		||||
#include "core/perf_stats.h"
 | 
			
		||||
#include "core/telemetry_session.h"
 | 
			
		||||
#include "file_sys/vfs_real.h"
 | 
			
		||||
#include "hle/service/filesystem/filesystem.h"
 | 
			
		||||
#include "video_core/debug_utils/debug_utils.h"
 | 
			
		||||
#include "video_core/gpu.h"
 | 
			
		||||
 | 
			
		||||
@ -211,6 +213,14 @@ public:
 | 
			
		||||
        return debug_context;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void SetFilesystem(FileSys::VirtualFilesystem vfs) {
 | 
			
		||||
        virtual_filesystem = std::move(vfs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    FileSys::VirtualFilesystem GetFilesystem() const {
 | 
			
		||||
        return virtual_filesystem;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    System();
 | 
			
		||||
 | 
			
		||||
@ -225,6 +235,8 @@ private:
 | 
			
		||||
     */
 | 
			
		||||
    ResultStatus Init(EmuWindow& emu_window);
 | 
			
		||||
 | 
			
		||||
    /// RealVfsFilesystem instance
 | 
			
		||||
    FileSys::VirtualFilesystem virtual_filesystem;
 | 
			
		||||
    /// AppLoader used to load the current executing application
 | 
			
		||||
    std::unique_ptr<Loader::AppLoader> app_loader;
 | 
			
		||||
    std::unique_ptr<VideoCore::RendererBase> renderer;
 | 
			
		||||
 | 
			
		||||
@ -281,15 +281,15 @@ ResultVal<FileSys::VirtualDir> OpenSDMC() {
 | 
			
		||||
    return sdmc_factory->Open();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RegisterFileSystems() {
 | 
			
		||||
void RegisterFileSystems(const FileSys::VirtualFilesystem& vfs) {
 | 
			
		||||
    romfs_factory = nullptr;
 | 
			
		||||
    save_data_factory = nullptr;
 | 
			
		||||
    sdmc_factory = nullptr;
 | 
			
		||||
 | 
			
		||||
    auto nand_directory = std::make_shared<FileSys::RealVfsDirectory>(
 | 
			
		||||
        FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), FileSys::Mode::ReadWrite);
 | 
			
		||||
    auto sd_directory = std::make_shared<FileSys::RealVfsDirectory>(
 | 
			
		||||
        FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), FileSys::Mode::ReadWrite);
 | 
			
		||||
    auto nand_directory = vfs->OpenDirectory(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir),
 | 
			
		||||
                                             FileSys::Mode::ReadWrite);
 | 
			
		||||
    auto sd_directory = vfs->OpenDirectory(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir),
 | 
			
		||||
                                           FileSys::Mode::ReadWrite);
 | 
			
		||||
 | 
			
		||||
    auto savedata = std::make_unique<FileSys::SaveDataFactory>(std::move(nand_directory));
 | 
			
		||||
    save_data_factory = std::move(savedata);
 | 
			
		||||
@ -298,8 +298,8 @@ void RegisterFileSystems() {
 | 
			
		||||
    sdmc_factory = std::move(sdcard);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
 | 
			
		||||
    RegisterFileSystems();
 | 
			
		||||
void InstallInterfaces(SM::ServiceManager& service_manager, const FileSys::VirtualFilesystem& vfs) {
 | 
			
		||||
    RegisterFileSystems(vfs);
 | 
			
		||||
    std::make_shared<FSP_LDR>()->InstallAsService(service_manager);
 | 
			
		||||
    std::make_shared<FSP_PR>()->InstallAsService(service_manager);
 | 
			
		||||
    std::make_shared<FSP_SRV>()->InstallAsService(service_manager);
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@ ResultVal<FileSys::VirtualDir> OpenSDMC();
 | 
			
		||||
// ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenBIS();
 | 
			
		||||
 | 
			
		||||
/// Registers all Filesystem services with the specified service manager.
 | 
			
		||||
void InstallInterfaces(SM::ServiceManager& service_manager);
 | 
			
		||||
void InstallInterfaces(SM::ServiceManager& service_manager, const FileSys::VirtualFilesystem& vfs);
 | 
			
		||||
 | 
			
		||||
// A class that wraps a VfsDirectory with methods that return ResultVal and ResultCode instead of
 | 
			
		||||
// pointers and booleans. This makes using a VfsDirectory with switch services much easier and
 | 
			
		||||
 | 
			
		||||
@ -198,7 +198,7 @@ void AddNamedPort(std::string name, SharedPtr<ClientPort> port) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Initialize ServiceManager
 | 
			
		||||
void Init(std::shared_ptr<SM::ServiceManager>& sm) {
 | 
			
		||||
void Init(std::shared_ptr<SM::ServiceManager>& sm, const FileSys::VirtualFilesystem& rfs) {
 | 
			
		||||
    // NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it
 | 
			
		||||
    // here and pass it into the respective InstallInterfaces functions.
 | 
			
		||||
    auto nv_flinger = std::make_shared<NVFlinger::NVFlinger>();
 | 
			
		||||
@ -221,7 +221,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
 | 
			
		||||
    EUPLD::InstallInterfaces(*sm);
 | 
			
		||||
    Fatal::InstallInterfaces(*sm);
 | 
			
		||||
    FGM::InstallInterfaces(*sm);
 | 
			
		||||
    FileSystem::InstallInterfaces(*sm);
 | 
			
		||||
    FileSystem::InstallInterfaces(*sm, rfs);
 | 
			
		||||
    Friend::InstallInterfaces(*sm);
 | 
			
		||||
    GRC::InstallInterfaces(*sm);
 | 
			
		||||
    HID::InstallInterfaces(*sm);
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,10 @@ class ServerSession;
 | 
			
		||||
class HLERequestContext;
 | 
			
		||||
} // namespace Kernel
 | 
			
		||||
 | 
			
		||||
namespace FileSys {
 | 
			
		||||
struct VfsFilesystem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Service {
 | 
			
		||||
 | 
			
		||||
namespace SM {
 | 
			
		||||
@ -177,7 +181,8 @@ private:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Initialize ServiceManager
 | 
			
		||||
void Init(std::shared_ptr<SM::ServiceManager>& sm);
 | 
			
		||||
void Init(std::shared_ptr<SM::ServiceManager>& sm,
 | 
			
		||||
          const std::shared_ptr<FileSys::VfsFilesystem>& vfs);
 | 
			
		||||
 | 
			
		||||
/// Shutdown ServiceManager
 | 
			
		||||
void Shutdown();
 | 
			
		||||
 | 
			
		||||
@ -197,7 +197,8 @@ void GameList::onFilterCloseClicked() {
 | 
			
		||||
    main_window->filterBarSetChecked(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GameList::GameList(GMainWindow* parent) : QWidget{parent} {
 | 
			
		||||
GameList::GameList(FileSys::VirtualFilesystem vfs, GMainWindow* parent)
 | 
			
		||||
    : QWidget{parent}, vfs(std::move(vfs)) {
 | 
			
		||||
    watcher = new QFileSystemWatcher(this);
 | 
			
		||||
    connect(watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory);
 | 
			
		||||
 | 
			
		||||
@ -341,7 +342,7 @@ void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) {
 | 
			
		||||
 | 
			
		||||
    emit ShouldCancelWorker();
 | 
			
		||||
 | 
			
		||||
    GameListWorker* worker = new GameListWorker(dir_path, deep_scan);
 | 
			
		||||
    GameListWorker* worker = new GameListWorker(vfs, dir_path, deep_scan);
 | 
			
		||||
 | 
			
		||||
    connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection);
 | 
			
		||||
    connect(worker, &GameListWorker::Finished, this, &GameList::DonePopulating,
 | 
			
		||||
@ -436,7 +437,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
 | 
			
		||||
        if (!is_dir &&
 | 
			
		||||
            (HasSupportedFileExtension(physical_name) || IsExtractedNCAMain(physical_name))) {
 | 
			
		||||
            std::unique_ptr<Loader::AppLoader> loader =
 | 
			
		||||
                Loader::GetLoader(std::make_shared<FileSys::RealVfsFile>(physical_name));
 | 
			
		||||
                Loader::GetLoader(vfs->OpenFile(physical_name, FileSys::Mode::Read));
 | 
			
		||||
            if (!loader || ((loader->GetFileType() == Loader::FileType::Unknown ||
 | 
			
		||||
                             loader->GetFileType() == Loader::FileType::Error) &&
 | 
			
		||||
                            !UISettings::values.show_unknown))
 | 
			
		||||
 | 
			
		||||
@ -59,7 +59,7 @@ public:
 | 
			
		||||
        QToolButton* button_filter_close = nullptr;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    explicit GameList(GMainWindow* parent = nullptr);
 | 
			
		||||
    explicit GameList(FileSys::VirtualFilesystem vfs, GMainWindow* parent = nullptr);
 | 
			
		||||
    ~GameList() override;
 | 
			
		||||
 | 
			
		||||
    void clearFilter();
 | 
			
		||||
@ -90,6 +90,7 @@ private:
 | 
			
		||||
    void PopupContextMenu(const QPoint& menu_location);
 | 
			
		||||
    void RefreshGameDirectory();
 | 
			
		||||
 | 
			
		||||
    FileSys::VirtualFilesystem vfs;
 | 
			
		||||
    SearchField* search_field;
 | 
			
		||||
    GMainWindow* main_window = nullptr;
 | 
			
		||||
    QVBoxLayout* layout = nullptr;
 | 
			
		||||
 | 
			
		||||
@ -139,7 +139,7 @@ class GameListWorker : public QObject, public QRunnable {
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    GameListWorker(QString dir_path, bool deep_scan)
 | 
			
		||||
    GameListWorker(FileSys::VirtualFilesystem vfs, QString dir_path, bool deep_scan)
 | 
			
		||||
        : dir_path(std::move(dir_path)), deep_scan(deep_scan) {}
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
@ -163,6 +163,7 @@ signals:
 | 
			
		||||
    void Finished(QStringList watch_list);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    FileSys::VirtualFilesystem vfs;
 | 
			
		||||
    QStringList watch_list;
 | 
			
		||||
    QString dir_path;
 | 
			
		||||
    bool deep_scan;
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,7 @@
 | 
			
		||||
#include "common/string_util.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/crypto/key_manager.h"
 | 
			
		||||
#include "core/file_sys/vfs_real.h"
 | 
			
		||||
#include "core/gdbstub/gdbstub.h"
 | 
			
		||||
#include "core/loader/loader.h"
 | 
			
		||||
#include "core/settings.h"
 | 
			
		||||
@ -81,9 +82,9 @@ static void ShowCalloutMessage(const QString& message, CalloutFlag flag) {
 | 
			
		||||
 | 
			
		||||
void GMainWindow::ShowCallouts() {}
 | 
			
		||||
 | 
			
		||||
const int GMainWindow::max_recent_files_item;
 | 
			
		||||
 | 
			
		||||
GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
 | 
			
		||||
GMainWindow::GMainWindow()
 | 
			
		||||
    : config(new Config()), emu_thread(nullptr),
 | 
			
		||||
      vfs(std::make_shared<FileSys::RealVfsFilesystem>()) {
 | 
			
		||||
 | 
			
		||||
    debug_context = Tegra::DebugContext::Construct();
 | 
			
		||||
 | 
			
		||||
@ -132,7 +133,7 @@ void GMainWindow::InitializeWidgets() {
 | 
			
		||||
    render_window = new GRenderWindow(this, emu_thread.get());
 | 
			
		||||
    render_window->hide();
 | 
			
		||||
 | 
			
		||||
    game_list = new GameList(this);
 | 
			
		||||
    game_list = new GameList(vfs, this);
 | 
			
		||||
    ui.horizontalLayout->addWidget(game_list);
 | 
			
		||||
 | 
			
		||||
    // Create status bar
 | 
			
		||||
@ -406,6 +407,7 @@ bool GMainWindow::LoadROM(const QString& filename) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Core::System& system{Core::System::GetInstance()};
 | 
			
		||||
    system.SetFilesystem(vfs);
 | 
			
		||||
 | 
			
		||||
    system.SetGPUDebugContext(debug_context);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -161,6 +161,9 @@ private:
 | 
			
		||||
    bool emulation_running = false;
 | 
			
		||||
    std::unique_ptr<EmuThread> emu_thread;
 | 
			
		||||
 | 
			
		||||
    // FS
 | 
			
		||||
    FileSys::VirtualFilesystem vfs;
 | 
			
		||||
 | 
			
		||||
    // Debugger panes
 | 
			
		||||
    ProfilerWidget* profilerWidget;
 | 
			
		||||
    MicroProfileDialog* microProfileDialog;
 | 
			
		||||
 | 
			
		||||
@ -161,6 +161,7 @@ int main(int argc, char** argv) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Core::System& system{Core::System::GetInstance()};
 | 
			
		||||
    system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>());
 | 
			
		||||
 | 
			
		||||
    SCOPE_EXIT({ system.Shutdown(); });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user