mirror of
https://github.com/stenzek/duckstation.git
synced 2025-07-23 10:30:23 +00:00
FullscreenUI: Display game cover when loading
This commit is contained in:
parent
75314f79de
commit
278614a415
@ -1856,7 +1856,7 @@ bool Achievements::DoState(StateWrapper& sw)
|
|||||||
{
|
{
|
||||||
// Messy because GPU-thread, but at least it looks pretty.
|
// Messy because GPU-thread, but at least it looks pretty.
|
||||||
GPUThread::RunOnThread([]() {
|
GPUThread::RunOnThread([]() {
|
||||||
FullscreenUI::OpenLoadingScreen(ImGuiManager::LOGO_IMAGE_NAME,
|
FullscreenUI::OpenLoadingScreen(System::GetImageForLoadingScreen(GPUThread::GetGameSerial()),
|
||||||
TRANSLATE_SV("Achievements", "Downloading achievements data..."));
|
TRANSLATE_SV("Achievements", "Downloading achievements data..."));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -9165,6 +9165,8 @@ void FullscreenUI::BackgroundProgressCallback::SetCancelled()
|
|||||||
LoadingScreenProgressCallback::LoadingScreenProgressCallback()
|
LoadingScreenProgressCallback::LoadingScreenProgressCallback()
|
||||||
: ProgressCallback(), m_open_time(Timer::GetCurrentValue()), m_on_gpu_thread(GPUThread::IsOnThread())
|
: ProgressCallback(), m_open_time(Timer::GetCurrentValue()), m_on_gpu_thread(GPUThread::IsOnThread())
|
||||||
{
|
{
|
||||||
|
m_image = System::GetImageForLoadingScreen(
|
||||||
|
std::string_view(m_on_gpu_thread ? GPUThread::GetGameSerial() : System::GetGameSerial()));
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadingScreenProgressCallback::~LoadingScreenProgressCallback()
|
LoadingScreenProgressCallback::~LoadingScreenProgressCallback()
|
||||||
@ -9269,15 +9271,16 @@ void LoadingScreenProgressCallback::Redraw(bool force)
|
|||||||
m_last_progress_percent = percent;
|
m_last_progress_percent = percent;
|
||||||
if (m_on_gpu_thread)
|
if (m_on_gpu_thread)
|
||||||
{
|
{
|
||||||
ImGuiFullscreen::RenderLoadingScreen(ImGuiManager::LOGO_IMAGE_NAME, m_status_text, 0,
|
ImGuiFullscreen::RenderLoadingScreen(m_image, m_status_text, 0, static_cast<s32>(m_progress_range),
|
||||||
static_cast<s32>(m_progress_range), static_cast<s32>(m_progress_value));
|
static_cast<s32>(m_progress_value));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GPUThread::RunOnThread([status_text = SmallString(std::string_view(m_status_text)),
|
GPUThread::RunOnThread([image = std::move(m_image), status_text = SmallString(std::string_view(m_status_text)),
|
||||||
range = static_cast<s32>(m_progress_range), value = static_cast<s32>(m_progress_value)]() {
|
range = static_cast<s32>(m_progress_range), value = static_cast<s32>(m_progress_value)]() {
|
||||||
ImGuiFullscreen::OpenOrUpdateLoadingScreen(ImGuiManager::LOGO_IMAGE_NAME, status_text, 0, range, value);
|
ImGuiFullscreen::OpenOrUpdateLoadingScreen(ImGuiManager::LOGO_IMAGE_NAME, status_text, 0, range, value);
|
||||||
});
|
});
|
||||||
|
m_image = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +138,7 @@ private:
|
|||||||
float m_open_delay = 1.0f;
|
float m_open_delay = 1.0f;
|
||||||
s32 m_last_progress_percent = -1;
|
s32 m_last_progress_percent = -1;
|
||||||
bool m_on_gpu_thread = false;
|
bool m_on_gpu_thread = false;
|
||||||
|
std::string m_image;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Host UI triggers from Big Picture mode.
|
// Host UI triggers from Big Picture mode.
|
||||||
|
@ -1182,36 +1182,46 @@ static std::string GetFullCoverPath(std::string_view filename, std::string_view
|
|||||||
std::string GameList::GetCoverImagePath(const std::string& path, const std::string& serial, const std::string& title)
|
std::string GameList::GetCoverImagePath(const std::string& path, const std::string& serial, const std::string& title)
|
||||||
{
|
{
|
||||||
static constexpr const std::array extensions = {"jpg", "jpeg", "png", "webp"};
|
static constexpr const std::array extensions = {"jpg", "jpeg", "png", "webp"};
|
||||||
|
std::string ret;
|
||||||
|
|
||||||
for (const char* extension : extensions)
|
for (const char* extension : extensions)
|
||||||
{
|
{
|
||||||
// Prioritize lookup by serial (Most specific)
|
// Prioritize lookup by serial (Most specific)
|
||||||
if (!serial.empty())
|
if (!serial.empty())
|
||||||
{
|
{
|
||||||
const std::string cover_path(GetFullCoverPath(serial, extension));
|
std::string cover_path(GetFullCoverPath(serial, extension));
|
||||||
if (FileSystem::FileExists(cover_path.c_str()))
|
if (FileSystem::FileExists(cover_path.c_str()))
|
||||||
return cover_path;
|
{
|
||||||
|
ret = std::move(cover_path);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try file title (for modded games or specific like above)
|
// Try file title (for modded games or specific like above)
|
||||||
const std::string_view file_title(Path::GetFileTitle(path));
|
const std::string_view file_title(Path::GetFileTitle(path));
|
||||||
if (!file_title.empty() && title != file_title)
|
if (!file_title.empty() && title != file_title)
|
||||||
{
|
{
|
||||||
const std::string cover_path(GetFullCoverPath(file_title, extension));
|
std::string cover_path(GetFullCoverPath(file_title, extension));
|
||||||
if (FileSystem::FileExists(cover_path.c_str()))
|
if (FileSystem::FileExists(cover_path.c_str()))
|
||||||
return cover_path;
|
{
|
||||||
|
ret = std::move(cover_path);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last resort, check the game title
|
// Last resort, check the game title
|
||||||
if (!title.empty())
|
if (!title.empty())
|
||||||
{
|
{
|
||||||
const std::string cover_path(GetFullCoverPath(title, extension));
|
std::string cover_path(GetFullCoverPath(title, extension));
|
||||||
if (FileSystem::FileExists(cover_path.c_str()))
|
if (FileSystem::FileExists(cover_path.c_str()))
|
||||||
return cover_path;
|
{
|
||||||
|
ret = std::move(cover_path);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GameList::GetNewCoverImagePathForEntry(const Entry* entry, const char* new_filename, bool use_serial)
|
std::string GameList::GetNewCoverImagePathForEntry(const Entry* entry, const char* new_filename, bool use_serial)
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "gpu_hw_shadergen.h"
|
#include "gpu_hw_shadergen.h"
|
||||||
#include "gpu_presenter.h"
|
#include "gpu_presenter.h"
|
||||||
#include "gpu_sw_rasterizer.h"
|
#include "gpu_sw_rasterizer.h"
|
||||||
|
#include "gpu_thread.h"
|
||||||
#include "gte_types.h"
|
#include "gte_types.h"
|
||||||
#include "host.h"
|
#include "host.h"
|
||||||
#include "imgui_overlays.h"
|
#include "imgui_overlays.h"
|
||||||
@ -184,9 +185,9 @@ class ShaderCompileProgressTracker
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShaderCompileProgressTracker(std::string title, u32 total)
|
ShaderCompileProgressTracker(std::string title, u32 total)
|
||||||
: m_title(std::move(title)), m_min_time(Timer::ConvertSecondsToValue(1.0)),
|
: m_title(std::move(title)), m_image(System::GetImageForLoadingScreen(GPUThread::GetGameSerial())),
|
||||||
m_update_interval(Timer::ConvertSecondsToValue(0.1)), m_start_time(Timer::GetCurrentValue()),
|
m_min_time(Timer::ConvertSecondsToValue(1.0)), m_update_interval(Timer::ConvertSecondsToValue(0.1)),
|
||||||
m_last_update_time(0), m_progress(0), m_total(total)
|
m_start_time(Timer::GetCurrentValue()), m_last_update_time(0), m_progress(0), m_total(total)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
~ShaderCompileProgressTracker() = default;
|
~ShaderCompileProgressTracker() = default;
|
||||||
@ -209,7 +210,7 @@ public:
|
|||||||
const u64 tv = Timer::GetCurrentValue();
|
const u64 tv = Timer::GetCurrentValue();
|
||||||
if ((tv - m_start_time) >= m_min_time && (tv - m_last_update_time) >= m_update_interval)
|
if ((tv - m_start_time) >= m_min_time && (tv - m_last_update_time) >= m_update_interval)
|
||||||
{
|
{
|
||||||
ImGuiFullscreen::RenderLoadingScreen(ImGuiManager::LOGO_IMAGE_NAME, m_title, 0, static_cast<int>(m_total),
|
ImGuiFullscreen::RenderLoadingScreen(m_image, m_title, 0, static_cast<int>(m_total),
|
||||||
static_cast<int>(m_progress));
|
static_cast<int>(m_progress));
|
||||||
m_last_update_time = tv;
|
m_last_update_time = tv;
|
||||||
}
|
}
|
||||||
@ -219,6 +220,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_title;
|
std::string m_title;
|
||||||
|
std::string m_image;
|
||||||
Timer::Value m_min_time;
|
Timer::Value m_min_time;
|
||||||
Timer::Value m_update_interval;
|
Timer::Value m_update_interval;
|
||||||
Timer::Value m_start_time;
|
Timer::Value m_start_time;
|
||||||
|
@ -3455,11 +3455,12 @@ void GPUTextureCache::PreloadReplacementTextures()
|
|||||||
u32 num_textures_loaded = 0;
|
u32 num_textures_loaded = 0;
|
||||||
const size_t total_textures = s_state.vram_replacements.size() + s_state.vram_write_texture_replacements.size() +
|
const size_t total_textures = s_state.vram_replacements.size() + s_state.vram_write_texture_replacements.size() +
|
||||||
s_state.texture_page_texture_replacements.size();
|
s_state.texture_page_texture_replacements.size();
|
||||||
|
std::string image_path = System::GetImageForLoadingScreen(GPUThread::GetGameSerial());
|
||||||
|
|
||||||
#define UPDATE_PROGRESS() \
|
#define UPDATE_PROGRESS() \
|
||||||
if (last_update_time.GetTimeSeconds() >= UPDATE_INTERVAL) \
|
if (last_update_time.GetTimeSeconds() >= UPDATE_INTERVAL) \
|
||||||
{ \
|
{ \
|
||||||
ImGuiFullscreen::RenderLoadingScreen(ImGuiManager::LOGO_IMAGE_NAME, "Preloading replacement textures...", 0, \
|
ImGuiFullscreen::RenderLoadingScreen(image_path, "Preloading replacement textures...", 0, \
|
||||||
static_cast<int>(total_textures), static_cast<int>(num_textures_loaded)); \
|
static_cast<int>(total_textures), static_cast<int>(num_textures_loaded)); \
|
||||||
last_update_time.Reset(); \
|
last_update_time.Reset(); \
|
||||||
}
|
}
|
||||||
|
@ -6007,6 +6007,22 @@ bool System::ChangeGPUDump(std::string new_path)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string System::GetImageForLoadingScreen(std::string_view serial)
|
||||||
|
{
|
||||||
|
std::string ret;
|
||||||
|
|
||||||
|
const auto lock = GameList::GetLock();
|
||||||
|
const GameList::Entry* entry = GameList::GetEntryBySerial(serial);
|
||||||
|
|
||||||
|
if (entry)
|
||||||
|
ret = GameList::GetCoverImagePathForEntry(entry);
|
||||||
|
|
||||||
|
if (ret.empty())
|
||||||
|
ret = ImGuiManager::LOGO_IMAGE_NAME;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void System::UpdateSessionTime(const std::string& prev_serial)
|
void System::UpdateSessionTime(const std::string& prev_serial)
|
||||||
{
|
{
|
||||||
const Timer::Value ctime = Timer::GetCurrentValue();
|
const Timer::Value ctime = Timer::GetCurrentValue();
|
||||||
|
@ -423,6 +423,10 @@ void ToggleSoftwareRendering();
|
|||||||
/// If the scale is set to 0, the internal resolution will be used, otherwise it is treated as a multiplier to 1x.
|
/// If the scale is set to 0, the internal resolution will be used, otherwise it is treated as a multiplier to 1x.
|
||||||
void RequestDisplaySize(float scale = 0.0f);
|
void RequestDisplaySize(float scale = 0.0f);
|
||||||
|
|
||||||
|
/// Returns the path to a possible cover image for the current serial.
|
||||||
|
/// Only intended to be used for loading screens, so it may not be correct with custom titles and such.
|
||||||
|
std::string GetImageForLoadingScreen(std::string_view serial);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// Memory Save States (Rewind and Runahead)
|
// Memory Save States (Rewind and Runahead)
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -3915,7 +3915,7 @@ void ImGuiFullscreen::OpenOrUpdateLoadingScreen(std::string_view image, std::str
|
|||||||
s32 progress_min /*= -1*/, s32 progress_max /*= -1*/,
|
s32 progress_min /*= -1*/, s32 progress_max /*= -1*/,
|
||||||
s32 progress_value /*= -1*/)
|
s32 progress_value /*= -1*/)
|
||||||
{
|
{
|
||||||
if (s_state.loading_screen_image != image)
|
if (!image.empty() && s_state.loading_screen_image != image)
|
||||||
s_state.loading_screen_image = image;
|
s_state.loading_screen_image = image;
|
||||||
if (s_state.loading_screen_message != message)
|
if (s_state.loading_screen_message != message)
|
||||||
s_state.loading_screen_message = message;
|
s_state.loading_screen_message = message;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user