Fixed VFS initialization order

Fixed RAP location for SELF
Fixed custom config loading
This commit is contained in:
Nekotekina 2017-02-28 14:10:04 +03:00
parent 45bb51ded8
commit 3751d5d5c1
6 changed files with 85 additions and 89 deletions

View file

@ -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 <zlib.h>
@ -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<const char*>(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;
}

View file

@ -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<u32>() == "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<GSRender>(Emu.GetCallbacks().get_gs_render); // TODO: must be created in appropriate sys_rsx syscall

View file

@ -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)

View file

@ -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))

View file

@ -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());

View file

@ -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;