mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-19 19:15:26 +00:00
Merge branch 'master' into AVX10
This commit is contained in:
commit
55a918bdab
15 changed files with 163 additions and 128 deletions
|
@ -62,7 +62,7 @@ namespace rsx
|
|||
|
||||
if (fs::exists(avatar_path))
|
||||
{
|
||||
icon_data = std::make_unique<image_info>(avatar_path.c_str());
|
||||
icon_data = std::make_unique<image_info>(avatar_path);
|
||||
static_cast<image_view*>(image.get())->set_raw_image(icon_data.get());
|
||||
}
|
||||
else
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace rsx
|
|||
|
||||
if (fs::exists(icon_path))
|
||||
{
|
||||
icon_data = std::make_unique<image_info>(icon_path.c_str(), details.hidden || locked);
|
||||
icon_data = std::make_unique<image_info>(icon_path, details.hidden || locked);
|
||||
static_cast<image_view*>(image.get())->set_raw_image(icon_data.get());
|
||||
}
|
||||
else
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace rsx
|
|||
animated_icon::animated_icon(const char* icon_name)
|
||||
{
|
||||
const std::string image_path = fmt::format("%s/Icons/ui/%s", fs::get_config_dir(), icon_name);
|
||||
m_icon = std::make_unique<image_info>(image_path.c_str());
|
||||
m_icon = std::make_unique<image_info>(image_path);
|
||||
set_raw_image(m_icon.get());
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace rsx
|
|||
return result;
|
||||
}
|
||||
|
||||
image_info::image_info(const char* filename, bool grayscaled)
|
||||
image_info::image_info(const std::string& filename, bool grayscaled)
|
||||
{
|
||||
fs::file f(filename, fs::read + fs::isfile);
|
||||
|
||||
|
@ -132,7 +132,7 @@ namespace rsx
|
|||
{
|
||||
// First check the global config dir
|
||||
const std::string image_path = fs::get_config_dir() + "Icons/ui/" + res;
|
||||
auto info = std::make_unique<image_info>(image_path.c_str());
|
||||
auto info = std::make_unique<image_info>(image_path);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__) && defined(DATADIR)
|
||||
// Check the DATADIR if defined
|
||||
|
@ -140,7 +140,7 @@ namespace rsx
|
|||
{
|
||||
const std::string data_dir (DATADIR);
|
||||
const std::string image_data = data_dir + "/Icons/ui/" + res;
|
||||
info = std::make_unique<image_info>(image_data.c_str());
|
||||
info = std::make_unique<image_info>(image_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -148,7 +148,7 @@ namespace rsx
|
|||
{
|
||||
// Resource was not found in the DATADIR or config dir, try and grab from relative path (linux)
|
||||
std::string src = "Icons/ui/" + res;
|
||||
info = std::make_unique<image_info>(src.c_str());
|
||||
info = std::make_unique<image_info>(src);
|
||||
#ifndef _WIN32
|
||||
// Check for Icons in ../share/rpcs3 for AppImages,
|
||||
// in rpcs3.app/Contents/Resources for App Bundles, and /usr/bin.
|
||||
|
@ -188,12 +188,12 @@ namespace rsx
|
|||
#else
|
||||
src = executablePath + "/../share/rpcs3/Icons/ui/" + res;
|
||||
#endif
|
||||
info = std::make_unique<image_info>(src.c_str());
|
||||
info = std::make_unique<image_info>(src);
|
||||
// Check if the icons are in the same directory as the executable (local builds)
|
||||
if (info->get_data() == nullptr)
|
||||
{
|
||||
src = executablePath + "/Icons/ui/" + res;
|
||||
info = std::make_unique<image_info>(src.c_str());
|
||||
info = std::make_unique<image_info>(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace rsx
|
|||
int bpp = 0;
|
||||
|
||||
image_info(image_info&) = delete;
|
||||
image_info(const char* filename, bool grayscaled = false);
|
||||
image_info(const std::string& filename, bool grayscaled = false);
|
||||
image_info(const std::vector<u8>& bytes, bool grayscaled = false);
|
||||
~image_info();
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace rsx
|
|||
}
|
||||
}
|
||||
|
||||
icon_data = std::make_unique<image_info>(entry.info.path.c_str());
|
||||
icon_data = std::make_unique<image_info>(entry.info.path);
|
||||
static_cast<image_view*>(image.get())->set_raw_image(icon_data.get());
|
||||
}
|
||||
else
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "overlay_message_dialog.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/system_config.h"
|
||||
#include "Emu/system_utils.hpp"
|
||||
#include "Emu/Cell/ErrorCodes.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Utilities/Thread.h"
|
||||
|
@ -95,6 +96,11 @@ namespace rsx
|
|||
if (background_image && background_image->get_data())
|
||||
{
|
||||
result.add(background_poster.get_compiled());
|
||||
|
||||
if (background_overlay_image && background_overlay_image->get_data())
|
||||
{
|
||||
result.add(background_overlay_poster.get_compiled());
|
||||
}
|
||||
}
|
||||
|
||||
result.add(background.get_compiled());
|
||||
|
@ -356,10 +362,28 @@ namespace rsx
|
|||
|
||||
if (!background_image)
|
||||
{
|
||||
if (const auto picture_path = Emu.GetBackgroundPicturePath(); fs::exists(picture_path))
|
||||
// Search for any useable background picture in the given order
|
||||
game_content_type content_type = game_content_type::background_picture;
|
||||
|
||||
for (game_content_type type : { game_content_type::background_picture, game_content_type::overlay_picture, game_content_type::content_icon })
|
||||
{
|
||||
background_image = std::make_unique<image_info>(picture_path.c_str());
|
||||
dirty |= !!background_image->get_data();
|
||||
if (const std::string picture_path = rpcs3::utils::get_game_content_path(type); !picture_path.empty())
|
||||
{
|
||||
content_type = type;
|
||||
background_image = std::make_unique<image_info>(picture_path);
|
||||
dirty |= !!background_image->get_data();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Search for an overlay picture in the same dir in case we found a real background picture
|
||||
if (background_image && !background_overlay_image && content_type == game_content_type::background_picture)
|
||||
{
|
||||
if (const std::string picture_path = rpcs3::utils::get_game_content_path(game_content_type::overlay_picture); !picture_path.empty())
|
||||
{
|
||||
background_overlay_image = std::make_unique<image_info>(picture_path);
|
||||
dirty |= !!background_overlay_image->get_data();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -388,6 +412,23 @@ namespace rsx
|
|||
const int padding = (background_poster.w - static_cast<int>(background_image->w * (background_poster.h / static_cast<double>(background_image->h)))) / 2;
|
||||
background_poster.set_padding(padding, padding, 0, 0);
|
||||
}
|
||||
|
||||
if (background_overlay_image && background_overlay_image->get_data())
|
||||
{
|
||||
constexpr f32 reference_factor = 2.0f / 3.0f;
|
||||
const f32 image_aspect = background_overlay_image->w / static_cast<f32>(background_overlay_image->h);
|
||||
const f32 overlay_width = background_overlay_image->w * reference_factor;
|
||||
const f32 overlay_height = overlay_width / image_aspect;
|
||||
const u16 overlay_x = static_cast<u16>(std::min(virtual_width - overlay_width, (virtual_width * reference_factor) - (overlay_width / 2.0f)));
|
||||
const u16 overlay_y = static_cast<u16>(std::min(virtual_height - overlay_height, (virtual_height * reference_factor) - (overlay_height / 2.0f)));
|
||||
const f32 color = (100 - background_darkening_strength) / 100.f;
|
||||
|
||||
background_overlay_poster.fore_color = color4f(color, color, color, 1.);
|
||||
background_overlay_poster.set_size(static_cast<u16>(overlay_width), static_cast<u16>(overlay_height));
|
||||
background_overlay_poster.set_pos(overlay_x, overlay_y);
|
||||
background_overlay_poster.set_raw_image(background_overlay_image.get());
|
||||
background_overlay_poster.set_blur_strength(static_cast<u8>(background_blur_strength));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -397,6 +438,13 @@ namespace rsx
|
|||
background_poster.clear_image();
|
||||
background_image.reset();
|
||||
}
|
||||
|
||||
if (background_overlay_image)
|
||||
{
|
||||
background_overlay_poster.clear_image();
|
||||
background_overlay_image.reset();
|
||||
}
|
||||
|
||||
background.back_color.a = 0.85f;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,10 @@ namespace rsx
|
|||
image_button btn_ok;
|
||||
image_button btn_cancel;
|
||||
|
||||
overlay_element bottom_bar, background;
|
||||
overlay_element bottom_bar;
|
||||
overlay_element background;
|
||||
image_view background_poster;
|
||||
image_view background_overlay_poster;
|
||||
std::array<progress_bar, 2> progress_bars{};
|
||||
u8 num_progress_bars = 0;
|
||||
s32 taskbar_index = 0;
|
||||
|
@ -31,6 +33,7 @@ namespace rsx
|
|||
u32 background_blur_strength = 0;
|
||||
u32 background_darkening_strength = 0;
|
||||
std::unique_ptr<image_info> background_image;
|
||||
std::unique_ptr<image_info> background_overlay_image;
|
||||
|
||||
animation_color_interpolate fade_animation;
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace rsx
|
|||
|
||||
if (fs::exists(avatar_path))
|
||||
{
|
||||
icon_data = std::make_unique<image_info>(avatar_path.c_str());
|
||||
icon_data = std::make_unique<image_info>(avatar_path);
|
||||
static_cast<image_view*>(image.get())->set_raw_image(icon_data.get());
|
||||
}
|
||||
else
|
||||
|
|
|
@ -753,99 +753,6 @@ void Emulator::SetUsr(const std::string& user)
|
|||
m_usr = user;
|
||||
}
|
||||
|
||||
std::string Emulator::GetBackgroundPicturePath() const
|
||||
{
|
||||
// Try to find a custom icon first
|
||||
std::string path = fs::get_config_dir() + "/Icons/game_icons/" + GetTitleID() + "/PIC1.PNG";
|
||||
|
||||
if (fs::is_file(path))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string disc_dir = vfs::get("/dev_bdvd/PS3_GAME");
|
||||
|
||||
if (m_sfo_dir == disc_dir)
|
||||
{
|
||||
disc_dir.clear();
|
||||
}
|
||||
|
||||
constexpr auto search_barrier = "barrier";
|
||||
const std::string locale_suffix = fmt::format("_%02d", static_cast<s32>(g_cfg.sys.language.get()));
|
||||
|
||||
std::initializer_list<std::string> testees =
|
||||
{
|
||||
m_sfo_dir + fmt::format("/PIC0%s.PNG", locale_suffix),
|
||||
m_sfo_dir + fmt::format("/PIC1%s.PNG", locale_suffix),
|
||||
m_sfo_dir + fmt::format("/PIC2%s.PNG", locale_suffix),
|
||||
m_sfo_dir + fmt::format("/PIC3%s.PNG", locale_suffix),
|
||||
search_barrier,
|
||||
m_sfo_dir + "/PIC0.PNG",
|
||||
m_sfo_dir + "/PIC1.PNG",
|
||||
m_sfo_dir + "/PIC2.PNG",
|
||||
m_sfo_dir + "/PIC3.PNG",
|
||||
search_barrier,
|
||||
!disc_dir.empty() ? (disc_dir + fmt::format("/PIC0%s.PNG", locale_suffix)) : disc_dir,
|
||||
!disc_dir.empty() ? (disc_dir + fmt::format("/PIC1%s.PNG", locale_suffix)) : disc_dir,
|
||||
!disc_dir.empty() ? (disc_dir + fmt::format("/PIC2%s.PNG", locale_suffix)) : disc_dir,
|
||||
!disc_dir.empty() ? (disc_dir + fmt::format("/PIC3%s.PNG", locale_suffix)) : disc_dir,
|
||||
search_barrier,
|
||||
!disc_dir.empty() ? (disc_dir + "/PIC0.PNG") : disc_dir,
|
||||
!disc_dir.empty() ? (disc_dir + "/PIC1.PNG") : disc_dir,
|
||||
!disc_dir.empty() ? (disc_dir + "/PIC2.PNG") : disc_dir,
|
||||
!disc_dir.empty() ? (disc_dir + "/PIC3.PNG") : disc_dir,
|
||||
search_barrier,
|
||||
m_sfo_dir + fmt::format("/ICON0%s.PNG", locale_suffix),
|
||||
search_barrier,
|
||||
m_sfo_dir + "/ICON0.PNG",
|
||||
search_barrier,
|
||||
!disc_dir.empty() ? (disc_dir + fmt::format("/ICON0%s.PNG", locale_suffix)) : disc_dir,
|
||||
search_barrier,
|
||||
!disc_dir.empty() ? (disc_dir + "/ICON0.PNG") : disc_dir,
|
||||
};
|
||||
|
||||
// Try to return the picture with the highest resolution
|
||||
// Be naive and assume that its the one that spans over the most bytes
|
||||
usz max_file_size = 0;
|
||||
usz index_of_largest_file = umax;
|
||||
|
||||
for (usz index = 0; index < testees.size(); index++)
|
||||
{
|
||||
const std::string& path = testees.begin()[index];
|
||||
|
||||
fs::stat_t file_stat{};
|
||||
|
||||
if (path == search_barrier)
|
||||
{
|
||||
if (index_of_largest_file != umax)
|
||||
{
|
||||
// Found a file in the preferred image group
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (path.empty() || !fs::get_stat(path, file_stat) || file_stat.is_directory)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (max_file_size < file_stat.size)
|
||||
{
|
||||
max_file_size = file_stat.size;
|
||||
index_of_largest_file = index;
|
||||
}
|
||||
}
|
||||
|
||||
if (index_of_largest_file == umax)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return testees.begin()[index_of_largest_file];
|
||||
}
|
||||
|
||||
bool Emulator::BootRsxCapture(const std::string& path)
|
||||
{
|
||||
if (m_state != system_state::stopped || m_restrict_emu_state_change)
|
||||
|
|
|
@ -338,8 +338,6 @@ public:
|
|||
|
||||
void SetUsr(const std::string& user);
|
||||
|
||||
std::string GetBackgroundPicturePath() const;
|
||||
|
||||
u64 GetPauseTime() const
|
||||
{
|
||||
return m_pause_amend_time;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "vfs_config.h"
|
||||
#include "Emu/Io/pad_config.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/VFS.h"
|
||||
#include "util/sysinfo.hpp"
|
||||
#include "Utilities/File.h"
|
||||
#include "Utilities/Thread.h"
|
||||
|
@ -338,4 +339,83 @@ namespace rpcs3::utils
|
|||
if (title_id.empty()) return "";
|
||||
return get_input_config_dir(title_id) + g_cfg_input_configs.default_config + ".yml";
|
||||
}
|
||||
|
||||
std::string get_game_content_path(game_content_type type)
|
||||
{
|
||||
const std::string locale_suffix = fmt::format("_%02d", static_cast<s32>(g_cfg.sys.language.get()));
|
||||
const std::string disc_dir = vfs::get("/dev_bdvd/PS3_GAME");
|
||||
std::string hdd0_dir = Emu.GetSfoDir(false);
|
||||
|
||||
if (hdd0_dir == disc_dir)
|
||||
{
|
||||
hdd0_dir.clear(); // No hdd0 dir
|
||||
}
|
||||
|
||||
const bool check_disc = !disc_dir.empty();
|
||||
const bool check_hdd0 = !hdd0_dir.empty() && !check_disc;
|
||||
|
||||
const auto find_content = [&](const std::string& name, const std::string& extension) -> std::string
|
||||
{
|
||||
// Check localized content first
|
||||
for (bool localized : { true, false })
|
||||
{
|
||||
const std::string filename = fmt::format("/%s%s.%s", name, localized ? locale_suffix : std::string(), extension);
|
||||
|
||||
// Check content on hdd0 first
|
||||
if (check_hdd0)
|
||||
{
|
||||
if (std::string path = hdd0_dir + filename; fs::is_file(path))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
// Check content on disc
|
||||
if (check_disc)
|
||||
{
|
||||
if (std::string path = disc_dir + filename; fs::is_file(path))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case game_content_type::content_icon:
|
||||
{
|
||||
return find_content("ICON0", "PNG");
|
||||
}
|
||||
case game_content_type::content_video:
|
||||
{
|
||||
return find_content("ICON1", "PAM");
|
||||
}
|
||||
case game_content_type::content_sound:
|
||||
{
|
||||
return find_content("SND0", "AT3");
|
||||
}
|
||||
case game_content_type::overlay_picture:
|
||||
{
|
||||
const bool high_res = g_cfg.video.aspect_ratio == video_aspect::_16_9;
|
||||
return find_content(high_res ? "PIC0" : "PIC2", "PNG");
|
||||
}
|
||||
case game_content_type::background_picture:
|
||||
case game_content_type::background_picture_2:
|
||||
{
|
||||
// Try to find a custom background first
|
||||
if (std::string path = fs::get_config_dir() + "/Icons/game_icons/" + Emu.GetTitleID() + "/PIC1.PNG"; fs::is_file(path))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
// Look for proper background
|
||||
return find_content(type == game_content_type::background_picture ? "PIC1" : "PIC3", "PNG");
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,16 @@
|
|||
#include "util/types.hpp"
|
||||
#include <string>
|
||||
|
||||
enum class game_content_type
|
||||
{
|
||||
content_icon, // ICON0.PNG
|
||||
content_video, // ICON1.PAM
|
||||
content_sound, // SND0.AT3
|
||||
overlay_picture, // PIC0.PNG (16:9) or PIC2.PNG (4:3)
|
||||
background_picture, // PIC1.PNG
|
||||
background_picture_2, // PIC3.PNG (should only exist for install or extra content discs...)
|
||||
};
|
||||
|
||||
namespace rpcs3::utils
|
||||
{
|
||||
u32 get_max_threads();
|
||||
|
@ -30,4 +40,6 @@ namespace rpcs3::utils
|
|||
std::string get_input_config_root();
|
||||
std::string get_input_config_dir(const std::string& title_id = "");
|
||||
std::string get_custom_input_config_path(const std::string& title_id);
|
||||
|
||||
std::string get_game_content_path(game_content_type type);
|
||||
}
|
||||
|
|
|
@ -897,7 +897,8 @@ void game_list_frame::OnRefreshFinished()
|
|||
}
|
||||
}
|
||||
|
||||
if (!entry->has_custom_icon)
|
||||
// Let's fetch the game data icon if the path was empty for some reason
|
||||
if (entry->info.icon_path.empty())
|
||||
{
|
||||
if (std::string icon_path = other->info.path + "/" + localized_icon; fs::is_file(icon_path))
|
||||
{
|
||||
|
@ -908,20 +909,6 @@ void game_list_frame::OnRefreshFinished()
|
|||
entry->info.icon_path = std::move(icon_path);
|
||||
}
|
||||
}
|
||||
|
||||
if (!entry->has_hover_gif)
|
||||
{
|
||||
if (std::string movie_path = other->info.path + "/" + localized_movie; fs::is_file(movie_path))
|
||||
{
|
||||
entry->info.movie_path = std::move(movie_path);
|
||||
entry->has_hover_pam = true;
|
||||
}
|
||||
else if (std::string movie_path = other->info.path + "/ICON1.PAM"; fs::is_file(movie_path))
|
||||
{
|
||||
entry->info.movie_path = std::move(movie_path);
|
||||
entry->has_hover_pam = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
const QString anti_cheat_savestates = tr("When this mode is on, emulation exits when saving and the savestate file is concealed after its load, preventing reuse by RPCS3.\nThis mode is like hibernation of emulation: if you don't want to be able to cheat using savestates when playing the game, consider using this mode.\nDo note that the savestate file is not gone completely, just ignored by RPCS3. You can manually relaunch it if needed.");
|
||||
const QString compatible_savestates = tr("When this mode is on, SPU emulation prioritizes savestate compatibility, however, it may reduce performance slightly.\nWhen this mode is off, some games may not allow making a savestate and show an SPU pause error in the log.");
|
||||
const QString paused_savestates = tr("When this mode is on, savestates are loaded and paused on the first frame.\nThis allows players to prepare for gameplay without being thrown into the action immediately.");
|
||||
const QString spu_profiler = tr("When enabled, SPU performance is measured at runtime.\nEnable only at a developr's request because when enabled it reduces performance a bit by itself.");
|
||||
const QString spu_profiler = tr("When enabled, SPU performance is measured at runtime.\nEnable only at a developer's request because when enabled it reduces performance a bit by itself.");
|
||||
|
||||
// audio
|
||||
|
||||
|
@ -166,7 +166,7 @@ public:
|
|||
const QString perf_overlay_center_x = tr("Centers the performance overlay horizontally and overrides the horizontal margin.");
|
||||
const QString perf_overlay_center_y = tr("Centers the performance overlay vertically and overrides the vertical margin.");
|
||||
|
||||
const QString shader_load_bg_enabled = tr("Shows a background image during the native shader loading dialog/loading screen.\nBy default the used image will be <gamedir>/PS3_GAME/PIC1.PNG or <gamedir>/PS3_GAME/PIC0.PNG.");
|
||||
const QString shader_load_bg_enabled = tr("Shows a background image during the native shader loading dialog/loading screen.\nBy default the used image will be <gamedir>/PS3_GAME/PIC1.PNG.");
|
||||
const QString shader_load_bg_darkening = tr("Changes the background image darkening effect strength of the native shader loading dialog.\nThis may be used to improve readability and/or aesthetics.");
|
||||
const QString shader_load_bg_blur = tr("Changes the background image blur effect strength of the native shader loading dialog.\nThis may be used to improve readability and/or aesthetics.");
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue