mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 16:31:28 +12:00
Properly get PARAM.SFO and icons for C00 games (#5370)
* Added a helper function for fetching game's PARAM.SFO path This should properly get SFO path for unlocked C00 games * Normalized line endings * Refresh game list after installing a RAP file
This commit is contained in:
parent
afdf0b74a0
commit
32059bfaa2
5 changed files with 216 additions and 195 deletions
|
@ -1,4 +1,4 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "overlay_controls.h"
|
#include "overlay_controls.h"
|
||||||
|
|
||||||
#include "../../../Utilities/date_time.h"
|
#include "../../../Utilities/date_time.h"
|
||||||
|
@ -813,14 +813,11 @@ namespace rsx
|
||||||
|
|
||||||
if (use_custom_background)
|
if (use_custom_background)
|
||||||
{
|
{
|
||||||
std::string root_path = Emu.GetBoot();
|
auto icon_path = Emu.GetSfoDir() + "/PIC1.PNG";
|
||||||
root_path = root_path.substr(0, root_path.find_last_of("/"));
|
|
||||||
|
|
||||||
auto icon_path = root_path + "/../PIC1.PNG";
|
|
||||||
if (!fs::exists(icon_path))
|
if (!fs::exists(icon_path))
|
||||||
{
|
{
|
||||||
// Fallback path
|
// Fallback path
|
||||||
icon_path = root_path + "/../ICON0.PNG";
|
icon_path = Emu.GetSfoDir() + "/ICON0.PNG";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs::exists(icon_path))
|
if (fs::exists(icon_path))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Utilities/bin_patch.h"
|
#include "Utilities/bin_patch.h"
|
||||||
#include "Emu/Memory/vm.h"
|
#include "Emu/Memory/vm.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
|
@ -571,6 +571,32 @@ std::string Emulator::GetHddDir()
|
||||||
return fmt::replace_all(g_cfg.vfs.dev_hdd0, "$(EmulatorDir)", GetEmuDir());
|
return fmt::replace_all(g_cfg.vfs.dev_hdd0, "$(EmulatorDir)", GetEmuDir());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Emulator::GetSfoDirFromGamePath(const std::string& game_path, const std::string& user)
|
||||||
|
{
|
||||||
|
if (fs::is_file(game_path + "/PS3_DISC.SFB"))
|
||||||
|
{
|
||||||
|
// This is a disc game.
|
||||||
|
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");
|
||||||
|
const std::string content_id = get_string(psf, "CONTENT_ID");
|
||||||
|
if (category == "HG" && !content_id.empty())
|
||||||
|
{
|
||||||
|
// This is a trial game. Check if the user has a RAP file to unlock it.
|
||||||
|
const std::string rap_path = GetHddDir() + "home/" + user + "/exdata/" + content_id + ".rap";
|
||||||
|
if (fs::is_file(rap_path) && fs::is_file(game_path + "/C00/PARAM.SFO"))
|
||||||
|
{
|
||||||
|
// Load full game data.
|
||||||
|
return game_path + "/C00";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return game_path;
|
||||||
|
}
|
||||||
|
|
||||||
void Emulator::SetForceBoot(bool force_boot)
|
void Emulator::SetForceBoot(bool force_boot)
|
||||||
{
|
{
|
||||||
m_force_boot = force_boot;
|
m_force_boot = force_boot;
|
||||||
|
@ -600,42 +626,43 @@ void Emulator::Load(bool add_only)
|
||||||
const std::string elf_dir = fs::get_parent_dir(m_path);
|
const std::string elf_dir = fs::get_parent_dir(m_path);
|
||||||
|
|
||||||
// Load PARAM.SFO (TODO)
|
// Load PARAM.SFO (TODO)
|
||||||
const auto _psf = psf::load_object([&]() -> fs::file
|
psf::registry _psf;
|
||||||
{
|
|
||||||
if (fs::file sfov{elf_dir + "/sce_sys/param.sfo"})
|
if (fs::file sfov{elf_dir + "/sce_sys/param.sfo"})
|
||||||
{
|
{
|
||||||
return sfov;
|
m_sfo_dir = elf_dir;
|
||||||
|
_psf = psf::load_object(sfov);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (fs::is_dir(m_path))
|
if (fs::is_dir(m_path))
|
||||||
{
|
{
|
||||||
// Special case (directory scan)
|
// Special case (directory scan)
|
||||||
if (fs::file sfo{m_path + "/PS3_GAME/PARAM.SFO"})
|
m_sfo_dir = GetSfoDirFromGamePath(m_path, GetUsr());
|
||||||
{
|
|
||||||
return sfo;
|
|
||||||
}
|
}
|
||||||
|
else if (disc.size())
|
||||||
return fs::file{m_path + "/PARAM.SFO"};
|
|
||||||
}
|
|
||||||
|
|
||||||
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")
|
||||||
{
|
{
|
||||||
return fs::file{disc + "/PS3_GAME/PARAM.SFO"};
|
m_sfo_dir = disc + "/PS3_GAME";
|
||||||
}
|
}
|
||||||
|
else if (m_cat == "GD")
|
||||||
if (m_cat == "GD")
|
|
||||||
{
|
{
|
||||||
return fs::file{GetHddDir() + "game/" + m_title_id + "/PARAM.SFO"};
|
m_sfo_dir = GetHddDir() + "game/" + m_title_id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_sfo_dir = GetSfoDirFromGamePath(disc, GetUsr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_sfo_dir = GetSfoDirFromGamePath(fs::get_parent_dir(elf_dir), GetUsr());
|
||||||
}
|
}
|
||||||
|
|
||||||
return fs::file{disc + "/PARAM.SFO"};
|
_psf = psf::load_object(fs::file(m_sfo_dir + "/PARAM.SFO"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return fs::file{elf_dir + "/../PARAM.SFO"};
|
|
||||||
}());
|
|
||||||
m_title = psf::get_string(_psf, "TITLE", m_path.substr(m_path.find_last_of('/') + 1));
|
m_title = psf::get_string(_psf, "TITLE", m_path.substr(m_path.find_last_of('/') + 1));
|
||||||
m_title_id = psf::get_string(_psf, "TITLE_ID");
|
m_title_id = psf::get_string(_psf, "TITLE_ID");
|
||||||
m_cat = psf::get_string(_psf, "CATEGORY");
|
m_cat = psf::get_string(_psf, "CATEGORY");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "VFS.h"
|
#include "VFS.h"
|
||||||
#include "Utilities/Atomic.h"
|
#include "Utilities/Atomic.h"
|
||||||
|
@ -215,6 +215,7 @@ class Emulator final
|
||||||
std::string m_title;
|
std::string m_title;
|
||||||
std::string m_cat;
|
std::string m_cat;
|
||||||
std::string m_dir;
|
std::string m_dir;
|
||||||
|
std::string m_sfo_dir;
|
||||||
std::string m_usr{"00000001"};
|
std::string m_usr{"00000001"};
|
||||||
u32 m_usrid{1};
|
u32 m_usrid{1};
|
||||||
|
|
||||||
|
@ -285,6 +286,11 @@ public:
|
||||||
return m_dir;
|
return m_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string& GetSfoDir() const
|
||||||
|
{
|
||||||
|
return m_sfo_dir;
|
||||||
|
}
|
||||||
|
|
||||||
// String for GUI dialogs.
|
// String for GUI dialogs.
|
||||||
const std::string& GetUsr() const
|
const std::string& GetUsr() const
|
||||||
{
|
{
|
||||||
|
@ -312,6 +318,7 @@ private:
|
||||||
static std::string GetEmuDir();
|
static std::string GetEmuDir();
|
||||||
public:
|
public:
|
||||||
static std::string GetHddDir();
|
static std::string GetHddDir();
|
||||||
|
static std::string GetSfoDirFromGamePath(const std::string& game_path, const std::string& user);
|
||||||
|
|
||||||
void SetForceBoot(bool force_boot);
|
void SetForceBoot(bool force_boot);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "game_list_frame.h"
|
#include "game_list_frame.h"
|
||||||
#include "qt_utils.h"
|
#include "qt_utils.h"
|
||||||
#include "settings_dialog.h"
|
#include "settings_dialog.h"
|
||||||
#include "table_item_delegate.h"
|
#include "table_item_delegate.h"
|
||||||
|
@ -393,10 +393,8 @@ void game_list_frame::Refresh(const bool fromDrive, const bool scrollAfter)
|
||||||
|
|
||||||
for (const auto& dir : path_list) { try
|
for (const auto& dir : path_list) { try
|
||||||
{
|
{
|
||||||
const std::string sfb = dir + "/PS3_DISC.SFB";
|
const std::string sfo_dir = Emu.GetSfoDirFromGamePath(dir, Emu.GetUsr());
|
||||||
const std::string sfo = dir + (fs::is_file(sfb) ? "/PS3_GAME/PARAM.SFO" : "/PARAM.SFO");
|
const fs::file sfo_file(sfo_dir + "/PARAM.SFO");
|
||||||
|
|
||||||
const fs::file sfo_file(sfo);
|
|
||||||
if (!sfo_file)
|
if (!sfo_file)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -430,29 +428,21 @@ void game_list_frame::Refresh(const bool fromDrive, const bool scrollAfter)
|
||||||
auto cat = category::cat_boot.find(game.category);
|
auto cat = category::cat_boot.find(game.category);
|
||||||
if (cat != category::cat_boot.end())
|
if (cat != category::cat_boot.end())
|
||||||
{
|
{
|
||||||
if (game.category == "DG")
|
game.icon_path = sfo_dir + "/ICON0.PNG";
|
||||||
{
|
|
||||||
game.icon_path = dir + "/PS3_GAME/ICON0.PNG";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
game.icon_path = dir + "/ICON0.PNG";
|
|
||||||
}
|
|
||||||
|
|
||||||
game.category = sstr(cat->second);
|
game.category = sstr(cat->second);
|
||||||
}
|
}
|
||||||
else if ((cat = category::cat_data.find(game.category)) != category::cat_data.end())
|
else if ((cat = category::cat_data.find(game.category)) != category::cat_data.end())
|
||||||
{
|
{
|
||||||
game.icon_path = dir + "/ICON0.PNG";
|
game.icon_path = sfo_dir + "/ICON0.PNG";
|
||||||
game.category = sstr(cat->second);
|
game.category = sstr(cat->second);
|
||||||
}
|
}
|
||||||
else if (game.category == sstr(category::unknown))
|
else if (game.category == sstr(category::unknown))
|
||||||
{
|
{
|
||||||
game.icon_path = dir + "/ICON0.PNG";
|
game.icon_path = sfo_dir + "/ICON0.PNG";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
game.icon_path = dir + "/ICON0.PNG";
|
game.icon_path = sfo_dir + "/ICON0.PNG";
|
||||||
game.category = sstr(category::other);
|
game.category = sstr(category::other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,15 +189,13 @@ void main_window::SetAppIconFromPath(const std::string& path)
|
||||||
{
|
{
|
||||||
// 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);
|
QString qpath = qstr(path);
|
||||||
std::string icon_list[] = { "/ICON0.PNG", "/PS3_GAME/ICON0.PNG" };
|
|
||||||
std::string path_list[] = { path, sstr(qpath.section("/", 0, -2)), sstr(qpath.section("/", 0, -3)) };
|
std::string path_list[] = { path, sstr(qpath.section("/", 0, -2)), sstr(qpath.section("/", 0, -3)) };
|
||||||
for (std::string pth : path_list)
|
for (std::string pth : path_list)
|
||||||
{
|
{
|
||||||
if (!fs::is_dir(pth)) continue;
|
if (!fs::is_dir(pth)) continue;
|
||||||
|
|
||||||
for (std::string ico : icon_list)
|
const std::string sfo_dir = Emu.GetSfoDirFromGamePath(path, Emu.GetUsr());
|
||||||
{
|
const std::string ico = sfo_dir + "/ICON0.PNG";
|
||||||
ico = pth + ico;
|
|
||||||
if (fs::is_file(ico))
|
if (fs::is_file(ico))
|
||||||
{
|
{
|
||||||
// load the image from path. It will most likely be a rectangle
|
// load the image from path. It will most likely be a rectangle
|
||||||
|
@ -210,8 +208,7 @@ void main_window::SetAppIconFromPath(const std::string& path)
|
||||||
dest.fill(QColor("transparent"));
|
dest.fill(QColor("transparent"));
|
||||||
|
|
||||||
// get the location to draw the source image centered within the dest image.
|
// get the location to draw the source image centered within the dest image.
|
||||||
QPoint destPos = source.width() > source.height() ? QPoint(0, (source.width() - source.height()) / 2)
|
QPoint destPos = source.width() > source.height() ? QPoint(0, (source.width() - source.height()) / 2) : QPoint((source.height() - source.width()) / 2, 0);
|
||||||
: QPoint((source.height() - source.width()) / 2, 0);
|
|
||||||
|
|
||||||
// Paint the source into/over the dest
|
// Paint the source into/over the dest
|
||||||
QPainter painter(&dest);
|
QPainter painter(&dest);
|
||||||
|
@ -223,7 +220,6 @@ void main_window::SetAppIconFromPath(const std::string& path)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// if nothing was found reset the icon to default
|
// if nothing was found reset the icon to default
|
||||||
m_appIcon = QApplication::windowIcon();
|
m_appIcon = QApplication::windowIcon();
|
||||||
}
|
}
|
||||||
|
@ -1290,8 +1286,9 @@ void main_window::CreateConnects()
|
||||||
|
|
||||||
connect(ui->actionManage_Users, &QAction::triggered, [=]
|
connect(ui->actionManage_Users, &QAction::triggered, [=]
|
||||||
{
|
{
|
||||||
user_manager_dialog* user_manager = new user_manager_dialog(guiSettings, this);
|
user_manager_dialog user_manager(guiSettings, this);
|
||||||
user_manager->show();
|
user_manager.exec();
|
||||||
|
m_gameListFrame->Refresh(true); // New user may have different games unlocked.
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->toolsCgDisasmAct, &QAction::triggered, [=]
|
connect(ui->toolsCgDisasmAct, &QAction::triggered, [=]
|
||||||
|
@ -1832,6 +1829,9 @@ void main_window::dropEvent(QDropEvent* event)
|
||||||
LOG_SUCCESS(GENERAL, "Successfully copied rap file by drop: %s", rapname);
|
LOG_SUCCESS(GENERAL, "Successfully copied rap file by drop: %s", rapname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Refresh game list since we probably unlocked some games now.
|
||||||
|
m_gameListFrame->Refresh(true);
|
||||||
break;
|
break;
|
||||||
case drop_type::drop_dir: // import valid games to gamelist (games.yaml)
|
case drop_type::drop_dir: // import valid games to gamelist (games.yaml)
|
||||||
for (const auto& path : dropPaths)
|
for (const auto& path : dropPaths)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue