System: Adjust initialization order to better fit FullscreenUI
Fixes jankyness of rendering the landing page when trying to resume a game with achievements active, or when loading state.
This commit is contained in:
parent
1b678d0ebc
commit
4da7692a2d
|
@ -706,7 +706,8 @@ bool FullscreenUI::AreAnyDialogsOpen()
|
||||||
{
|
{
|
||||||
return (s_state.save_state_selector_open || s_state.about_window_open ||
|
return (s_state.save_state_selector_open || s_state.about_window_open ||
|
||||||
s_state.input_binding_type != InputBindingInfo::Type::Unknown || ImGuiFullscreen::IsChoiceDialogOpen() ||
|
s_state.input_binding_type != InputBindingInfo::Type::Unknown || ImGuiFullscreen::IsChoiceDialogOpen() ||
|
||||||
ImGuiFullscreen::IsFileSelectorOpen());
|
ImGuiFullscreen::IsInputDialogOpen() || ImGuiFullscreen::IsFileSelectorOpen() ||
|
||||||
|
ImGuiFullscreen::IsMessageBoxDialogOpen());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FullscreenUI::CheckForConfigChanges(const GPUSettings& old_settings)
|
void FullscreenUI::CheckForConfigChanges(const GPUSettings& old_settings)
|
||||||
|
@ -720,7 +721,7 @@ void FullscreenUI::UpdateRunIdleState()
|
||||||
GPUThread::SetRunIdleReason(GPUThread::RunIdleReason::FullscreenUIActive, new_run_idle);
|
GPUThread::SetRunIdleReason(GPUThread::RunIdleReason::FullscreenUIActive, new_run_idle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FullscreenUI::OnSystemStarted()
|
void FullscreenUI::OnSystemStarting()
|
||||||
{
|
{
|
||||||
// NOTE: Called on CPU thread.
|
// NOTE: Called on CPU thread.
|
||||||
if (!IsInitialized())
|
if (!IsInitialized())
|
||||||
|
@ -1109,34 +1110,37 @@ void FullscreenUI::DoStartPath(std::string path, std::string state, std::optiona
|
||||||
if (GPUThread::HasGPUBackend())
|
if (GPUThread::HasGPUBackend())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Switch to nothing, we'll get called back via OnSystemDestroyed() if startup fails.
|
// Stop running idle to prevent game list from being redrawn until we know if startup succeeded.
|
||||||
const MainWindowType prev_main_window = std::exchange(s_state.current_main_window, MainWindowType::None);
|
|
||||||
QueueResetFocus(FocusResetType::ViewChanged);
|
|
||||||
GPUThread::SetRunIdleReason(GPUThread::RunIdleReason::FullscreenUIActive, false);
|
GPUThread::SetRunIdleReason(GPUThread::RunIdleReason::FullscreenUIActive, false);
|
||||||
|
|
||||||
SystemBootParameters params;
|
SystemBootParameters params;
|
||||||
params.filename = std::move(path);
|
params.filename = std::move(path);
|
||||||
params.save_state = std::move(state);
|
params.save_state = std::move(state);
|
||||||
params.override_fast_boot = std::move(fast_boot);
|
params.override_fast_boot = std::move(fast_boot);
|
||||||
Host::RunOnCPUThread([params = std::move(params), prev_main_window]() {
|
Host::RunOnCPUThread([params = std::move(params)]() mutable {
|
||||||
if (System::IsValid())
|
if (System::IsValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// This can "fail" if HC mode is enabled and the user cancels, or other startup cancel paths.
|
||||||
|
// In that case, we need to re-trigger the idle state so the user can interact with the message.
|
||||||
|
// But we can skip it if we have a system, because OnSystemStarted() fixed it up.
|
||||||
Error error;
|
Error error;
|
||||||
if (!System::BootSystem(std::move(params), &error))
|
const bool result = System::BootSystem(std::move(params), &error);
|
||||||
{
|
if (result && System::IsValid())
|
||||||
GPUThread::RunOnThread([error_desc = error.TakeDescription(), prev_main_window]() {
|
return;
|
||||||
if (!IsInitialized())
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
GPUThread::RunOnThread([error_desc = error.TakeDescription(), result]() {
|
||||||
|
if (!IsInitialized())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
OpenInfoMessageDialog(TRANSLATE_STR("System", "Error"),
|
OpenInfoMessageDialog(TRANSLATE_STR("System", "Error"),
|
||||||
fmt::format(TRANSLATE_FS("System", "Failed to boot system: {}"), error_desc));
|
fmt::format(TRANSLATE_FS("System", "Failed to boot system: {}"), error_desc));
|
||||||
// ReturnToPreviousWindow();
|
}
|
||||||
s_state.current_main_window = prev_main_window;
|
|
||||||
QueueResetFocus(FocusResetType::ViewChanged);
|
UpdateRunIdleState();
|
||||||
UpdateRunIdleState();
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ bool Initialize();
|
||||||
bool IsInitialized();
|
bool IsInitialized();
|
||||||
bool HasActiveWindow();
|
bool HasActiveWindow();
|
||||||
void CheckForConfigChanges(const GPUSettings& old_settings);
|
void CheckForConfigChanges(const GPUSettings& old_settings);
|
||||||
void OnSystemStarted();
|
void OnSystemStarting();
|
||||||
void OnSystemResumed();
|
void OnSystemResumed();
|
||||||
void OnSystemDestroyed();
|
void OnSystemDestroyed();
|
||||||
void OnRunningGameChanged(const std::string& path, const std::string& serial, const std::string& title);
|
void OnRunningGameChanged(const std::string& path, const std::string& serial, const std::string& title);
|
||||||
|
|
|
@ -223,7 +223,6 @@ static void DoRewind();
|
||||||
|
|
||||||
static bool DoRunahead();
|
static bool DoRunahead();
|
||||||
|
|
||||||
static bool OpenGPUDump(std::string path, Error* error);
|
|
||||||
static bool ChangeGPUDump(std::string new_path);
|
static bool ChangeGPUDump(std::string new_path);
|
||||||
|
|
||||||
static void UpdateSessionTime(const std::string& prev_serial);
|
static void UpdateSessionTime(const std::string& prev_serial);
|
||||||
|
@ -1657,18 +1656,13 @@ bool System::BootSystem(SystemBootParameters parameters, Error* error)
|
||||||
else
|
else
|
||||||
INFO_LOG("Boot Filename: {}", parameters.filename);
|
INFO_LOG("Boot Filename: {}", parameters.filename);
|
||||||
|
|
||||||
Assert(s_state.state == State::Shutdown);
|
|
||||||
s_state.state = State::Starting;
|
|
||||||
s_state.startup_cancelled.store(false, std::memory_order_relaxed);
|
|
||||||
s_state.region = g_settings.region;
|
|
||||||
std::atomic_thread_fence(std::memory_order_release);
|
|
||||||
Host::OnSystemStarting();
|
|
||||||
|
|
||||||
// Load CD image up and detect region.
|
// Load CD image up and detect region.
|
||||||
std::unique_ptr<CDImage> disc;
|
std::unique_ptr<CDImage> disc;
|
||||||
|
ConsoleRegion console_region = ConsoleRegion::Auto;
|
||||||
DiscRegion disc_region = DiscRegion::NonPS1;
|
DiscRegion disc_region = DiscRegion::NonPS1;
|
||||||
BootMode boot_mode = BootMode::FullBoot;
|
BootMode boot_mode = BootMode::FullBoot;
|
||||||
std::string exe_override;
|
std::string exe_override;
|
||||||
|
std::unique_ptr<GPUDump::Player> gpu_dump;
|
||||||
if (!parameters.filename.empty())
|
if (!parameters.filename.empty())
|
||||||
{
|
{
|
||||||
if (IsExePath(parameters.filename))
|
if (IsExePath(parameters.filename))
|
||||||
|
@ -1683,24 +1677,22 @@ bool System::BootSystem(SystemBootParameters parameters, Error* error)
|
||||||
}
|
}
|
||||||
else if (IsGPUDumpPath(parameters.filename))
|
else if (IsGPUDumpPath(parameters.filename))
|
||||||
{
|
{
|
||||||
if (!OpenGPUDump(parameters.filename, error))
|
gpu_dump = GPUDump::Player::Open(parameters.filename, error);
|
||||||
{
|
if (!gpu_dump)
|
||||||
DestroySystem();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
boot_mode = BootMode::ReplayGPUDump;
|
boot_mode = BootMode::ReplayGPUDump;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boot_mode == BootMode::BootEXE || boot_mode == BootMode::BootPSF)
|
if (boot_mode == BootMode::BootEXE || boot_mode == BootMode::BootPSF)
|
||||||
{
|
{
|
||||||
if (s_state.region == ConsoleRegion::Auto)
|
if (console_region == ConsoleRegion::Auto)
|
||||||
{
|
{
|
||||||
const DiscRegion file_region =
|
const DiscRegion file_region =
|
||||||
((boot_mode == BootMode::BootEXE) ? GetRegionForExe(parameters.filename.c_str()) :
|
((boot_mode == BootMode::BootEXE) ? GetRegionForExe(parameters.filename.c_str()) :
|
||||||
GetRegionForPsf(parameters.filename.c_str()));
|
GetRegionForPsf(parameters.filename.c_str()));
|
||||||
INFO_LOG("EXE/PSF Region: {}", Settings::GetDiscRegionDisplayName(file_region));
|
INFO_LOG("EXE/PSF Region: {}", Settings::GetDiscRegionDisplayName(file_region));
|
||||||
s_state.region = GetConsoleRegionForDiscRegion(file_region);
|
console_region = GetConsoleRegionForDiscRegion(file_region);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (boot_mode != BootMode::ReplayGPUDump)
|
else if (boot_mode != BootMode::ReplayGPUDump)
|
||||||
|
@ -1710,25 +1702,24 @@ bool System::BootSystem(SystemBootParameters parameters, Error* error)
|
||||||
if (!disc)
|
if (!disc)
|
||||||
{
|
{
|
||||||
Error::AddPrefixFmt(error, "Failed to open CD image '{}':\n", Path::GetFileName(parameters.filename));
|
Error::AddPrefixFmt(error, "Failed to open CD image '{}':\n", Path::GetFileName(parameters.filename));
|
||||||
DestroySystem();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
disc_region = GameList::GetCustomRegionForPath(parameters.filename).value_or(GetRegionForImage(disc.get()));
|
disc_region = GameList::GetCustomRegionForPath(parameters.filename).value_or(GetRegionForImage(disc.get()));
|
||||||
if (s_state.region == ConsoleRegion::Auto)
|
if (console_region == ConsoleRegion::Auto)
|
||||||
{
|
{
|
||||||
if (disc_region != DiscRegion::Other)
|
if (disc_region != DiscRegion::Other)
|
||||||
{
|
{
|
||||||
s_state.region = GetConsoleRegionForDiscRegion(disc_region);
|
console_region = GetConsoleRegionForDiscRegion(disc_region);
|
||||||
INFO_LOG("Auto-detected console {} region for '{}' (region {})",
|
INFO_LOG("Auto-detected console {} region for '{}' (region {})",
|
||||||
Settings::GetConsoleRegionName(s_state.region), parameters.filename,
|
Settings::GetConsoleRegionName(console_region), parameters.filename,
|
||||||
Settings::GetDiscRegionName(disc_region));
|
Settings::GetDiscRegionName(disc_region));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s_state.region = ConsoleRegion::NTSC_U;
|
console_region = ConsoleRegion::NTSC_U;
|
||||||
WARNING_LOG("Could not determine console region for disc region {}. Defaulting to {}.",
|
WARNING_LOG("Could not determine console region for disc region {}. Defaulting to {}.",
|
||||||
Settings::GetDiscRegionName(disc_region), Settings::GetConsoleRegionName(s_state.region));
|
Settings::GetDiscRegionName(disc_region), Settings::GetConsoleRegionName(console_region));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1736,21 +1727,72 @@ bool System::BootSystem(SystemBootParameters parameters, Error* error)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Default to NTSC for BIOS boot.
|
// Default to NTSC for BIOS boot.
|
||||||
if (s_state.region == ConsoleRegion::Auto)
|
if (console_region == ConsoleRegion::Auto)
|
||||||
s_state.region = ConsoleRegion::NTSC_U;
|
console_region = ConsoleRegion::NTSC_U;
|
||||||
}
|
}
|
||||||
|
|
||||||
INFO_LOG("Console Region: {}", Settings::GetConsoleRegionDisplayName(s_state.region));
|
INFO_LOG("Console Region: {}", Settings::GetConsoleRegionDisplayName(console_region));
|
||||||
|
|
||||||
// Switch subimage.
|
// Switch subimage.
|
||||||
if (disc && parameters.media_playlist_index != 0 && !disc->SwitchSubImage(parameters.media_playlist_index, error))
|
if (disc && parameters.media_playlist_index != 0 && !disc->SwitchSubImage(parameters.media_playlist_index, error))
|
||||||
{
|
{
|
||||||
Error::AddPrefixFmt(error, "Failed to switch to subimage {} in '{}':\n", parameters.media_playlist_index,
|
Error::AddPrefixFmt(error, "Failed to switch to subimage {} in '{}':\n", parameters.media_playlist_index,
|
||||||
Path::GetFileName(parameters.filename));
|
Path::GetFileName(parameters.filename));
|
||||||
DestroySystem();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Achievement hardcore checks before committing to anything.
|
||||||
|
if (!IsReplayingGPUDump())
|
||||||
|
{
|
||||||
|
// Check for resuming with hardcore mode.
|
||||||
|
if (parameters.disable_achievements_hardcore_mode)
|
||||||
|
Achievements::DisableHardcoreMode();
|
||||||
|
else
|
||||||
|
Achievements::ResetHardcoreMode(true);
|
||||||
|
|
||||||
|
if ((!parameters.save_state.empty() || !exe_override.empty()) && Achievements::IsHardcoreModeActive())
|
||||||
|
{
|
||||||
|
const bool is_exe_override_boot = parameters.save_state.empty();
|
||||||
|
bool cancelled;
|
||||||
|
if (FullscreenUI::IsInitialized())
|
||||||
|
{
|
||||||
|
Achievements::ConfirmHardcoreModeDisableAsync(is_exe_override_boot ?
|
||||||
|
TRANSLATE("Achievements", "Overriding executable") :
|
||||||
|
TRANSLATE("Achievements", "Resuming state"),
|
||||||
|
[parameters = std::move(parameters)](bool approved) mutable {
|
||||||
|
if (approved)
|
||||||
|
{
|
||||||
|
parameters.disable_achievements_hardcore_mode = true;
|
||||||
|
BootSystem(std::move(parameters), nullptr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cancelled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cancelled = !Achievements::ConfirmHardcoreModeDisable(is_exe_override_boot ?
|
||||||
|
TRANSLATE("Achievements", "Overriding executable") :
|
||||||
|
TRANSLATE("Achievements", "Resuming state"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cancelled)
|
||||||
|
{
|
||||||
|
// Technically a failure, but user-initiated. Returning false here would try to display a non-existent error.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can't early cancel without destroying past this point.
|
||||||
|
Assert(s_state.state == State::Shutdown);
|
||||||
|
s_state.state = State::Starting;
|
||||||
|
s_state.region = console_region;
|
||||||
|
s_state.startup_cancelled.store(false, std::memory_order_relaxed);
|
||||||
|
s_state.gpu_dump_player = std::move(gpu_dump);
|
||||||
|
std::atomic_thread_fence(std::memory_order_release);
|
||||||
|
Host::OnSystemStarting();
|
||||||
|
FullscreenUI::OnSystemStarting();
|
||||||
|
|
||||||
// Update running game, this will apply settings as well.
|
// Update running game, this will apply settings as well.
|
||||||
UpdateRunningGame(disc ? disc->GetPath() : parameters.filename, disc.get(), true);
|
UpdateRunningGame(disc ? disc->GetPath() : parameters.filename, disc.get(), true);
|
||||||
|
|
||||||
|
@ -1770,42 +1812,6 @@ bool System::BootSystem(SystemBootParameters parameters, Error* error)
|
||||||
exe_override = std::move(parameters.override_exe);
|
exe_override = std::move(parameters.override_exe);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for resuming with hardcore mode.
|
|
||||||
if (parameters.disable_achievements_hardcore_mode)
|
|
||||||
Achievements::DisableHardcoreMode();
|
|
||||||
if ((!parameters.save_state.empty() || !exe_override.empty()) && Achievements::IsHardcoreModeActive())
|
|
||||||
{
|
|
||||||
const bool is_exe_override_boot = parameters.save_state.empty();
|
|
||||||
bool cancelled;
|
|
||||||
if (FullscreenUI::IsInitialized())
|
|
||||||
{
|
|
||||||
Achievements::ConfirmHardcoreModeDisableAsync(is_exe_override_boot ?
|
|
||||||
TRANSLATE("Achievements", "Overriding executable") :
|
|
||||||
TRANSLATE("Achievements", "Resuming state"),
|
|
||||||
[parameters = std::move(parameters)](bool approved) mutable {
|
|
||||||
if (approved)
|
|
||||||
{
|
|
||||||
parameters.disable_achievements_hardcore_mode = true;
|
|
||||||
BootSystem(std::move(parameters), nullptr);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
cancelled = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cancelled = !Achievements::ConfirmHardcoreModeDisable(is_exe_override_boot ?
|
|
||||||
TRANSLATE("Achievements", "Overriding executable") :
|
|
||||||
TRANSLATE("Achievements", "Resuming state"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cancelled)
|
|
||||||
{
|
|
||||||
// Technically a failure, but user-initiated. Returning false here would try to display a non-existent error.
|
|
||||||
DestroySystem();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Are we fast booting? Must be checked after updating game settings.
|
// Are we fast booting? Must be checked after updating game settings.
|
||||||
if (boot_mode == BootMode::FullBoot && disc_region != DiscRegion::NonPS1 &&
|
if (boot_mode == BootMode::FullBoot && disc_region != DiscRegion::NonPS1 &&
|
||||||
parameters.override_fast_boot.value_or(static_cast<bool>(g_settings.bios_patch_fast_boot)))
|
parameters.override_fast_boot.value_or(static_cast<bool>(g_settings.bios_patch_fast_boot)))
|
||||||
|
@ -1847,8 +1853,6 @@ bool System::BootSystem(SystemBootParameters parameters, Error* error)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FullscreenUI::OnSystemStarted();
|
|
||||||
|
|
||||||
InputManager::UpdateHostMouseMode();
|
InputManager::UpdateHostMouseMode();
|
||||||
|
|
||||||
if (g_settings.inhibit_screensaver)
|
if (g_settings.inhibit_screensaver)
|
||||||
|
@ -4189,9 +4193,6 @@ void System::UpdateRunningGame(const std::string& path, CDImage* image, bool boo
|
||||||
|
|
||||||
if (!IsReplayingGPUDump())
|
if (!IsReplayingGPUDump())
|
||||||
{
|
{
|
||||||
if (booting)
|
|
||||||
Achievements::ResetHardcoreMode(true);
|
|
||||||
|
|
||||||
Achievements::GameChanged(s_state.running_game_path, image, booting);
|
Achievements::GameChanged(s_state.running_game_path, image, booting);
|
||||||
|
|
||||||
// game layer reloads cheats, but only the active list, we need new files
|
// game layer reloads cheats, but only the active list, we need new files
|
||||||
|
@ -5848,27 +5849,18 @@ void System::UpdateGTEAspectRatio()
|
||||||
GTE::SetAspectRatio(gte_ar, custom_num, custom_denom);
|
GTE::SetAspectRatio(gte_ar, custom_num, custom_denom);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool System::OpenGPUDump(std::string path, Error* error)
|
|
||||||
{
|
|
||||||
std::unique_ptr<GPUDump::Player> new_dump = GPUDump::Player::Open(std::move(path), error);
|
|
||||||
if (!new_dump)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// set properties
|
|
||||||
s_state.gpu_dump_player = std::move(new_dump);
|
|
||||||
s_state.region = s_state.gpu_dump_player->GetRegion();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool System::ChangeGPUDump(std::string new_path)
|
bool System::ChangeGPUDump(std::string new_path)
|
||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
if (!OpenGPUDump(std::move(new_path), &error))
|
std::unique_ptr<GPUDump::Player> new_dump = GPUDump::Player::Open(std::move(new_path), &error);
|
||||||
|
if (!new_dump)
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync("Error", fmt::format(TRANSLATE_FS("Failed to change GPU dump: {}", error.GetDescription())));
|
Host::ReportErrorAsync("Error", fmt::format(TRANSLATE_FS("Failed to change GPU dump: {}", error.GetDescription())));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s_state.gpu_dump_player = std::move(new_dump);
|
||||||
|
s_state.region = s_state.gpu_dump_player->GetRegion();
|
||||||
UpdateRunningGame(s_state.gpu_dump_player->GetPath(), nullptr, false);
|
UpdateRunningGame(s_state.gpu_dump_player->GetPath(), nullptr, false);
|
||||||
|
|
||||||
// current player object has been changed out, toss call stack
|
// current player object has been changed out, toss call stack
|
||||||
|
|
|
@ -449,7 +449,7 @@ CDImage::PrecacheResult CDImageCHD::Precache(ProgressCallback* progress)
|
||||||
if (m_precached)
|
if (m_precached)
|
||||||
return CDImage::PrecacheResult::Success;
|
return CDImage::PrecacheResult::Success;
|
||||||
|
|
||||||
progress->SetStatusText(fmt::format("Precaching {}...", FileSystem::GetDisplayNameFromPath(m_filename)).c_str());
|
progress->SetStatusText("Precaching CHD...");
|
||||||
progress->SetProgressRange(100);
|
progress->SetProgressRange(100);
|
||||||
|
|
||||||
auto callback = [](size_t pos, size_t total, void* param) {
|
auto callback = [](size_t pos, size_t total, void* param) {
|
||||||
|
|
Loading…
Reference in New Issue