diff --git a/Utilities/File.cpp b/Utilities/File.cpp index 10f57eef0e..d7b345ffe4 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -1125,11 +1125,22 @@ const std::string& fs::get_config_dir() // Use magic static static const std::string s_dir = [] { -#ifdef _WIN32 - return get_executable_dir(); // ? -#else std::string dir; +#ifdef _WIN32 + wchar_t buf[2048]; + if (GetModuleFileName(NULL, buf, ::size32(buf)) - 1 >= ::size32(buf) - 1) + { + MessageBoxA(0, fmt::format("GetModuleFileName() failed: error %u.", GetLastError()).c_str(), "fs::get_config_dir()", MB_ICONERROR); + return dir; // empty + } + + to_utf8(dir, buf); // Convert to UTF-8 + + std::replace(dir.begin(), dir.end(), '\\', '/'); + + dir.resize(dir.rfind('/') + 1); +#else if (const char* home = ::getenv("XDG_CONFIG_HOME")) dir = home; else if (const char* home = ::getenv("HOME")) @@ -1142,59 +1153,9 @@ const std::string& fs::get_config_dir() if (!is_dir(dir) && !create_path(dir)) { std::printf("Failed to create configuration directory '%s' (%d).\n", dir.c_str(), errno); - return get_executable_dir(); } - - return dir; #endif - }(); - return s_dir; -} - -const std::string& fs::get_executable_dir() -{ - // Use magic static - static const std::string s_dir = [] - { - std::string dir; - -#ifdef _WIN32 - wchar_t buf[2048]; - if (GetModuleFileName(NULL, buf, ::size32(buf)) - 1 >= ::size32(buf) - 1) - { - MessageBoxA(0, fmt::format("GetModuleFileName() failed: error %u.", GetLastError()).c_str(), "fs::get_executable_dir()", MB_ICONERROR); - return dir; // empty - } - - to_utf8(dir, buf); // Convert to UTF-8 - - std::replace(dir.begin(), dir.end(), '\\', '/'); - -#elif __APPLE__ - char buf[4096]; - u32 size = sizeof(buf); - if (_NSGetExecutablePath(buf, &size)) - { - std::printf("_NSGetExecutablePath() failed (size=0x%x).\n", size); - return dir; // empty - } - - dir = buf; -#else - char buf[4096]; - const auto size = ::readlink("/proc/self/exe", buf, sizeof(buf)); - if (size <= 0 || size >= sizeof(buf)) - { - std::printf("readlink(/proc/self/exe) failed (%d).\n", errno); - return dir; // empty - } - - dir.assign(buf, size); -#endif - - // Leave only path - dir.resize(dir.rfind('/') + 1); return dir; }(); diff --git a/Utilities/File.h b/Utilities/File.h index aa95c478e8..a92aabf861 100644 --- a/Utilities/File.h +++ b/Utilities/File.h @@ -444,9 +444,6 @@ namespace fs // Get configuration directory const std::string& get_config_dir(); - // Get executable directory - const std::string& get_executable_dir(); - // Get data/cache directory for specified prefix and suffix std::string get_data_dir(const std::string& prefix, const std::string& location, const std::string& suffix); diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index fe7bdfb43b..e4d86e41dc 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -38,11 +38,6 @@ namespace rsx { std::function g_access_violation_handler; - std::string old_shaders_cache::shaders_cache::path_to_root() - { - return fs::get_executable_dir() + "data/"; - } - void old_shaders_cache::shaders_cache::load(const std::string &path, shader_language lang) { const std::string lang_name(lang == shader_language::glsl ? "glsl" : "hlsl"); @@ -65,7 +60,6 @@ namespace rsx } catch (...) { - LOG_WARNING(RSX, "Cache file '%s' ignored", entry.name); continue; } @@ -87,17 +81,7 @@ namespace rsx void old_shaders_cache::shaders_cache::load(shader_language lang) { - std::string root = path_to_root(); - - //shared cache - load(root + "cache/", lang); - - std::string title_id = Emu.GetTitleID(); - - if (!title_id.empty()) - { - load(root + title_id + "/cache/", lang); - } + load(Emu.GetCachePath(), lang); } u32 get_address(u32 offset, u32 location) diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 4d2fc2ac10..e63fa3e2d1 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -99,8 +99,6 @@ namespace rsx void load(const std::string &path, shader_language lang); void load(shader_language lang); - - static std::string path_to_root(); }; } diff --git a/rpcs3/Emu/RSX/rsx_cache.cpp b/rpcs3/Emu/RSX/rsx_cache.cpp index 2ff2ecfafe..a7574da82e 100644 --- a/rpcs3/Emu/RSX/rsx_cache.cpp +++ b/rpcs3/Emu/RSX/rsx_cache.cpp @@ -90,23 +90,8 @@ namespace rsx programs_cache::programs_cache() { - std::string path{ fs::get_executable_dir() + "data/cache/" }; - std::string title = Emu.GetTitleID(); - - if (title.empty()) - { - path += "temporary/"; - fs::remove_all(path, false); - } - else - { - path += title + "/"; - } - - fs::create_path(path); - - m_vertex_shaders_cache.path(path); - m_fragment_shader_cache.path(path); + m_vertex_shaders_cache.path(Emu.GetCachePath()); + m_fragment_shader_cache.path(Emu.GetCachePath()); } programs_cache::~programs_cache() diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 79fe9b6f31..393d98cba1 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -30,7 +30,7 @@ system_type g_system; cfg::bool_entry g_cfg_autostart(cfg::root.misc, "Always start after boot", true); cfg::bool_entry g_cfg_autoexit(cfg::root.misc, "Exit RPCS3 when process finishes"); -cfg::string_entry g_cfg_vfs_emulator_dir(cfg::root.vfs, "$(EmulatorDir)"); // Default (empty): taken from fs::get_executable_dir() +cfg::string_entry g_cfg_vfs_emulator_dir(cfg::root.vfs, "$(EmulatorDir)"); // Default (empty): taken from fs::get_config_dir() cfg::string_entry g_cfg_vfs_dev_hdd0(cfg::root.vfs, "/dev_hdd0/", "$(EmulatorDir)dev_hdd0/"); cfg::string_entry g_cfg_vfs_dev_hdd1(cfg::root.vfs, "/dev_hdd1/", "$(EmulatorDir)dev_hdd1/"); cfg::string_entry g_cfg_vfs_dev_flash(cfg::root.vfs, "/dev_flash/", "$(EmulatorDir)dev_flash/"); @@ -131,7 +131,7 @@ bool Emulator::BootGame(const std::string& path, bool direct) std::string Emulator::GetGameDir() { const std::string& emu_dir_ = g_cfg_vfs_emulator_dir; - const std::string& emu_dir = emu_dir_.empty() ? fs::get_executable_dir() : emu_dir_; + const std::string& emu_dir = emu_dir_.empty() ? fs::get_config_dir() : emu_dir_; return fmt::replace_all(g_cfg_vfs_dev_hdd0, "$(EmulatorDir)", emu_dir) + "game/"; } @@ -139,7 +139,7 @@ std::string Emulator::GetGameDir() std::string Emulator::GetLibDir() { const std::string& emu_dir_ = g_cfg_vfs_emulator_dir; - const std::string& emu_dir = emu_dir_.empty() ? fs::get_executable_dir() : emu_dir_; + const std::string& emu_dir = emu_dir_.empty() ? fs::get_config_dir() : emu_dir_; return fmt::replace_all(g_cfg_vfs_dev_flash, "$(EmulatorDir)", emu_dir) + "sys/external/"; } @@ -173,12 +173,12 @@ void Emulator::Load() m_title_id = psf::get_string(_psf, "TITLE_ID"); // Initialize data/cache directory - const std::string data_dir = fs::get_data_dir(m_title_id, m_path); + m_cache_path = fs::get_data_dir(m_title_id, m_path); // Check SELF header if (elf_file.size() >= 4 && elf_file.read() == "SCE\0"_u32) { - const std::string decrypted_path = data_dir + "boot.elf"; + const std::string decrypted_path = m_cache_path + "boot.elf"; fs::stat_t encrypted_stat = elf_file.stat(); fs::stat_t decrypted_stat; @@ -201,13 +201,13 @@ void Emulator::Load() } else { - LOG_ERROR(LOADER, "Failed to create boot.elf", data_dir); + LOG_ERROR(LOADER, "Failed to create boot.elf"); } } } // Load custom config-1 - if (fs::file cfg_file{data_dir + "config.yml"}) + if (fs::file cfg_file{m_cache_path + "config.yml"}) { LOG_NOTICE(LOADER, "Applying custom config (config.yml)"); cfg::root.from_string(cfg_file.to_string()); @@ -248,7 +248,7 @@ void Emulator::Load() // Mount all devices const std::string& emu_dir_ = g_cfg_vfs_emulator_dir; - const std::string& emu_dir = emu_dir_.empty() ? fs::get_executable_dir() : emu_dir_; + const std::string& emu_dir = emu_dir_.empty() ? fs::get_config_dir() : emu_dir_; const std::string& bdvd_dir = g_cfg_vfs_dev_bdvd; const std::string& home_dir = g_cfg_vfs_app_home; diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 3f32210755..0bacd1487c 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -50,6 +50,7 @@ class Emulator final std::string m_path; std::string m_elf_path; + std::string m_cache_path; std::string m_title_id; std::string m_title; @@ -98,6 +99,11 @@ public: return m_title; } + const std::string& GetCachePath() const + { + return m_cache_path; + } + u64 GetPauseTime() { return m_pause_amend_time; diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 8dd34569aa..d7a22ed7ae 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -234,13 +234,10 @@ void MainFrame::BootGame(wxCommandEvent& WXUNUSED(event)) void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event)) { - const bool paused = Emu.Pause(); - wxFileDialog ctrl(this, L"Select PKG", wxEmptyString, wxEmptyString, "PKG files (*.pkg)|*.pkg|All files (*.*)|*.*", wxFD_OPEN | wxFD_FILE_MUST_EXIST); if (ctrl.ShowModal() == wxID_CANCEL) { - if (paused) Emu.Resume(); return; } @@ -372,6 +369,8 @@ void MainFrame::DecryptSPRXLibraries(wxCommandEvent& WXUNUSED(event)) return; } + Emu.Stop(); + wxArrayString modules; ctrl.GetPaths(modules); @@ -427,9 +426,12 @@ void MainFrame::InstallFirmware(wxCommandEvent& WXUNUSED(event)) return; } + Emu.Stop(); + fs::file pup_f(ctrl.GetPath().ToStdString()); pup_object pup(pup_f); - if (!pup) { + if (!pup) + { LOG_ERROR(GENERAL, "Error while installing firmware: PUP file is invalid."); wxMessageBox("Error while installing firmware: PUP file is invalid.", "Failure!", wxOK | wxICON_ERROR, this); return; @@ -440,7 +442,7 @@ void MainFrame::InstallFirmware(wxCommandEvent& WXUNUSED(event)) auto updatefilenames = update_files.get_filenames(); updatefilenames.erase(std::remove_if( - updatefilenames.begin(), updatefilenames.end(), [](std::string s) {return s.find("dev_flash_") == std::string::npos; }), + updatefilenames.begin(), updatefilenames.end(), [](std::string s) { return s.find("dev_flash_") == std::string::npos; }), updatefilenames.end()); wxProgressDialog pdlg("Firmware Installer", "Please wait, unpacking...", updatefilenames.size(), this, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT); @@ -470,7 +472,7 @@ void MainFrame::InstallFirmware(wxCommandEvent& WXUNUSED(event)) } tar_object dev_flash_tar(dev_flash_tar_f[2]); - if (!dev_flash_tar.extract(fs::get_executable_dir())) + if (!dev_flash_tar.extract(fs::get_config_dir())) { LOG_ERROR(GENERAL, "Error while installing firmware: TAR contents are invalid."); wxMessageBox("Error while installing firmware: TAR contents are invalid.", "Failure!", wxOK | wxICON_ERROR, this); diff --git a/rpcs3/Loader/PUP.cpp b/rpcs3/Loader/PUP.cpp index 161af8118d..9928251f84 100644 --- a/rpcs3/Loader/PUP.cpp +++ b/rpcs3/Loader/PUP.cpp @@ -6,8 +6,8 @@ pup_object::pup_object(const fs::file& file): m_file(file) { PUPHeader m_header; m_file.read(m_header); - if (m_header.magic != "SCEUF\0\0\0"_u64) - { + if (m_header.magic != "SCEUF\0\0\0"_u64) + { isValid = false; return; } @@ -22,7 +22,7 @@ fs::file pup_object::get_file(u64 entry_id) { if (!isValid) return fs::file(); - for (PUPFileEntry file_entry : m_file_tbl) + for (PUPFileEntry file_entry : m_file_tbl) { if (file_entry.entry_id == entry_id) { diff --git a/rpcs3/Loader/PUP.h b/rpcs3/Loader/PUP.h index 2e38ed591d..246ddb0e95 100644 --- a/rpcs3/Loader/PUP.h +++ b/rpcs3/Loader/PUP.h @@ -5,29 +5,33 @@ #include -typedef struct { +struct PUPHeader +{ le_t magic; be_t package_version; be_t image_version; be_t file_count; be_t header_length; be_t data_length; -} PUPHeader; +}; -typedef struct { +struct PUPFileEntry +{ be_t entry_id; be_t data_offset; be_t data_length; u8 padding[8]; -} PUPFileEntry; +}; -typedef struct { +struct PUPHashEntry +{ be_t entry_id; - be_t hash[20]; - be_t padding[4]; -} PUPHashEntry; + u8 hash[20]; + u8 padding[4]; +}; -class pup_object { +class pup_object +{ const fs::file& m_file; bool isValid = true; @@ -37,7 +41,7 @@ class pup_object { public: pup_object(const fs::file& file); - operator bool() const { return isValid; }; + explicit operator bool() const { return isValid; }; fs::file get_file(u64 entry_id); -}; \ No newline at end of file +}; diff --git a/rpcs3/Loader/TAR.cpp b/rpcs3/Loader/TAR.cpp index 58de2841cb..cc75a93066 100644 --- a/rpcs3/Loader/TAR.cpp +++ b/rpcs3/Loader/TAR.cpp @@ -5,7 +5,9 @@ #include #include -tar_object::tar_object(const fs::file& file, size_t offset) : m_file(file), initial_offset(offset) +tar_object::tar_object(const fs::file& file, size_t offset) + : m_file(file) + , initial_offset(offset) { m_file.seek(initial_offset); largest_offset = initial_offset; @@ -34,8 +36,6 @@ int octalToDecimal(int octalNumber) std::vector tar_object::get_filenames() { - if (!isValid) return std::vector(); - std::vector vec; get_file(""); for (auto it = m_map.cbegin(); it != m_map.cend(); ++it) @@ -47,7 +47,7 @@ std::vector tar_object::get_filenames() fs::file tar_object::get_file(std::string path) { - if (!isValid || !m_file) return fs::file(); + if (!m_file) return fs::file(); auto it = m_map.find(path); if (it != m_map.end()) @@ -62,9 +62,9 @@ fs::file tar_object::get_file(std::string path) } else //continue scanning from last file entered { - while (m_file.pos() < m_file.size()) { + while (m_file.pos() < m_file.size()) + { TARHeader header = read_header(largest_offset); - if (!isValid) return fs::file(); if (std::string(header.magic).find("ustar") != std::string::npos) m_map[header.name] = largest_offset; @@ -85,7 +85,7 @@ fs::file tar_object::get_file(std::string path) m_file.seek(offset); largest_offset = offset; } - } + } return fs::file(); } @@ -93,7 +93,7 @@ fs::file tar_object::get_file(std::string path) bool tar_object::extract(std::string path) { - if (!isValid || !m_file) return false; + if (!m_file) return false; get_file(""); //Make sure we have scanned all files for (auto iter : m_map) @@ -101,7 +101,8 @@ bool tar_object::extract(std::string path) TARHeader header = read_header(iter.second); if (std::string(header.name).empty()) continue; - switch (header.filetype) { + switch (header.filetype) + { case '0': { fs::file file(header.name, fs::rewrite); @@ -116,9 +117,9 @@ bool tar_object::extract(std::string path) } default: - LOG_ERROR(GENERAL,"Tar loader: unknown file type: "+header.filetype); + LOG_ERROR(GENERAL,"Tar loader: unknown file type: %c", header.filetype); return false; } } return true; -} \ No newline at end of file +} diff --git a/rpcs3/Loader/TAR.h b/rpcs3/Loader/TAR.h index c6e48f76fa..7a43afd218 100644 --- a/rpcs3/Loader/TAR.h +++ b/rpcs3/Loader/TAR.h @@ -2,7 +2,8 @@ #include -typedef struct { +struct TARHeader +{ char name[100]; char dontcare[24]; char size[12]; @@ -14,7 +15,7 @@ typedef struct { char dontcare2[82]; char prefix[155]; char padding[12]; -} TARHeader; +}; class tar_object { @@ -23,18 +24,15 @@ class tar_object int initial_offset; int largest_offset; //we store the largest offset so we can continue to scan from there. std::map m_map; //maps path to offset of header of that file, so we only need to scan the entire file once. - bool isValid = true; TARHeader read_header(u64 offset); public: tar_object(const fs::file& file, size_t offset = 0); - operator bool() const { return isValid; }; - std::vector get_filenames(); fs::file get_file(std::string path); bool extract(std::string path); // extract all files in archive to path -}; \ No newline at end of file +};