mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-14 10:21:21 +00:00
VSH/UI: Add VSH to game grid
* Custom VSH config. * VSH shortcut creation.
This commit is contained in:
parent
8cf28730cb
commit
8eefbcae45
@ -855,12 +855,14 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||
|
||||
bool resolve_path_as_vfs_path = false;
|
||||
|
||||
const bool from_dev_flash = IsPathInsideDir(m_path, g_cfg_vfs.get_dev_flash());
|
||||
|
||||
if (m_ar)
|
||||
{
|
||||
struct file_header
|
||||
{
|
||||
ENABLE_BITWISE_SERIALIZATION;
|
||||
|
||||
|
||||
nse_t<u64, 1> magic;
|
||||
bool LE_format;
|
||||
bool state_inspection_support;
|
||||
@ -874,14 +876,14 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||
{
|
||||
return game_boot_result::savestate_corrupted;
|
||||
}
|
||||
|
||||
|
||||
if (header.LE_format != (std::endian::native == std::endian::little) || header.offset >= m_ar->data.size())
|
||||
{
|
||||
return game_boot_result::savestate_corrupted;
|
||||
}
|
||||
|
||||
g_cfg.savestate.state_inspection_mode.set(header.state_inspection_support);
|
||||
|
||||
|
||||
// Emulate seek operation (please avoid using in other places)
|
||||
m_ar->pos = header.offset;
|
||||
|
||||
@ -894,7 +896,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||
|
||||
argv.clear();
|
||||
klic.clear();
|
||||
|
||||
|
||||
std::string disc_info;
|
||||
(*m_ar)(argv.emplace_back(), disc_info, klic.emplace_back(), m_game_dir, hdd1);
|
||||
|
||||
@ -907,7 +909,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||
{
|
||||
// Restore disc path for disc games (must exist in games.yml i.e. your game library)
|
||||
m_title_id = disc_info;
|
||||
|
||||
|
||||
// Load /dev_bdvd/ from game list if available
|
||||
if (auto node = games[m_title_id])
|
||||
{
|
||||
@ -1189,39 +1191,32 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||
}
|
||||
else if (m_config_mode == cfg_mode::custom)
|
||||
{
|
||||
const std::string config_path = rpcs3::utils::get_custom_config_path(m_title_id);
|
||||
|
||||
// Load custom config-1
|
||||
if (fs::file cfg_file{ config_path })
|
||||
// Load custom configs
|
||||
for (std::string config_path :
|
||||
{
|
||||
sys_log.notice("Applying custom config: %s", config_path);
|
||||
|
||||
if (g_cfg.from_string(cfg_file.to_string()))
|
||||
m_path + ".yml",
|
||||
rpcs3::utils::get_custom_config_path(from_dev_flash ? m_path.substr(m_path.find_last_of(fs::delim) + 1) : m_title_id),
|
||||
})
|
||||
{
|
||||
if (config_path.empty())
|
||||
{
|
||||
g_cfg.name = config_path;
|
||||
m_config_path = config_path;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
||||
if (fs::file cfg_file{config_path})
|
||||
{
|
||||
sys_log.notice("Applying custom config: %s", config_path);
|
||||
|
||||
if (g_cfg.from_string(cfg_file.to_string()))
|
||||
{
|
||||
g_cfg.name = config_path;
|
||||
m_config_path = config_path;
|
||||
break;
|
||||
}
|
||||
|
||||
sys_log.fatal("Failed to apply custom config: %s", config_path);
|
||||
}
|
||||
}
|
||||
|
||||
// Load custom config-2
|
||||
if (fs::file cfg_file{ m_path + ".yml" })
|
||||
{
|
||||
sys_log.notice("Applying custom config: %s.yml", m_path);
|
||||
|
||||
if (g_cfg.from_string(cfg_file.to_string()))
|
||||
{
|
||||
g_cfg.name = m_path + ".yml";
|
||||
m_config_path = g_cfg.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
sys_log.fatal("Failed to apply custom config: %s.yml", m_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable incompatible settings
|
||||
@ -1441,7 +1436,6 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||
// Detect boot location
|
||||
const std::string hdd0_game = vfs::get("/dev_hdd0/game/");
|
||||
const bool from_hdd0_game = IsPathInsideDir(m_path, hdd0_game);
|
||||
const bool from_dev_flash = IsPathInsideDir(m_path, g_cfg_vfs.get_dev_flash());
|
||||
|
||||
#ifdef _WIN32
|
||||
// m_path might be passed from command line with differences in uppercase/lowercase on windows.
|
||||
|
@ -352,9 +352,14 @@ namespace rpcs3::utils
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string get_custom_config_path(const std::string& title_id)
|
||||
std::string get_custom_config_path(const std::string& identifier)
|
||||
{
|
||||
return get_custom_config_dir() + "config_" + title_id + ".yml";
|
||||
if (identifier.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return get_custom_config_dir() + "config_" + identifier + ".yml";
|
||||
}
|
||||
|
||||
std::string get_input_config_root()
|
||||
|
@ -31,7 +31,7 @@ namespace rpcs3::utils
|
||||
std::string get_sfo_dir_from_game_path(const std::string& game_path, const std::string& title_id = "");
|
||||
|
||||
std::string get_custom_config_dir();
|
||||
std::string get_custom_config_path(const std::string& title_id);
|
||||
std::string get_custom_config_path(const std::string& identifier);
|
||||
|
||||
std::string get_input_config_root();
|
||||
std::string get_input_config_dir(const std::string& title_id = "");
|
||||
|
@ -42,11 +42,13 @@ namespace cat
|
||||
const QString cat_ps3_save = "SD";
|
||||
const QString cat_psp_save = "MS";
|
||||
|
||||
const QString cat_ps3_os = "/OS";
|
||||
|
||||
const QString cat_unknown = "Unknown";
|
||||
|
||||
const QStringList ps2_games = { cat_ps2_game, cat_ps2_inst };
|
||||
const QStringList psp_games = { cat_psp_game, cat_psp_mini, cat_psp_rema };
|
||||
const QStringList media = { cat_app_photo, cat_app_video, cat_bc_video, cat_app_music, cat_app_store, cat_app_tv, cat_web_tv };
|
||||
const QStringList data = { cat_ps3_data, cat_ps2_data, cat_ps3_save, cat_psp_save };
|
||||
const QStringList others = { cat_network, cat_store_fe };
|
||||
const QStringList others = { cat_network, cat_store_fe, cat_ps3_os };
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/system_config.h"
|
||||
#include "Emu/vfs_config.h"
|
||||
#include "Emu/system_utils.hpp"
|
||||
#include "Emu/Cell/Modules/cellSysutil.h"
|
||||
#include "Emu/Io/Keyboard.h"
|
||||
@ -136,10 +137,9 @@ void emu_settings::LoadSettings(const std::string& title_id)
|
||||
// Otherwise we'll always trigger the "obsolete settings dialog" when editing custom configs.
|
||||
ValidateSettings(true);
|
||||
|
||||
const std::string config_path = rpcs3::utils::get_custom_config_path(m_title_id);
|
||||
std::string custom_config_path;
|
||||
|
||||
if (fs::is_file(config_path))
|
||||
if (std::string config_path = rpcs3::utils::get_custom_config_path(m_title_id); fs::is_file(config_path))
|
||||
{
|
||||
custom_config_path = config_path;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "Utilities/File.h"
|
||||
#include "Utilities/mutex.h"
|
||||
#include "util/yaml.hpp"
|
||||
#include "util/sysinfo.hpp"
|
||||
#include "Input/pad_thread.h"
|
||||
|
||||
#include <algorithm>
|
||||
@ -580,48 +581,84 @@ void game_list_frame::Refresh(const bool from_drive, const bool scroll_after)
|
||||
}
|
||||
}
|
||||
|
||||
const auto dev_flash = g_cfg_vfs.get_dev_flash();
|
||||
|
||||
m_path_list.emplace_back(dev_flash + "vsh/module/vsh.self");
|
||||
|
||||
// Remove duplicates
|
||||
sort(m_path_list.begin(), m_path_list.end());
|
||||
m_path_list.erase(unique(m_path_list.begin(), m_path_list.end()), m_path_list.end());
|
||||
|
||||
const std::string game_icon_path = m_play_hover_movies ? fs::get_config_dir() + "/Icons/game_icons/" : "";
|
||||
|
||||
m_refresh_watcher.setFuture(QtConcurrent::map(m_path_list, [this, cat_unknown_localized = sstr(localized.category.unknown), cat_unknown = sstr(cat::cat_unknown), game_icon_path](const std::string& dir)
|
||||
m_refresh_watcher.setFuture(QtConcurrent::map(m_path_list, [this, dev_flash, cat_unknown_localized = sstr(localized.category.unknown), cat_unknown = sstr(cat::cat_unknown), game_icon_path](const std::string& dir_or_elf)
|
||||
{
|
||||
GameInfo game{};
|
||||
game.path = dir_or_elf;
|
||||
|
||||
const Localized thread_localized;
|
||||
|
||||
const std::string sfo_dir = rpcs3::utils::get_sfo_dir_from_game_path(dir);
|
||||
const std::string sfo_dir = rpcs3::utils::get_sfo_dir_from_game_path(dir_or_elf);
|
||||
const psf::registry psf = psf::load_object(sfo_dir + "/PARAM.SFO");
|
||||
const std::string_view title_id = psf::get_string(psf, "TITLE_ID", "");
|
||||
|
||||
if (title_id.empty())
|
||||
{
|
||||
// Do not care about invalid entries
|
||||
return;
|
||||
}
|
||||
if (!fs::is_file(dir_or_elf))
|
||||
{
|
||||
// Do not care about invalid entries
|
||||
return;
|
||||
}
|
||||
|
||||
GameInfo game{};
|
||||
game.path = dir;
|
||||
game.serial = std::string(title_id);
|
||||
game.name = std::string(psf::get_string(psf, "TITLE", cat_unknown_localized));
|
||||
game.app_ver = std::string(psf::get_string(psf, "APP_VER", cat_unknown_localized));
|
||||
game.version = std::string(psf::get_string(psf, "VERSION", cat_unknown_localized));
|
||||
game.category = std::string(psf::get_string(psf, "CATEGORY", cat_unknown));
|
||||
game.fw = std::string(psf::get_string(psf, "PS3_SYSTEM_VER", cat_unknown_localized));
|
||||
game.parental_lvl = psf::get_integer(psf, "PARENTAL_LEVEL", 0);
|
||||
game.resolution = psf::get_integer(psf, "RESOLUTION", 0);
|
||||
game.sound_format = psf::get_integer(psf, "SOUND_FORMAT", 0);
|
||||
game.bootable = psf::get_integer(psf, "BOOTABLE", 0);
|
||||
game.attr = psf::get_integer(psf, "ATTRIBUTE", 0);
|
||||
game.serial = dir_or_elf.substr(dir_or_elf.find_last_of(fs::delim) + 1);
|
||||
game.category = cat::cat_ps3_os.toStdString(); // Key for operating system executables
|
||||
game.version = utils::get_firmware_version();
|
||||
game.fw = game.version;
|
||||
game.bootable = 1;
|
||||
game.icon_path = dev_flash + "vsh/resource/explore/icon/icon_home.png";
|
||||
|
||||
if (dir_or_elf.starts_with(dev_flash))
|
||||
{
|
||||
std::string path_vfs = dir_or_elf.substr(dev_flash.size());
|
||||
|
||||
if (usz pos = path_vfs.find_first_not_of(fs::delim); pos != umax && pos != 0)
|
||||
{
|
||||
path_vfs = path_vfs.substr(pos);
|
||||
}
|
||||
|
||||
if (Localized().title.titles.contains(path_vfs))
|
||||
{
|
||||
game.name = Localized().title.titles.at(path_vfs).toStdString();
|
||||
}
|
||||
}
|
||||
|
||||
if (game.name == "Unknown")
|
||||
{
|
||||
game.name = game.serial;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
game.serial = std::string(title_id);
|
||||
game.name = std::string(psf::get_string(psf, "TITLE", cat_unknown_localized));
|
||||
game.app_ver = std::string(psf::get_string(psf, "APP_VER", cat_unknown_localized));
|
||||
game.version = std::string(psf::get_string(psf, "VERSION", cat_unknown_localized));
|
||||
game.category = std::string(psf::get_string(psf, "CATEGORY", cat_unknown));
|
||||
game.fw = std::string(psf::get_string(psf, "PS3_SYSTEM_VER", cat_unknown_localized));
|
||||
game.parental_lvl = psf::get_integer(psf, "PARENTAL_LEVEL", 0);
|
||||
game.resolution = psf::get_integer(psf, "RESOLUTION", 0);
|
||||
game.sound_format = psf::get_integer(psf, "SOUND_FORMAT", 0);
|
||||
game.bootable = psf::get_integer(psf, "BOOTABLE", 0);
|
||||
game.attr = psf::get_integer(psf, "ATTRIBUTE", 0);
|
||||
game.icon_path = sfo_dir + "/ICON0.PNG";
|
||||
}
|
||||
|
||||
if (m_show_custom_icons)
|
||||
{
|
||||
game.icon_path = fs::get_config_dir() + "/Icons/game_icons/" + game.serial + "/ICON0.PNG";
|
||||
}
|
||||
|
||||
if (!m_show_custom_icons || !fs::is_file(game.icon_path))
|
||||
{
|
||||
game.icon_path = sfo_dir + "/ICON0.PNG";
|
||||
if (std::string icon_path = fs::get_config_dir() + "/Icons/game_icons/" + game.serial + "/ICON0.PNG"; fs::is_file(icon_path))
|
||||
{
|
||||
game.icon_path = std::move(icon_path);
|
||||
}
|
||||
}
|
||||
|
||||
m_mutex_cat.lock();
|
||||
@ -916,6 +953,8 @@ void game_list_frame::CreateShortcuts(const game_info& gameinfo, const std::set<
|
||||
|
||||
std::string gameid_token_value;
|
||||
|
||||
const std::string dev_flash = g_cfg_vfs.get_dev_flash();
|
||||
|
||||
if (gameinfo->info.category == "DG" && !fs::is_file(rpcs3::utils::get_hdd0_dir() + "/game/" + gameinfo->info.serial + "/USRDIR/EBOOT.BIN"))
|
||||
{
|
||||
const usz ps3_game_dir_pos = fs::get_parent_dir(gameinfo->info.path).size();
|
||||
@ -948,9 +987,11 @@ void game_list_frame::CreateShortcuts(const game_info& gameinfo, const std::set<
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
const std::string target_cli_args = fmt::format("--no-gui \"%%%%RPCS3_GAMEID%%%%:%s\"", gameid_token_value);
|
||||
const std::string target_cli_args = gameinfo->info.path.starts_with(dev_flash) ? fmt::format("--no-gui \"%%%%RPCS3_VFS%%%%:dev_flash/%s\"", gameinfo->info.path.substr(dev_flash.size()))
|
||||
: fmt::format("--no-gui \"%%%%RPCS3_GAMEID%%%%:%s\"", gameid_token_value);
|
||||
#else
|
||||
const std::string target_cli_args = fmt::format("--no-gui \"%%RPCS3_GAMEID%%:%s\"", gameid_token_value);
|
||||
const std::string target_cli_args = gameinfo->info.path.starts_with(dev_flash) ? fmt::format("--no-gui \"%%RPCS3_VFS%%:dev_flash/%s\"", gameinfo->info.path.substr(dev_flash.size()))
|
||||
: fmt::format("--no-gui \"%%RPCS3_GAMEID%%:%s\"", gameid_token_value);
|
||||
#endif
|
||||
const std::string target_icon_dir = fmt::format("%sIcons/game_icons/%s/", fs::get_config_dir(), gameinfo->info.serial);
|
||||
|
||||
@ -1566,7 +1607,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
||||
// Disable options depending on software category
|
||||
const QString category = qstr(current_game.category);
|
||||
|
||||
if (category == cat::cat_disc_game)
|
||||
if (category == cat::cat_disc_game || category == cat::cat_ps3_os)
|
||||
{
|
||||
remove_game->setEnabled(false);
|
||||
}
|
||||
|
@ -69,3 +69,10 @@ Localized::sound::sound()
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
Localized::title_t::title_t()
|
||||
: titles({
|
||||
{ "vsh/module/vsh.self", tr("XMB (VSH)") },
|
||||
})
|
||||
{
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ public:
|
||||
const QString network = tr("Network");
|
||||
const QString store_fe = tr("Store");
|
||||
const QString web_tv = tr("Web TV");
|
||||
const QString os_app = tr("Operating System");
|
||||
|
||||
// PS2 bootable
|
||||
const QString ps2_game = tr("PS2 Classics");
|
||||
@ -79,6 +80,7 @@ public:
|
||||
{ cat::cat_psp_game , psp_game }, // psp_games
|
||||
{ cat::cat_psp_mini , psp_mini }, // psp_games
|
||||
{ cat::cat_psp_rema , psp_rema }, // psp_games
|
||||
{ cat::cat_ps3_os , os_app }, // other
|
||||
};
|
||||
|
||||
const localized_cat cat_data =
|
||||
@ -122,4 +124,10 @@ public:
|
||||
sound();
|
||||
const std::map<u32, QString> format;
|
||||
} sound;
|
||||
|
||||
const struct title_t
|
||||
{
|
||||
title_t();
|
||||
const std::map<std::string, QString> titles;
|
||||
} title;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user