diff --git a/rpcs3/Crypto/unself.cpp b/rpcs3/Crypto/unself.cpp index 75675d3577..d989190b2e 100644 --- a/rpcs3/Crypto/unself.cpp +++ b/rpcs3/Crypto/unself.cpp @@ -3,6 +3,7 @@ #include "sha1.h" #include "utils.h" #include "unself.h" +#include "Emu/VFS.h" // TODO: Still reliant on wxWidgets for zlib functions. Alternative solutions? #include @@ -1390,30 +1391,22 @@ fs::file SELFDecrypter::MakeElf(bool isElf32) return e; } -bool SELFDecrypter::GetKeyFromRap(u8 *content_id, u8 *npdrm_key) +bool SELFDecrypter::GetKeyFromRap(u8* content_id, u8* npdrm_key) { // Set empty RAP key. u8 rap_key[0x10]; memset(rap_key, 0, 0x10); // Try to find a matching RAP file under exdata folder. - std::string ci_str((const char *)content_id); - std::string pf_str("00000001"); // TODO: Allow multiple profiles. Use default for now. - std::string rap_path("dev_hdd0/home/" + pf_str + "/exdata/" + ci_str + ".rap"); - - // Check if we have a valid RAP file. - if (!fs::is_file(rap_path)) - { - LOG_ERROR(LOADER, "This application requires a valid RAP file for decryption!"); - return false; - } + const std::string ci_str = reinterpret_cast(content_id); + const std::string rap_path = "/dev_hdd0/home/00000001/exdata/" + ci_str + ".rap"; // Open the RAP file and read the key. - fs::file rap_file(rap_path); + const fs::file rap_file(vfs::get(rap_path)); if (!rap_file) { - LOG_ERROR(LOADER, "Failed to load RAP file!"); + LOG_FATAL(LOADER, "Failed to load RAP file: %s", rap_path); return false; } diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 739aab8981..b8b2f6763d 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -194,8 +194,76 @@ void Emulator::Load() m_title = psf::get_string(_psf, "TITLE", m_path); m_title_id = psf::get_string(_psf, "TITLE_ID"); + LOG_NOTICE(LOADER, "Title: %s", GetTitle()); + LOG_NOTICE(LOADER, "Serial: %s", GetTitleID()); + // Initialize data/cache directory m_cache_path = fs::get_data_dir(m_title_id, m_path); + LOG_NOTICE(LOADER, "Cache: %s", GetCachePath()); + + // Load custom config-0 + if (fs::file cfg_file{m_cache_path + "/config.yml"}) + { + LOG_NOTICE(LOADER, "Applying custom config: %s/config.yml", m_cache_path); + cfg::root.from_string(cfg_file.to_string()); + } + + // Load custom config-1 + if (fs::file cfg_file{fs::get_config_dir() + "data/" + m_title_id + "/config.yml"}) + { + LOG_NOTICE(LOADER, "Applying custom config: data/%s/config.yml", m_title_id); + cfg::root.from_string(cfg_file.to_string()); + } + + // Load custom config-2 + if (fs::file cfg_file{m_path + ".yml"}) + { + LOG_NOTICE(LOADER, "Applying custom config: %s.yml", m_path); + cfg::root.from_string(cfg_file.to_string()); + } + + LOG_NOTICE(LOADER, "Used configuration:\n%s\n", cfg::root.to_string()); + + // Mount all devices + const std::string emu_dir_ = g_cfg_vfs_emulator_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; + + vfs::mount("dev_hdd0", fmt::replace_all(g_cfg_vfs_dev_hdd0, "$(EmulatorDir)", emu_dir)); + vfs::mount("dev_hdd1", fmt::replace_all(g_cfg_vfs_dev_hdd1, "$(EmulatorDir)", emu_dir)); + vfs::mount("dev_flash", fmt::replace_all(g_cfg_vfs_dev_flash, "$(EmulatorDir)", emu_dir)); + vfs::mount("dev_usb", fmt::replace_all(g_cfg_vfs_dev_usb000, "$(EmulatorDir)", emu_dir)); + vfs::mount("dev_usb000", fmt::replace_all(g_cfg_vfs_dev_usb000, "$(EmulatorDir)", emu_dir)); + vfs::mount("app_home", home_dir.empty() ? elf_dir + '/' : fmt::replace_all(home_dir, "$(EmulatorDir)", emu_dir)); + + // Mount /dev_bdvd/ if necessary + if (bdvd_dir.empty() && fs::is_file(elf_dir + "/../../PS3_DISC.SFB")) + { + const auto dir_list = fmt::split(elf_dir, { "/", "\\" }); + + // Check latest two directories + if (dir_list.size() >= 2 && dir_list.back() == "USRDIR" && *(dir_list.end() - 2) == "PS3_GAME") + { + vfs::mount("dev_bdvd", elf_dir.substr(0, elf_dir.length() - 15)); + } + else + { + vfs::mount("dev_bdvd", elf_dir + "/../../"); + } + + LOG_NOTICE(LOADER, "Disc: %s", vfs::get("/dev_bdvd")); + } + else if (bdvd_dir.size()) + { + vfs::mount("dev_bdvd", fmt::replace_all(bdvd_dir, "$(EmulatorDir)", emu_dir)); + } + + // Mount /host_root/ if necessary + if (g_cfg_vfs_allow_host_root) + { + vfs::mount("host_root", {}); + } // Check SELF header if (elf_file.size() >= 4 && elf_file.read() == "SCE\0"_u32) @@ -228,20 +296,6 @@ void Emulator::Load() } } - // Load custom config-1 - if (fs::file cfg_file{ fs::get_config_dir() + "data/" + m_title_id + "/config.yml" }) - { - LOG_NOTICE(LOADER, "Applying custom config %s", fs::get_config_dir() + "data/" + m_title_id + "/config.yml"); - cfg::root.from_string(cfg_file.to_string()); - } - - // Load custom config-2 - if (fs::file cfg_file{m_path + ".yml"}) - { - LOG_NOTICE(LOADER, "Applying custom config: %s.yml", m_path); - cfg::root.from_string(cfg_file.to_string()); - } - ppu_exec_object ppu_exec; ppu_prx_object ppu_prx; spu_exec_object spu_exec; @@ -265,52 +319,6 @@ void Emulator::Load() LOG_NOTICE(LOADER, "Elf path: %s", m_elf_path); } - LOG_NOTICE(LOADER, "Title: %s", GetTitle()); - LOG_NOTICE(LOADER, "Serial: %s", GetTitleID()); - - // Mount all devices - const std::string& emu_dir_ = g_cfg_vfs_emulator_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; - - vfs::mount("dev_hdd0", fmt::replace_all(g_cfg_vfs_dev_hdd0, "$(EmulatorDir)", emu_dir)); - vfs::mount("dev_hdd1", fmt::replace_all(g_cfg_vfs_dev_hdd1, "$(EmulatorDir)", emu_dir)); - vfs::mount("dev_flash", fmt::replace_all(g_cfg_vfs_dev_flash, "$(EmulatorDir)", emu_dir)); - vfs::mount("dev_usb", fmt::replace_all(g_cfg_vfs_dev_usb000, "$(EmulatorDir)", emu_dir)); - vfs::mount("dev_usb000", fmt::replace_all(g_cfg_vfs_dev_usb000, "$(EmulatorDir)", emu_dir)); - vfs::mount("app_home", home_dir.empty() ? elf_dir + '/' : fmt::replace_all(home_dir, "$(EmulatorDir)", emu_dir)); - - // Mount /dev_bdvd/ if necessary - if (bdvd_dir.empty() && fs::is_file(elf_dir + "/../../PS3_DISC.SFB")) - { - const auto dir_list = fmt::split(elf_dir, { "/", "\\" }); - - // Check latest two directories - if (dir_list.size() >= 2 && dir_list.back() == "USRDIR" && *(dir_list.end() - 2) == "PS3_GAME") - { - vfs::mount("dev_bdvd", elf_dir.substr(0, elf_dir.length() - 15)); - } - else - { - vfs::mount("dev_bdvd", elf_dir + "/../../"); - } - - LOG_NOTICE(LOADER, "Disc: %s", vfs::get("/dev_bdvd")); - } - else if (bdvd_dir.size()) - { - vfs::mount("dev_bdvd", fmt::replace_all(bdvd_dir, "$(EmulatorDir)", emu_dir)); - } - - // Mount /host_root/ if necessary - if (g_cfg_vfs_allow_host_root) - { - vfs::mount("host_root", {}); - } - - LOG_NOTICE(LOADER, "Used configuration:\n%s\n", cfg::root.to_string()); - ppu_load_exec(ppu_exec); fxm::import(Emu.GetCallbacks().get_gs_render); // TODO: must be created in appropriate sys_rsx syscall diff --git a/rpcs3/Gui/GameViewer.cpp b/rpcs3/Gui/GameViewer.cpp index f2ee3a541f..202fda295e 100644 --- a/rpcs3/Gui/GameViewer.cpp +++ b/rpcs3/Gui/GameViewer.cpp @@ -129,7 +129,7 @@ void GameViewer::LoadPSF() GameInfo game; game.root = m_games[i]; - game.serial = psf::get_string(psf, "TITLE_ID", "unknown"); + game.serial = psf::get_string(psf, "TITLE_ID", ""); game.name = psf::get_string(psf, "TITLE", "unknown"); game.app_ver = psf::get_string(psf, "APP_VER", "unknown"); game.category = psf::get_string(psf, "CATEGORY", "unknown"); @@ -137,11 +137,6 @@ void GameViewer::LoadPSF() game.parental_lvl = psf::get_integer(psf, "PARENTAL_LEVEL"); game.resolution = psf::get_integer(psf, "RESOLUTION"); game.sound_format = psf::get_integer(psf, "SOUND_FORMAT"); - - if (game.serial.length() == 9) - { - game.serial.insert(4, 1, '-'); - } if (game.category == "HG") { @@ -230,11 +225,7 @@ void GameViewer::ConfigureGame(wxCommandEvent& WXUNUSED(event)) { long i = GetFirstSelected(); if (i < 0) return; - if (!fs::exists(fs::get_config_dir() + "data/" + m_game_data[i].root)) - { - fs::create_dir(fs::get_config_dir() + "data/" + m_game_data[i].root); - } - SettingsDialog(this, fs::get_config_dir() + "data/" + m_game_data[i].root + "/config.yml"); + SettingsDialog(this, "data/" + m_game_data[i].serial); } void GameViewer::RemoveGame(wxCommandEvent& event) diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 506cc6a15f..e7dc2051af 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -553,7 +553,7 @@ void MainFrame::SendOpenCloseSysMenu(wxCommandEvent& event) void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) { - SettingsDialog(this,""); + SettingsDialog(this, ""); } void MainFrame::ConfigPad(wxCommandEvent& WXUNUSED(event)) diff --git a/rpcs3/Gui/SettingsDialog.cpp b/rpcs3/Gui/SettingsDialog.cpp index 702a02d21d..b0e9304bb9 100644 --- a/rpcs3/Gui/SettingsDialog.cpp +++ b/rpcs3/Gui/SettingsDialog.cpp @@ -202,15 +202,19 @@ struct textctrl_pad : cfg_adapter }; -SettingsDialog::SettingsDialog(wxWindow* parent, const wxString& pergameload) +SettingsDialog::SettingsDialog(wxWindow* parent, const std::string& path) : wxDialog(parent, wxID_ANY, "Settings", wxDefaultPosition) { // Load default config loaded = YAML::Load(g_cfg_defaults); + // Create config path if necessary + fs::create_path(fs::get_config_dir() + path); + // Incrementally load config.yml - const fs::file config(!pergameload.IsEmpty() ? pergameload.ToStdString() : fs::get_config_dir() + "/config.yml", fs::read + fs::write + fs::create); - if (config.to_string().length() == 0 && !pergameload.IsEmpty())//empty first time gameconfig + const fs::file config(fs::get_config_dir() + path + "/config.yml", fs::read + fs::write + fs::create); + + if (config.size() == 0 && !path.empty()) // First time { const fs::file configexisted(fs::get_config_dir() + "/config.yml", fs::read + fs::write + fs::create); loaded += YAML::Load(configexisted.to_string()); diff --git a/rpcs3/Gui/SettingsDialog.h b/rpcs3/Gui/SettingsDialog.h index 1f2f84784a..e5f74550f0 100644 --- a/rpcs3/Gui/SettingsDialog.h +++ b/rpcs3/Gui/SettingsDialog.h @@ -3,7 +3,7 @@ class SettingsDialog : public wxDialog { public: - SettingsDialog(wxWindow* parent, const wxString& pergameload); + SettingsDialog(wxWindow* parent, const std::string& path); private: wxCheckListBox* chbox_list_core_lle;