diff --git a/src/core/file_sys/fs.cpp b/src/core/file_sys/fs.cpp index 7b8902086..e2a2f89b1 100644 --- a/src/core/file_sys/fs.cpp +++ b/src/core/file_sys/fs.cpp @@ -9,8 +9,6 @@ namespace Core::FileSys { -bool MntPoints::ignore_game_patches = false; - void MntPoints::Mount(const std::filesystem::path& host_folder, const std::string& guest_folder, bool read_only) { std::scoped_lock lock{m_mutex}; @@ -69,10 +67,10 @@ std::filesystem::path MntPoints::GetHostPath(std::string_view path, bool* is_rea } patch_path /= rel_path; - if ((corrected_path.starts_with("/app0") || corrected_path.starts_with("/hostapp")) && - !force_base_path && !ignore_game_patches && std::filesystem::exists(patch_path)) { - return patch_path; - } + // if ((corrected_path.starts_with("/app0") || corrected_path.starts_with("/hostapp")) && + // !force_base_path && !ignore_game_patches && std::filesystem::exists(patch_path)) { + // return patch_path; + // } if (!NeedsCaseInsensitiveSearch) { return host_path; @@ -130,11 +128,11 @@ std::filesystem::path MntPoints::GetHostPath(std::string_view path, bool* is_rea return std::optional(current_path); }; - if (!force_base_path && !ignore_game_patches) { - if (const auto path = search(patch_path)) { - return *path; - } - } + // if (!force_base_path && !ignore_game_patches) { + // if (const auto path = search(patch_path)) { + // return *path; + // } + // } if (const auto path = search(host_path)) { return *path; } diff --git a/src/core/file_sys/quasifs/src/quasifs_partition.cpp b/src/core/file_sys/quasifs/src/quasifs_partition.cpp index 8a7e5e838..8a782f6d4 100644 --- a/src/core/file_sys/quasifs/src/quasifs_partition.cpp +++ b/src/core/file_sys/quasifs/src/quasifs_partition.cpp @@ -1,6 +1,7 @@ // INAA License @marecl 2025 #include "common/logging/log.h" +// #include "common/string_util.h" #include "../quasi_errno.h" #include "../quasi_types.h" @@ -50,6 +51,29 @@ int Partition::GetHostPath(fs::path& output_path, const fs::path& local_path) { return -QUASI_EACCES; } output_path = host_path_target_sanitized; + + // #ifdef _WIN32 + // // Windows is case insensitive + // output_path = host_path_target_sanitized; + // #endif + + // fs::path current_path{}; + // for (auto part : host_path_target_sanitized) { + // fs::path tmp = Common::ToLower(part.string()); + // if (!fs::exists(tmp)) + // continue; + // current_path /= tmp; + // } + + // if (fs::equivalent(current_path, host_path_target_sanitized)) { + // output_path = current_path; + // return 0; + // } + + // output_path = ""; + // LOG_ERROR(Kernel_Fs, "Resolving [{}] to host's [{}] failed", local_path.string(), + // host_path_target_sanitized.string()); + // Log("Resolving local {} to {}", local_path.string(), host_path_target_sanitized.string()); return 0; } diff --git a/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp b/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp index 900aa0a18..609fb40f1 100644 --- a/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp +++ b/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp @@ -719,9 +719,10 @@ int QFS::OperationImpl::Stat(const fs::path& path, Libraries::Kernel::OrbisKerne hostpath_status != 0) return hostpath_status; - if (hio_status = qfs.hio_driver.Stat(host_path_target, &hio_stat); 0 != hio_status) + if (hio_status = qfs.hio_driver.Stat(host_path_target, &hio_stat); 0 != hio_status) { // hosts operation must succeed in order to continue return hio_status; + } host_used = true; } diff --git a/src/emulator.cpp b/src/emulator.cpp index 935ae3551..aced2fc36 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -63,6 +63,8 @@ namespace qfs = QuasiFS; namespace Core { +bool Emulator::ignore_game_patches = false; + Emulator::Emulator() { // Initialize NT API functions and set high priority #ifdef _WIN32 @@ -77,7 +79,7 @@ Emulator::Emulator() { Emulator::~Emulator() {} -void Emulator::LoadFilesystem(const std::filesystem::path& game_folder, const std::string& id) { +void Emulator::LoadFilesystem(const std::string& id) { const auto& mount_data_dir = Common::FS::GetUserPath(Common::FS::PathType::GameDataDir) / id; if (!std::filesystem::exists(mount_data_dir)) { std::filesystem::create_directory(mount_data_dir); @@ -98,31 +100,22 @@ void Emulator::LoadFilesystem(const std::filesystem::path& game_folder, const st qfs->Operation.Chmod("/", 0777); qfs::partition_ptr partition_av_contents = qfs::Partition::Create("", 0775, 512, 16384); - qfs::partition_ptr partition_av_contents_photo = - qfs::Partition::Create("", 0755, 4096, 32768); - qfs::partition_ptr partition_av_contents_thumbs = - qfs::Partition::Create("", 0755, 4096, 32768); - qfs::partition_ptr partition_av_contents_video = - qfs::Partition::Create("", 0755, 4096, 32768); + qfs::partition_ptr partition_av_contents_photo = qfs::Partition::Create("", 0755, 4096, 32768); + qfs::partition_ptr partition_av_contents_thumbs = qfs::Partition::Create("", 0755, 4096, 32768); + qfs::partition_ptr partition_av_contents_video = qfs::Partition::Create("", 0755, 4096, 32768); - qfs::partition_ptr partition_app0 = - qfs::Partition::Create(game_folder, 0555, 512, 65536); - qfs::partition_ptr partition_data = - qfs::Partition::Create(mount_data_dir, 0777, 4096, 32768); + qfs::partition_ptr partition_data = qfs::Partition::Create(mount_data_dir, 0777, 4096, 32768); qfs::partition_ptr partition_dev = qfs::Partition::Create("", 0755, 16384, 16384); // no idea what are the block sizes for these 3 qfs::partition_ptr partition_download = qfs::Partition::Create(mount_download_dir, 0777, 512, 65536); - qfs::partition_ptr partition_hostapp = - qfs::Partition::Create(game_folder, 0777, 2048, 16384); - qfs::partition_ptr partition_temp = - qfs::Partition::Create(mount_temp_dir, 0777, 512, 16384); + + qfs::partition_ptr partition_temp = qfs::Partition::Create(mount_temp_dir, 0777, 512, 16384); qfs->Operation.MKDir("/av_contents", 0775); qfs->Operation.MKDir("/av_contents/photo", 0755); qfs->Operation.MKDir("/av_contents/thumbnails", 0755); qfs->Operation.MKDir("/av_contents/video", 0755); - qfs->Operation.MKDir("/app0", 0555); qfs->Operation.MKDir("/data", 0777); qfs->Operation.MKDir("/dev", 0555); qfs->Operation.MKDir("/download0", 0777); // not sure about perms here @@ -136,12 +129,10 @@ void Emulator::LoadFilesystem(const std::filesystem::path& game_folder, const st qfs::MountOptions::MOUNT_RW); qfs->Mount("/av_contents/video", partition_av_contents_video, qfs::MountOptions::MOUNT_RW); - qfs->Mount("/app0", partition_app0, qfs::MountOptions::MOUNT_NOOPT); qfs->Mount("/data", partition_data, qfs::MountOptions::MOUNT_RW); qfs->Mount("/dev", partition_dev, qfs::MountOptions::MOUNT_RW); qfs->Mount("/download0", partition_download, qfs::MountOptions::MOUNT_RW); - // qfs->Mount("/hostapp", partition_hostapp, - // qfs::MountOptions::MOUNT_NOOPT | qfs::MountOptions::MOUNT_BIND); + qfs->Mount("/temp", partition_temp, qfs::MountOptions::MOUNT_RW); qfs->Mount("/temp0", partition_temp, qfs::MountOptions::MOUNT_RW | qfs::MountOptions::MOUNT_BIND); @@ -222,7 +213,22 @@ void Emulator::Run(std::filesystem::path file, const std::vector ar // Certain games may use /hostapp as well such as CUSA001100 mnt->Mount(game_folder, "/hostapp", true); - const auto param_sfo_path = mnt->GetHostPath("/app0/sce_sys/param.sfo"); + auto* qfs = Common::Singleton::Instance(); + qfs->Operation.MKDir("/app0", 0555); + qfs::partition_ptr partition_app0 = qfs::Partition::Create(game_folder, 0555, 512, 65536); + + qfs->Mount("/app0", partition_app0, qfs::MountOptions::MOUNT_NOOPT); + qfs->Mount("/hostapp", partition_app0, + qfs::MountOptions::MOUNT_NOOPT | qfs::MountOptions::MOUNT_BIND); + + // can't sync here, otherwise all mountpoints would need to be updated one by one + std::filesystem::path param_sfo_path{}; + { + qfs::Resolved res{}; + int status = qfs->Resolve("/app0", res); + // DON'T do this normally. This is init, anything goes + res.mountpoint->GetHostPath(param_sfo_path, "/sce_sys/param.sfo"); + } const auto param_sfo_exists = std::filesystem::exists(param_sfo_path); // Load param.sfo details if it exists @@ -232,24 +238,28 @@ void Emulator::Run(std::filesystem::path file, const std::vector ar u32 fw_version; Common::PSFAttributes psf_attributes{}; - if (param_sfo_exists) { - auto* param_sfo = Common::Singleton::Instance(); - ASSERT_MSG(param_sfo->Open(param_sfo_path), "Failed to open param.sfo"); + // There is no valid dump without this file ~shrug~ + if (!param_sfo_exists) + UNREACHABLE_MSG("Failed to access param.sfo"); - const auto content_id = param_sfo->GetString("CONTENT_ID"); - const auto title_id = param_sfo->GetString("TITLE_ID"); - if (content_id.has_value() && !content_id->empty()) { - id = std::string(*content_id, 7, 9); - } else if (title_id.has_value()) { - id = *title_id; - } - title = param_sfo->GetString("TITLE").value_or("Unknown title"); - fw_version = param_sfo->GetInteger("SYSTEM_VER").value_or(0x4700000); - app_version = param_sfo->GetString("APP_VER").value_or("Unknown version"); - if (const auto raw_attributes = param_sfo->GetInteger("ATTRIBUTE")) { - psf_attributes.raw = *raw_attributes; - } + auto* param_sfo = Common::Singleton::Instance(); + ASSERT_MSG(param_sfo->Open(param_sfo_path), "Failed to open param.sfo"); + + const auto content_id = param_sfo->GetString("CONTENT_ID"); + const auto title_id = param_sfo->GetString("TITLE_ID"); + if (content_id.has_value() && !content_id->empty()) { + id = std::string(*content_id, 7, 9); + } else if (title_id.has_value()) { + id = *title_id; } + title = param_sfo->GetString("TITLE").value_or("Unknown title"); + fw_version = param_sfo->GetInteger("SYSTEM_VER").value_or(0x4700000); + app_version = param_sfo->GetString("APP_VER").value_or("Unknown version"); + if (const auto raw_attributes = param_sfo->GetInteger("ATTRIBUTE")) { + psf_attributes.raw = *raw_attributes; + } + + this->LoadFilesystem(id); Config::load(Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) / (id + ".toml"), true); @@ -325,8 +335,6 @@ void Emulator::Run(std::filesystem::path file, const std::vector ar } } - this->LoadFilesystem(game_folder, id); - // Initialize components memory = Core::Memory::Instance(); controller = Common::Singleton::Instance(); diff --git a/src/emulator.h b/src/emulator.h index 079bfb46f..07a983f12 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -28,9 +28,11 @@ public: void Run(std::filesystem::path file, const std::vector args = {}); void UpdatePlayTime(const std::string& serial); + static bool ignore_game_patches; + private: void LoadSystemModules(const std::string& game_serial); - void LoadFilesystem(const std::filesystem::path& game_folder, const std::string& id); + void LoadFilesystem(const std::string& id); Core::MemoryManager* memory; Input::GameController* controller; diff --git a/src/qt_gui/main.cpp b/src/qt_gui/main.cpp index b7de517e8..9f7bbb8a6 100644 --- a/src/qt_gui/main.cpp +++ b/src/qt_gui/main.cpp @@ -7,7 +7,6 @@ #include "common/config.h" #include "common/memory_patcher.h" -#include "core/file_sys/fs.h" #include "emulator.h" #include "game_install_dialog.h" #include "main_window.h" @@ -86,7 +85,7 @@ int main(int argc, char* argv[]) { } }}, {"--patch", [&](int& i) { arg_map["-p"](i); }}, - {"-i", [&](int&) { Core::FileSys::MntPoints::ignore_game_patches = true; }}, + {"-i", [&](int&) { Core::Emulator::ignore_game_patches = true; }}, {"--ignore-game-patch", [&](int& i) { arg_map["-i"](i); }}, {"-f", [&](int& i) { diff --git a/src/qt_gui/main_window.h b/src/qt_gui/main_window.h index 5b880c15e..cee0a98b9 100644 --- a/src/qt_gui/main_window.h +++ b/src/qt_gui/main_window.h @@ -13,7 +13,6 @@ #include "common/path_util.h" #include "compatibility_info.h" #include "core/file_format/psf.h" -#include "core/file_sys/fs.h" #include "elf_viewer.h" #include "emulator.h" #include "game_grid_frame.h"