mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-08 16:01:42 +12:00
Better Support For Game Collections (#4450)
This commit is contained in:
parent
141d78344a
commit
cafa4521ee
8 changed files with 173 additions and 71 deletions
|
@ -1,4 +1,4 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Emu/Memory/vm.h"
|
#include "Emu/Memory/vm.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
#include "Emu/IdManager.h"
|
#include "Emu/IdManager.h"
|
||||||
|
@ -314,7 +314,7 @@ void _sys_process_exit2(ppu_thread& ppu, s32 status, vm::ptr<sys_exit2_param> ar
|
||||||
}
|
}
|
||||||
|
|
||||||
Emu.SetForceBoot(true);
|
Emu.SetForceBoot(true);
|
||||||
Emu.BootGame(path, true);
|
Emu.BootGame(path, "", true);
|
||||||
});
|
});
|
||||||
|
|
||||||
ppu.state += cpu_flag::dbg_global_stop;
|
ppu.state += cpu_flag::dbg_global_stop;
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
#include "Utilities/GDBDebugServer.h"
|
#include "Utilities/GDBDebugServer.h"
|
||||||
|
|
||||||
|
@ -592,18 +593,18 @@ void Emulator::LimitCacheSize()
|
||||||
LOG_SUCCESS(GENERAL, "Cleaned disk cache, removed %.2f MB", size / 1024.0 / 1024.0);
|
LOG_SUCCESS(GENERAL, "Cleaned disk cache, removed %.2f MB", size / 1024.0 / 1024.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Emulator::BootGame(const std::string& path, bool direct, bool add_only, bool force_global_config)
|
bool Emulator::BootGame(const std::string& path, const std::string& title_id, bool direct, bool add_only, bool force_global_config)
|
||||||
{
|
{
|
||||||
if (g_cfg.vfs.limit_cache_size)
|
if (g_cfg.vfs.limit_cache_size)
|
||||||
LimitCacheSize();
|
LimitCacheSize();
|
||||||
|
|
||||||
static const char* boot_list[] =
|
static const char* boot_list[] =
|
||||||
{
|
{
|
||||||
"/PS3_GAME/USRDIR/EBOOT.BIN",
|
|
||||||
"/USRDIR/EBOOT.BIN",
|
|
||||||
"/EBOOT.BIN",
|
|
||||||
"/eboot.bin",
|
"/eboot.bin",
|
||||||
|
"/EBOOT.BIN",
|
||||||
|
"/USRDIR/EBOOT.BIN",
|
||||||
"/USRDIR/ISO.BIN.EDAT",
|
"/USRDIR/ISO.BIN.EDAT",
|
||||||
|
"/PS3_GAME/USRDIR/EBOOT.BIN",
|
||||||
};
|
};
|
||||||
|
|
||||||
m_path_old = m_path;
|
m_path_old = m_path;
|
||||||
|
@ -611,10 +612,11 @@ bool Emulator::BootGame(const std::string& path, bool direct, bool add_only, boo
|
||||||
if (direct && fs::exists(path))
|
if (direct && fs::exists(path))
|
||||||
{
|
{
|
||||||
m_path = path;
|
m_path = path;
|
||||||
Load(add_only, force_global_config);
|
Load(title_id, add_only, force_global_config);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
for (std::string elf : boot_list)
|
for (std::string elf : boot_list)
|
||||||
{
|
{
|
||||||
elf = path + elf;
|
elf = path + elf;
|
||||||
|
@ -622,12 +624,36 @@ bool Emulator::BootGame(const std::string& path, bool direct, bool add_only, boo
|
||||||
if (fs::is_file(elf))
|
if (fs::is_file(elf))
|
||||||
{
|
{
|
||||||
m_path = elf;
|
m_path = elf;
|
||||||
Load(add_only, force_global_config);
|
Load(title_id, add_only, force_global_config);
|
||||||
return true;
|
success = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if (add_only)
|
||||||
|
{
|
||||||
|
for (auto&& entry : fs::dir{ path })
|
||||||
|
{
|
||||||
|
if (entry.name == "." || entry.name == "..")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.is_directory && std::regex_match(entry.name, std::regex("^PS3_GM[[:digit:]]{2}$")))
|
||||||
|
{
|
||||||
|
const std::string elf = path + "/" + entry.name + "/USRDIR/EBOOT.BIN";
|
||||||
|
|
||||||
|
if (fs::is_file(elf))
|
||||||
|
{
|
||||||
|
m_path = elf;
|
||||||
|
Load(title_id, add_only, force_global_config);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Emulator::InstallPkg(const std::string& path)
|
bool Emulator::InstallPkg(const std::string& path)
|
||||||
|
@ -679,11 +705,34 @@ std::string Emulator::GetHdd1Dir()
|
||||||
return fmt::replace_all(g_cfg.vfs.dev_hdd1, "$(EmulatorDir)", GetEmuDir());
|
return fmt::replace_all(g_cfg.vfs.dev_hdd1, "$(EmulatorDir)", GetEmuDir());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Emulator::GetSfoDirFromGamePath(const std::string& game_path, const std::string& user)
|
std::string Emulator::GetSfoDirFromGamePath(const std::string& game_path, const std::string& user, const std::string& title_id)
|
||||||
{
|
{
|
||||||
if (fs::is_file(game_path + "/PS3_DISC.SFB"))
|
if (fs::is_file(game_path + "/PS3_DISC.SFB"))
|
||||||
{
|
{
|
||||||
// This is a disc game.
|
// This is a disc game.
|
||||||
|
if (!title_id.empty())
|
||||||
|
{
|
||||||
|
for (auto&& entry : fs::dir{game_path})
|
||||||
|
{
|
||||||
|
if (entry.name == "." || entry.name == "..")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string sfo_path = game_path + "/" + entry.name + "/PARAM.SFO";
|
||||||
|
|
||||||
|
if (entry.is_directory && fs::is_file(sfo_path))
|
||||||
|
{
|
||||||
|
const auto psf = psf::load_object(fs::file(sfo_path));
|
||||||
|
const std::string serial = get_string(psf, "TITLE_ID");
|
||||||
|
if (serial == title_id)
|
||||||
|
{
|
||||||
|
return game_path + "/" + entry.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return game_path + "/PS3_GAME";
|
return game_path + "/PS3_GAME";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,13 +796,18 @@ void Emulator::SetForceBoot(bool force_boot)
|
||||||
m_force_boot = force_boot;
|
m_force_boot = force_boot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Emulator::Load(bool add_only, bool force_global_config)
|
void Emulator::Load(const std::string& title_id, bool add_only, bool force_global_config)
|
||||||
{
|
{
|
||||||
if (!IsStopped())
|
if (!IsStopped())
|
||||||
{
|
{
|
||||||
Stop();
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!title_id.empty())
|
||||||
|
{
|
||||||
|
m_title_id = title_id;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
|
@ -782,14 +836,14 @@ void Emulator::Load(bool add_only, bool force_global_config)
|
||||||
if (fs::is_dir(m_path))
|
if (fs::is_dir(m_path))
|
||||||
{
|
{
|
||||||
// Special case (directory scan)
|
// Special case (directory scan)
|
||||||
m_sfo_dir = GetSfoDirFromGamePath(m_path, GetUsr());
|
m_sfo_dir = GetSfoDirFromGamePath(m_path, GetUsr(), m_title_id);
|
||||||
}
|
}
|
||||||
else if (disc.size())
|
else if (disc.size())
|
||||||
{
|
{
|
||||||
// Check previously used category before it's overwritten
|
// Check previously used category before it's overwritten
|
||||||
if (m_cat == "DG")
|
if (m_cat == "DG")
|
||||||
{
|
{
|
||||||
m_sfo_dir = disc + "/PS3_GAME";
|
m_sfo_dir = disc + "/" + m_game_dir;
|
||||||
}
|
}
|
||||||
else if (m_cat == "GD")
|
else if (m_cat == "GD")
|
||||||
{
|
{
|
||||||
|
@ -797,12 +851,12 @@ void Emulator::Load(bool add_only, bool force_global_config)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_sfo_dir = GetSfoDirFromGamePath(disc, GetUsr());
|
m_sfo_dir = GetSfoDirFromGamePath(disc, GetUsr(), m_title_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_sfo_dir = GetSfoDirFromGamePath(elf_dir + "/../", GetUsr());
|
m_sfo_dir = GetSfoDirFromGamePath(elf_dir + "/../", GetUsr(), m_title_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
_psf = psf::load_object(fs::file(m_sfo_dir + "/PARAM.SFO"));
|
_psf = psf::load_object(fs::file(m_sfo_dir + "/PARAM.SFO"));
|
||||||
|
@ -1019,7 +1073,8 @@ void Emulator::Load(bool add_only, bool force_global_config)
|
||||||
// Detect boot location
|
// Detect boot location
|
||||||
const std::string hdd0_game = vfs::get("/dev_hdd0/game/");
|
const std::string hdd0_game = vfs::get("/dev_hdd0/game/");
|
||||||
const std::string hdd0_disc = vfs::get("/dev_hdd0/disc/");
|
const std::string hdd0_disc = vfs::get("/dev_hdd0/disc/");
|
||||||
const std::size_t bdvd_pos = m_cat == "DG" && bdvd_dir.empty() && disc.empty() ? elf_dir.rfind("/PS3_GAME/") + 1 : 0;
|
const std::size_t game_dir_size = 8; // size of PS3_GAME and PS3_GMXX
|
||||||
|
const std::size_t bdvd_pos = m_cat == "DG" && bdvd_dir.empty() && disc.empty() ? elf_dir.rfind("/USRDIR") - game_dir_size : 0;
|
||||||
const bool from_hdd0_game = m_path.find(hdd0_game) != -1;
|
const bool from_hdd0_game = m_path.find(hdd0_game) != -1;
|
||||||
|
|
||||||
if (bdvd_pos && from_hdd0_game)
|
if (bdvd_pos && from_hdd0_game)
|
||||||
|
@ -1045,6 +1100,11 @@ void Emulator::Load(bool add_only, bool force_global_config)
|
||||||
{
|
{
|
||||||
// Mount /dev_bdvd/ if necessary
|
// Mount /dev_bdvd/ if necessary
|
||||||
bdvd_dir = elf_dir.substr(0, bdvd_pos);
|
bdvd_dir = elf_dir.substr(0, bdvd_pos);
|
||||||
|
m_game_dir = elf_dir.substr(bdvd_pos, game_dir_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_game_dir = "PS3_GAME"; // reset
|
||||||
}
|
}
|
||||||
|
|
||||||
// Booting patch data
|
// Booting patch data
|
||||||
|
@ -1069,6 +1129,9 @@ void Emulator::Load(bool add_only, bool force_global_config)
|
||||||
vfs::mount("/dev_bdvd", bdvd_dir);
|
vfs::mount("/dev_bdvd", bdvd_dir);
|
||||||
LOG_NOTICE(LOADER, "Disc: %s", vfs::get("/dev_bdvd"));
|
LOG_NOTICE(LOADER, "Disc: %s", vfs::get("/dev_bdvd"));
|
||||||
|
|
||||||
|
vfs::mount("/dev_bdvd/PS3_GAME", bdvd_dir + m_game_dir + "/");
|
||||||
|
LOG_NOTICE(LOADER, "Game: %s", vfs::get("/dev_bdvd/PS3_GAME"));
|
||||||
|
|
||||||
if (!sfb_file.open(vfs::get("/dev_bdvd/PS3_DISC.SFB")) || sfb_file.size() < 4 || sfb_file.read<u32>() != ".SFB"_u32)
|
if (!sfb_file.open(vfs::get("/dev_bdvd/PS3_DISC.SFB")) || sfb_file.size() < 4 || sfb_file.read<u32>() != ".SFB"_u32)
|
||||||
{
|
{
|
||||||
LOG_ERROR(LOADER, "Invalid disc directory for the disc game %s", m_title_id);
|
LOG_ERROR(LOADER, "Invalid disc directory for the disc game %s", m_title_id);
|
||||||
|
@ -1167,9 +1230,10 @@ void Emulator::Load(bool add_only, bool force_global_config)
|
||||||
|
|
||||||
for (auto&& entry : fs::dir{ins_dir})
|
for (auto&& entry : fs::dir{ins_dir})
|
||||||
{
|
{
|
||||||
if (!entry.is_directory && ends_with(entry.name, ".PKG") && !InstallPkg(ins_dir + entry.name))
|
const std::string pkg = ins_dir + entry.name;
|
||||||
|
if (!entry.is_directory && ends_with(entry.name, ".PKG") && !InstallPkg(pkg))
|
||||||
{
|
{
|
||||||
LOG_ERROR(LOADER, "Failed to install /dev_bdvd/PS3_GAME/INSDIR/%s", entry.name);
|
LOG_ERROR(LOADER, "Failed to install %s", pkg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1187,7 +1251,7 @@ void Emulator::Load(bool add_only, bool force_global_config)
|
||||||
|
|
||||||
if (fs::is_file(pkg_file) && !InstallPkg(pkg_file))
|
if (fs::is_file(pkg_file) && !InstallPkg(pkg_file))
|
||||||
{
|
{
|
||||||
LOG_ERROR(LOADER, "Failed to install /dev_bdvd/PS3_GAME/PKGDIR/%s/INSTALL.PKG", entry.name);
|
LOG_ERROR(LOADER, "Failed to install %s", pkg_file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1206,7 +1270,7 @@ void Emulator::Load(bool add_only, bool force_global_config)
|
||||||
|
|
||||||
if (fs::is_file(pkg_file) && !InstallPkg(pkg_file))
|
if (fs::is_file(pkg_file) && !InstallPkg(pkg_file))
|
||||||
{
|
{
|
||||||
LOG_ERROR(LOADER, "Failed to install /dev_bdvd/PS3_GAME/PKGDIR/%s/DATA000.PKG", entry.name);
|
LOG_ERROR(LOADER, "Failed to install %s", pkg_file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1319,8 +1383,8 @@ void Emulator::Load(bool add_only, bool force_global_config)
|
||||||
else if (!bdvd_dir.empty() && fs::is_dir(bdvd_dir))
|
else if (!bdvd_dir.empty() && fs::is_dir(bdvd_dir))
|
||||||
{
|
{
|
||||||
// Disc games are on /dev_bdvd/
|
// Disc games are on /dev_bdvd/
|
||||||
const std::size_t pos = m_path.rfind("PS3_GAME");
|
const std::size_t pos = m_path.rfind(m_game_dir);
|
||||||
argv[0] = "/dev_bdvd/" + m_path.substr(pos);
|
argv[0] = "/dev_bdvd/PS3_GAME/" + m_path.substr(pos + game_dir_size + 1);
|
||||||
m_dir = "/dev_bdvd/PS3_GAME/";
|
m_dir = "/dev_bdvd/PS3_GAME/";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -220,6 +220,7 @@ class Emulator final
|
||||||
std::string m_cat;
|
std::string m_cat;
|
||||||
std::string m_dir;
|
std::string m_dir;
|
||||||
std::string m_sfo_dir;
|
std::string m_sfo_dir;
|
||||||
|
std::string m_game_dir{"PS3_GAME"};
|
||||||
std::string m_usr{"00000001"};
|
std::string m_usr{"00000001"};
|
||||||
u32 m_usrid{1};
|
u32 m_usrid{1};
|
||||||
|
|
||||||
|
@ -311,7 +312,7 @@ public:
|
||||||
|
|
||||||
std::string PPUCache() const;
|
std::string PPUCache() const;
|
||||||
|
|
||||||
bool BootGame(const std::string& path, bool direct = false, bool add_only = false, bool force_global_config = false);
|
bool BootGame(const std::string& path, const std::string& title_id = "", bool direct = false, bool add_only = false, bool force_global_config = false);
|
||||||
bool BootRsxCapture(const std::string& path);
|
bool BootRsxCapture(const std::string& path);
|
||||||
bool InstallPkg(const std::string& path);
|
bool InstallPkg(const std::string& path);
|
||||||
|
|
||||||
|
@ -322,7 +323,7 @@ private:
|
||||||
void LimitCacheSize();
|
void LimitCacheSize();
|
||||||
public:
|
public:
|
||||||
static std::string GetHddDir();
|
static std::string GetHddDir();
|
||||||
static std::string GetSfoDirFromGamePath(const std::string& game_path, const std::string& user);
|
static std::string GetSfoDirFromGamePath(const std::string& game_path, const std::string& user, const std::string& title_id = "");
|
||||||
|
|
||||||
static std::string GetCustomConfigDir();
|
static std::string GetCustomConfigDir();
|
||||||
static std::string GetCustomConfigPath(const std::string& title_id, bool get_deprecated_path = false);
|
static std::string GetCustomConfigPath(const std::string& title_id, bool get_deprecated_path = false);
|
||||||
|
@ -331,7 +332,7 @@ public:
|
||||||
|
|
||||||
void SetForceBoot(bool force_boot);
|
void SetForceBoot(bool force_boot);
|
||||||
|
|
||||||
void Load(bool add_only = false, bool force_global_config = false);
|
void Load(const std::string& title_id = "", bool add_only = false, bool force_global_config = false);
|
||||||
void Run();
|
void Run();
|
||||||
bool Pause();
|
bool Pause();
|
||||||
void Resume();
|
void Resume();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Qt5.2+ frontend implementation for rpcs3. Known to work on Windows, Linux, Mac
|
// Qt5.2+ frontend implementation for rpcs3. Known to work on Windows, Linux, Mac
|
||||||
// by Sacha Refshauge, Megamouse and flash-fire
|
// by Sacha Refshauge, Megamouse and flash-fire
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
@ -160,7 +160,7 @@ int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
Emu.argv = std::move(argv);
|
Emu.argv = std::move(argv);
|
||||||
Emu.SetForceBoot(true);
|
Emu.SetForceBoot(true);
|
||||||
Emu.BootGame(path, true);
|
Emu.BootGame(path, "", true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
|
@ -386,13 +387,40 @@ void game_list_frame::Refresh(const bool fromDrive, const bool scrollAfter)
|
||||||
|
|
||||||
std::vector<std::string> path_list;
|
std::vector<std::string> path_list;
|
||||||
|
|
||||||
|
const auto add_disc_dir = [&](const std::string& path)
|
||||||
|
{
|
||||||
|
for (const auto& entry : fs::dir(path))
|
||||||
|
{
|
||||||
|
if (!entry.is_directory || entry.name == "." || entry.name == "..")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.name == "PS3_GAME" || std::regex_match(entry.name, std::regex("^PS3_GM[[:digit:]]{2}$")))
|
||||||
|
{
|
||||||
|
path_list.emplace_back(path + "/" + entry.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const auto add_dir = [&](const std::string& path)
|
const auto add_dir = [&](const std::string& path)
|
||||||
{
|
{
|
||||||
for (const auto& entry : fs::dir(path))
|
for (const auto& entry : fs::dir(path))
|
||||||
{
|
{
|
||||||
if (entry.is_directory)
|
if (entry.name == "." || entry.name == "..")
|
||||||
{
|
{
|
||||||
path_list.emplace_back(path + entry.name);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string entry_path = path + entry.name;
|
||||||
|
|
||||||
|
if (fs::is_file(entry_path + "/PS3_DISC.SFB"))
|
||||||
|
{
|
||||||
|
add_disc_dir(entry_path);
|
||||||
|
}
|
||||||
|
else if (entry.is_directory)
|
||||||
|
{
|
||||||
|
path_list.emplace_back(entry_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -402,8 +430,17 @@ void game_list_frame::Refresh(const bool fromDrive, const bool scrollAfter)
|
||||||
|
|
||||||
for (auto pair : YAML::Load(fs::file{fs::get_config_dir() + "/games.yml", fs::read + fs::create}.to_string()))
|
for (auto pair : YAML::Load(fs::file{fs::get_config_dir() + "/games.yml", fs::read + fs::create}.to_string()))
|
||||||
{
|
{
|
||||||
path_list.push_back(pair.second.Scalar());
|
const std::string game_dir = pair.second.Scalar();
|
||||||
path_list.back().resize(path_list.back().find_last_not_of('/') + 1);
|
|
||||||
|
if (fs::is_file(game_dir + "/PS3_DISC.SFB"))
|
||||||
|
{
|
||||||
|
add_disc_dir(game_dir);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path_list.push_back(game_dir);
|
||||||
|
path_list.back().resize(path_list.back().find_last_not_of('/') + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to remove duplications from the list (serial -> set of cat names)
|
// Used to remove duplications from the list (serial -> set of cat names)
|
||||||
|
@ -648,7 +685,7 @@ void game_list_frame::doubleClickedSlot(QTableWidgetItem *item)
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_NOTICE(LOADER, "Booting from gamelist per doubleclick...");
|
LOG_NOTICE(LOADER, "Booting from gamelist per doubleclick...");
|
||||||
Q_EMIT RequestBoot(game->info.path);
|
Q_EMIT RequestBoot(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_list_frame::ShowContextMenu(const QPoint &pos)
|
void game_list_frame::ShowContextMenu(const QPoint &pos)
|
||||||
|
@ -693,7 +730,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
||||||
connect(boot_custom, &QAction::triggered, [=]
|
connect(boot_custom, &QAction::triggered, [=]
|
||||||
{
|
{
|
||||||
LOG_NOTICE(LOADER, "Booting from gamelist per context menu...");
|
LOG_NOTICE(LOADER, "Booting from gamelist per context menu...");
|
||||||
Q_EMIT RequestBoot(currGame.path);
|
Q_EMIT RequestBoot(gameinfo);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -787,7 +824,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
||||||
connect(boot, &QAction::triggered, [=]
|
connect(boot, &QAction::triggered, [=]
|
||||||
{
|
{
|
||||||
LOG_NOTICE(LOADER, "Booting from gamelist per context menu...");
|
LOG_NOTICE(LOADER, "Booting from gamelist per context menu...");
|
||||||
Q_EMIT RequestBoot(currGame.path, gameinfo->hasCustomConfig);
|
Q_EMIT RequestBoot(gameinfo, gameinfo->hasCustomConfig);
|
||||||
});
|
});
|
||||||
connect(configure, &QAction::triggered, [=]
|
connect(configure, &QAction::triggered, [=]
|
||||||
{
|
{
|
||||||
|
@ -835,7 +872,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
||||||
});
|
});
|
||||||
connect(createPPUCache, &QAction::triggered, [=]
|
connect(createPPUCache, &QAction::triggered, [=]
|
||||||
{
|
{
|
||||||
CreatePPUCache(currGame.path);
|
CreatePPUCache(gameinfo);
|
||||||
});
|
});
|
||||||
connect(removeGame, &QAction::triggered, [=]
|
connect(removeGame, &QAction::triggered, [=]
|
||||||
{
|
{
|
||||||
|
@ -961,20 +998,20 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
||||||
myMenu.exec(globalPos);
|
myMenu.exec(globalPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool game_list_frame::CreatePPUCache(const std::string& path)
|
bool game_list_frame::CreatePPUCache(const game_info& game)
|
||||||
{
|
{
|
||||||
Emu.SetForceBoot(true);
|
Emu.SetForceBoot(true);
|
||||||
Emu.Stop();
|
Emu.Stop();
|
||||||
Emu.SetForceBoot(true);
|
Emu.SetForceBoot(true);
|
||||||
const bool success = Emu.BootGame(path, true);
|
const bool success = Emu.BootGame(game->info.path, game->info.serial, true);
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
LOG_WARNING(GENERAL, "Creating PPU Cache for %s", path);
|
LOG_WARNING(GENERAL, "Creating PPU Cache for %s", game->info.path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_ERROR(GENERAL, "Could not create PPU Cache for %s", path);
|
LOG_ERROR(GENERAL, "Could not create PPU Cache for %s", game->info.path);
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -1171,12 +1208,7 @@ bool game_list_frame::RemoveSPUCache(const std::string& base_dir, bool is_intera
|
||||||
|
|
||||||
void game_list_frame::BatchCreatePPUCaches()
|
void game_list_frame::BatchCreatePPUCaches()
|
||||||
{
|
{
|
||||||
std::set<std::string> paths;
|
const u32 total = m_game_data.size();
|
||||||
for (const auto& game : m_game_data)
|
|
||||||
{
|
|
||||||
paths.emplace(game->info.path);
|
|
||||||
}
|
|
||||||
const u32 total = paths.size();
|
|
||||||
|
|
||||||
if (total == 0)
|
if (total == 0)
|
||||||
{
|
{
|
||||||
|
@ -1191,7 +1223,7 @@ void game_list_frame::BatchCreatePPUCaches()
|
||||||
pdlg->show();
|
pdlg->show();
|
||||||
|
|
||||||
u32 created = 0;
|
u32 created = 0;
|
||||||
for (const auto& path : paths)
|
for (const auto& game : m_game_data)
|
||||||
{
|
{
|
||||||
if (pdlg->wasCanceled())
|
if (pdlg->wasCanceled())
|
||||||
{
|
{
|
||||||
|
@ -1200,7 +1232,7 @@ void game_list_frame::BatchCreatePPUCaches()
|
||||||
}
|
}
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
|
|
||||||
if (CreatePPUCache(path))
|
if (CreatePPUCache(game))
|
||||||
{
|
{
|
||||||
while (!Emu.IsStopped())
|
while (!Emu.IsStopped())
|
||||||
{
|
{
|
||||||
|
@ -1635,7 +1667,7 @@ bool game_list_frame::eventFilter(QObject *object, QEvent *event)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
LOG_NOTICE(LOADER, "Booting from gamelist by pressing %s...", keyEvent->key() == Qt::Key_Enter ? "Enter" : "Return");
|
LOG_NOTICE(LOADER, "Booting from gamelist by pressing %s...", keyEvent->key() == Qt::Key_Enter ? "Enter" : "Return");
|
||||||
Q_EMIT RequestBoot(gameinfo->info.path);
|
Q_EMIT RequestBoot(gameinfo);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,7 +228,7 @@ private Q_SLOTS:
|
||||||
void doubleClickedSlot(QTableWidgetItem *item);
|
void doubleClickedSlot(QTableWidgetItem *item);
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void GameListFrameClosed();
|
void GameListFrameClosed();
|
||||||
void RequestBoot(const std::string& path, bool force_global_config = false);
|
void RequestBoot(const game_info& game, bool force_global_config = false);
|
||||||
void RequestIconSizeChange(const int& val);
|
void RequestIconSizeChange(const int& val);
|
||||||
protected:
|
protected:
|
||||||
/** Override inherited method from Qt to allow signalling when close happened.*/
|
/** Override inherited method from Qt to allow signalling when close happened.*/
|
||||||
|
@ -251,7 +251,7 @@ private:
|
||||||
bool RemoveShadersCache(const std::string& base_dir, bool is_interactive = false);
|
bool RemoveShadersCache(const std::string& base_dir, bool is_interactive = false);
|
||||||
bool RemovePPUCache(const std::string& base_dir, bool is_interactive = false);
|
bool RemovePPUCache(const std::string& base_dir, bool is_interactive = false);
|
||||||
bool RemoveSPUCache(const std::string& base_dir, bool is_interactive = false);
|
bool RemoveSPUCache(const std::string& base_dir, bool is_interactive = false);
|
||||||
bool CreatePPUCache(const std::string& path);
|
bool CreatePPUCache(const game_info& game);
|
||||||
|
|
||||||
std::string GetCacheDirBySerial(const std::string& serial);
|
std::string GetCacheDirBySerial(const std::string& serial);
|
||||||
std::string GetDataDirBySerial(const std::string& serial);
|
std::string GetDataDirBySerial(const std::string& serial);
|
||||||
|
|
|
@ -185,16 +185,20 @@ QIcon main_window::GetAppIcon()
|
||||||
}
|
}
|
||||||
|
|
||||||
// loads the appIcon from path and embeds it centered into an empty square icon
|
// loads the appIcon from path and embeds it centered into an empty square icon
|
||||||
void main_window::SetAppIconFromPath(const std::string& path)
|
void main_window::SetAppIconFromPath(const std::string& path, const std::string& title_id)
|
||||||
{
|
{
|
||||||
// get Icon for the gs_frame from path. this handles presumably all possible use cases
|
// get Icon for the gs_frame from path. this handles presumably all possible use cases
|
||||||
QString qpath = qstr(path);
|
const QString qpath = qstr(path);
|
||||||
std::string path_list[] = { path, sstr(qpath.section("/", 0, -2)), sstr(qpath.section("/", 0, -3)) };
|
const std::string path_list[] = { path, sstr(qpath.section("/", 0, -2)), sstr(qpath.section("/", 0, -3)) };
|
||||||
for (std::string pth : path_list)
|
|
||||||
{
|
|
||||||
if (!fs::is_dir(pth)) continue;
|
|
||||||
|
|
||||||
const std::string sfo_dir = Emu.GetSfoDirFromGamePath(pth, Emu.GetUsr());
|
for (const std::string& pth : path_list)
|
||||||
|
{
|
||||||
|
if (!fs::is_dir(pth))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string sfo_dir = Emu.GetSfoDirFromGamePath(pth, Emu.GetUsr(), title_id);
|
||||||
const std::string ico = sfo_dir + "/ICON0.PNG";
|
const std::string ico = sfo_dir + "/ICON0.PNG";
|
||||||
if (fs::is_file(ico))
|
if (fs::is_file(ico))
|
||||||
{
|
{
|
||||||
|
@ -268,7 +272,7 @@ void main_window::OnPlayOrPause()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void main_window::Boot(const std::string& path, bool direct, bool add_only, bool force_global_config)
|
void main_window::Boot(const std::string& path, const std::string& title_id, bool direct, bool add_only, bool force_global_config)
|
||||||
{
|
{
|
||||||
if (!Emu.IsStopped())
|
if (!Emu.IsStopped())
|
||||||
{
|
{
|
||||||
|
@ -283,11 +287,11 @@ void main_window::Boot(const std::string& path, bool direct, bool add_only, bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetAppIconFromPath(path);
|
SetAppIconFromPath(path, title_id);
|
||||||
Emu.SetForceBoot(true);
|
Emu.SetForceBoot(true);
|
||||||
Emu.Stop();
|
Emu.Stop();
|
||||||
|
|
||||||
if (Emu.BootGame(path, direct, add_only, force_global_config))
|
if (Emu.BootGame(path, title_id, direct, add_only, force_global_config))
|
||||||
{
|
{
|
||||||
LOG_SUCCESS(LOADER, "Boot successful.");
|
LOG_SUCCESS(LOADER, "Boot successful.");
|
||||||
const std::string serial = Emu.GetTitleID().empty() ? "" : "[" + Emu.GetTitleID() + "] ";
|
const std::string serial = Emu.GetTitleID().empty() ? "" : "[" + Emu.GetTitleID() + "] ";
|
||||||
|
@ -337,7 +341,7 @@ void main_window::BootElf()
|
||||||
const std::string path = sstr(QFileInfo(filePath).canonicalFilePath());
|
const std::string path = sstr(QFileInfo(filePath).canonicalFilePath());
|
||||||
|
|
||||||
LOG_NOTICE(LOADER, "Booting from BootElf...");
|
LOG_NOTICE(LOADER, "Booting from BootElf...");
|
||||||
Boot(path, true);
|
Boot(path, "", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main_window::BootGame()
|
void main_window::BootGame()
|
||||||
|
@ -652,7 +656,7 @@ void main_window::InstallPup(const QString& dropPath)
|
||||||
guiSettings->ShowInfoBox(tr("Success!"), tr("Successfully installed PS3 firmware and LLE Modules!"), gui::ib_pup_success, this);
|
guiSettings->ShowInfoBox(tr("Success!"), tr("Successfully installed PS3 firmware and LLE Modules!"), gui::ib_pup_success, this);
|
||||||
|
|
||||||
Emu.SetForceBoot(true);
|
Emu.SetForceBoot(true);
|
||||||
Emu.BootGame(g_cfg.vfs.get_dev_flash() + "sys/external/", true);
|
Emu.BootGame(g_cfg.vfs.get_dev_flash() + "sys/external/", "", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1022,7 +1026,7 @@ void main_window::BootRecentAction(const QAction* act)
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_NOTICE(LOADER, "Booting from recent games list...");
|
LOG_NOTICE(LOADER, "Booting from recent games list...");
|
||||||
Boot(path, true);
|
Boot(path, "", true);
|
||||||
};
|
};
|
||||||
|
|
||||||
QAction* main_window::CreateRecentAction(const q_string_pair& entry, const uint& sc_idx)
|
QAction* main_window::CreateRecentAction(const q_string_pair& entry, const uint& sc_idx)
|
||||||
|
@ -1578,9 +1582,9 @@ void main_window::CreateDockWindows()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_gameListFrame, &game_list_frame::RequestBoot, [this](const std::string& path, bool force_global_config)
|
connect(m_gameListFrame, &game_list_frame::RequestBoot, [this](const game_info& game, bool force_global_config)
|
||||||
{
|
{
|
||||||
Boot(path, false, false, force_global_config);
|
Boot(game->info.path, game->info.serial, false, false, force_global_config);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1774,7 +1778,7 @@ void main_window::AddGamesFromDir(const QString& path)
|
||||||
const std::string s_path = sstr(path);
|
const std::string s_path = sstr(path);
|
||||||
|
|
||||||
// search dropped path first or else the direct parent to an elf is wrongly skipped
|
// search dropped path first or else the direct parent to an elf is wrongly skipped
|
||||||
if (Emu.BootGame(s_path, false, true))
|
if (Emu.BootGame(s_path, "", false, true))
|
||||||
{
|
{
|
||||||
LOG_NOTICE(GENERAL, "Returned from game addition by drag and drop: %s", s_path);
|
LOG_NOTICE(GENERAL, "Returned from game addition by drag and drop: %s", s_path);
|
||||||
}
|
}
|
||||||
|
@ -1785,7 +1789,7 @@ void main_window::AddGamesFromDir(const QString& path)
|
||||||
{
|
{
|
||||||
std::string pth = sstr(dir_iter.next());
|
std::string pth = sstr(dir_iter.next());
|
||||||
|
|
||||||
if (Emu.BootGame(pth, false, true))
|
if (Emu.BootGame(pth, "", false, true))
|
||||||
{
|
{
|
||||||
LOG_NOTICE(GENERAL, "Returned from game addition by drag and drop: %s", pth);
|
LOG_NOTICE(GENERAL, "Returned from game addition by drag and drop: %s", pth);
|
||||||
}
|
}
|
||||||
|
@ -1916,7 +1920,7 @@ void main_window::dropEvent(QDropEvent* event)
|
||||||
m_gameListFrame->Refresh(true);
|
m_gameListFrame->Refresh(true);
|
||||||
break;
|
break;
|
||||||
case drop_type::drop_game: // import valid games to gamelist (games.yaml)
|
case drop_type::drop_game: // import valid games to gamelist (games.yaml)
|
||||||
if (Emu.BootGame(sstr(dropPaths.first()), true))
|
if (Emu.BootGame(sstr(dropPaths.first()), "", true))
|
||||||
{
|
{
|
||||||
LOG_SUCCESS(GENERAL, "Elf Boot from drag and drop done: %s", sstr(dropPaths.first()));
|
LOG_SUCCESS(GENERAL, "Elf Boot from drag and drop done: %s", sstr(dropPaths.first()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ public Q_SLOTS:
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void OnPlayOrPause();
|
void OnPlayOrPause();
|
||||||
void Boot(const std::string& path, bool direct = false, bool add_only = false, bool force_global_config = false);
|
void Boot(const std::string& path, const std::string& title_id = "", bool direct = false, bool add_only = false, bool force_global_config = false);
|
||||||
void BootElf();
|
void BootElf();
|
||||||
void BootGame();
|
void BootGame();
|
||||||
void BootRsxCapture(std::string path = "");
|
void BootRsxCapture(std::string path = "");
|
||||||
|
@ -108,7 +108,8 @@ protected:
|
||||||
void dragEnterEvent(QDragEnterEvent* event) override;
|
void dragEnterEvent(QDragEnterEvent* event) override;
|
||||||
void dragMoveEvent(QDragMoveEvent* event) override;
|
void dragMoveEvent(QDragMoveEvent* event) override;
|
||||||
void dragLeaveEvent(QDragLeaveEvent* event) override;
|
void dragLeaveEvent(QDragLeaveEvent* event) override;
|
||||||
void SetAppIconFromPath(const std::string& path);
|
void SetAppIconFromPath(const std::string& path, const std::string& title_id = "");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void RepaintToolBarIcons();
|
void RepaintToolBarIcons();
|
||||||
void RepaintThumbnailIcons();
|
void RepaintThumbnailIcons();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue