Skip to content

Commit

Permalink
Workarounds to keep games.yml consistent
Browse files Browse the repository at this point in the history
  • Loading branch information
Megamouse committed May 30, 2019
1 parent a521c2b commit e53aae4
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 67 deletions.
4 changes: 2 additions & 2 deletions rpcs3/Emu/Cell/lv2/sys_process.cpp
@@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
Expand Down Expand Up @@ -314,7 +314,7 @@ void _sys_process_exit2(ppu_thread& ppu, s32 status, vm::ptr<sys_exit2_param> ar
}

Emu.SetForceBoot(true);
Emu.BootGame(path, true);
Emu.BootGame(path, "", true);
});

ppu.state += cpu_flag::dbg_global_stop;
Expand Down
62 changes: 50 additions & 12 deletions rpcs3/Emu/System.cpp
Expand Up @@ -593,7 +593,7 @@ void Emulator::LimitCacheSize()
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)
LimitCacheSize();
Expand All @@ -612,7 +612,7 @@ bool Emulator::BootGame(const std::string& path, bool direct, bool add_only, boo
if (direct && fs::exists(path))
{
m_path = path;
Load(add_only, force_global_config);
Load(title_id, add_only, force_global_config);
return true;
}

Expand All @@ -624,7 +624,7 @@ bool Emulator::BootGame(const std::string& path, bool direct, bool add_only, boo
if (fs::is_file(elf))
{
m_path = elf;
Load(add_only, force_global_config);
Load(title_id, add_only, force_global_config);
success = true;
break;
}
Expand All @@ -634,14 +634,19 @@ bool Emulator::BootGame(const std::string& path, bool direct, bool add_only, boo
{
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(add_only, force_global_config);
Load(title_id, add_only, force_global_config);
success = true;
}
}
Expand Down Expand Up @@ -700,8 +705,37 @@ std::string Emulator::GetHdd1Dir()
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"))
{
// 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";
}

const auto psf = psf::load_object(fs::file(game_path + "/PARAM.SFO"));

const std::string category = get_string(psf, "CATEGORY");
Expand Down Expand Up @@ -762,13 +796,18 @@ void Emulator::SetForceBoot(bool 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())
{
Stop();
}

if (!title_id.empty())
{
m_title_id = title_id;
}

try
{
Init();
Expand Down Expand Up @@ -797,7 +836,7 @@ void Emulator::Load(bool add_only, bool force_global_config)
if (fs::is_dir(m_path))
{
// 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())
{
Expand All @@ -812,12 +851,12 @@ void Emulator::Load(bool add_only, bool force_global_config)
}
else
{
m_sfo_dir = GetSfoDirFromGamePath(disc, GetUsr());
m_sfo_dir = GetSfoDirFromGamePath(disc, GetUsr(), m_title_id);
}
}
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"));
Expand Down Expand Up @@ -1074,8 +1113,7 @@ void Emulator::Load(bool add_only, bool force_global_config)
// Load /dev_bdvd/ from game list if available
if (auto node = games[m_title_id])
{
const std::string game_dir = node.Scalar();
bdvd_dir = game_dir.substr(0, game_dir.size() - game_dir_size);
bdvd_dir = node.Scalar();
}
else
{
Expand Down Expand Up @@ -1109,7 +1147,7 @@ void Emulator::Load(bool add_only, bool force_global_config)
}

// Store /dev_bdvd/ location
games[m_title_id] = bdvd_dir + m_game_dir;
games[m_title_id] = bdvd_dir;
YAML::Emitter out;
out << games;
fs::file(fs::get_config_dir() + "/games.yml", fs::rewrite).write(out.c_str(), out.size());
Expand Down
6 changes: 3 additions & 3 deletions rpcs3/Emu/System.h
Expand Up @@ -312,7 +312,7 @@ class Emulator final

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 InstallPkg(const std::string& path);

Expand All @@ -323,7 +323,7 @@ class Emulator final
void LimitCacheSize();
public:
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 GetCustomConfigPath(const std::string& title_id, bool get_deprecated_path = false);
Expand All @@ -332,7 +332,7 @@ class Emulator final

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();
bool Pause();
void Resume();
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/main.cpp
@@ -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

#include <QApplication>
Expand Down Expand Up @@ -160,7 +160,7 @@ int main(int argc, char** argv)
{
Emu.argv = std::move(argv);
Emu.SetForceBoot(true);
Emu.BootGame(path, true);
Emu.BootGame(path, "", true);
});
}

Expand Down
77 changes: 46 additions & 31 deletions rpcs3/rpcs3qt/game_list_frame.cpp
Expand Up @@ -387,25 +387,36 @@ void game_list_frame::Refresh(const bool fromDrive, const bool scrollAfter)

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)
{
for (const auto& entry : fs::dir(path))
{
if (entry.name == "." || entry.name == "..")
{
continue;
}

const std::string entry_path = path + entry.name;

if (fs::is_file(entry_path + "/PS3_DISC.SFB"))
{
for (const auto& sub_entry : fs::dir(entry_path))
{
if (!sub_entry.is_directory)
{
continue;
}

if (sub_entry.name == "PS3_GAME" || std::regex_match(sub_entry.name, std::regex("^PS3_GM[[:digit:]]{2}$")))
{
path_list.emplace_back(entry_path + "/" + sub_entry.name);
}
}
add_disc_dir(entry_path);
}
else if (entry.is_directory)
{
Expand All @@ -419,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()))
{
path_list.push_back(pair.second.Scalar());
path_list.back().resize(path_list.back().find_last_not_of('/') + 1);
const std::string game_dir = pair.second.Scalar();

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)
Expand Down Expand Up @@ -665,7 +685,7 @@ void game_list_frame::doubleClickedSlot(QTableWidgetItem *item)
}

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)
Expand Down Expand Up @@ -710,7 +730,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
connect(boot_custom, &QAction::triggered, [=]
{
LOG_NOTICE(LOADER, "Booting from gamelist per context menu...");
Q_EMIT RequestBoot(currGame.path);
Q_EMIT RequestBoot(gameinfo);
});
}
else
Expand Down Expand Up @@ -804,7 +824,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
connect(boot, &QAction::triggered, [=]
{
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, [=]
{
Expand Down Expand Up @@ -852,7 +872,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
});
connect(createPPUCache, &QAction::triggered, [=]
{
CreatePPUCache(currGame.path);
CreatePPUCache(gameinfo);
});
connect(removeGame, &QAction::triggered, [=]
{
Expand Down Expand Up @@ -978,20 +998,20 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
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.Stop();
Emu.SetForceBoot(true);
const bool success = Emu.BootGame(path, true);
const bool success = Emu.BootGame(game->info.path, game->info.serial, true);

if (success)
{
LOG_WARNING(GENERAL, "Creating PPU Cache for %s", path);
LOG_WARNING(GENERAL, "Creating PPU Cache for %s", game->info.path);
}
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;
}
Expand Down Expand Up @@ -1188,12 +1208,7 @@ bool game_list_frame::RemoveSPUCache(const std::string& base_dir, bool is_intera

void game_list_frame::BatchCreatePPUCaches()
{
std::set<std::string> paths;
for (const auto& game : m_game_data)
{
paths.emplace(game->info.path);
}
const u32 total = paths.size();
const u32 total = m_game_data.size();

if (total == 0)
{
Expand All @@ -1208,7 +1223,7 @@ void game_list_frame::BatchCreatePPUCaches()
pdlg->show();

u32 created = 0;
for (const auto& path : paths)
for (const auto& game : m_game_data)
{
if (pdlg->wasCanceled())
{
Expand All @@ -1217,7 +1232,7 @@ void game_list_frame::BatchCreatePPUCaches()
}
QApplication::processEvents();

if (CreatePPUCache(path))
if (CreatePPUCache(game))
{
while (!Emu.IsStopped())
{
Expand Down Expand Up @@ -1652,7 +1667,7 @@ bool game_list_frame::eventFilter(QObject *object, QEvent *event)
return false;

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;
}
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/rpcs3qt/game_list_frame.h
Expand Up @@ -228,7 +228,7 @@ private Q_SLOTS:
void doubleClickedSlot(QTableWidgetItem *item);
Q_SIGNALS:
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);
protected:
/** Override inherited method from Qt to allow signalling when close happened.*/
Expand All @@ -251,7 +251,7 @@ private Q_SLOTS:
bool RemoveShadersCache(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 CreatePPUCache(const std::string& path);
bool CreatePPUCache(const game_info& game);

std::string GetCacheDirBySerial(const std::string& serial);
std::string GetDataDirBySerial(const std::string& serial);
Expand Down

0 comments on commit e53aae4

Please sign in to comment.