From a6a7a1613c6a37fe5f81c4c394cffdd65d9af9be Mon Sep 17 00:00:00 2001 From: Stenzek Date: Tue, 16 May 2023 01:00:41 +1000 Subject: [PATCH] System: Add fast_forward_to_first_frame boot parameter --- src/core/system.cpp | 42 +++++++++++++++++++++++++++++++++++++++--- src/core/system.h | 3 ++- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/core/system.cpp b/src/core/system.cpp index fbf528405..132a012f1 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -108,6 +108,7 @@ static void DoRunahead(); static void DoMemorySaveStates(); static bool Initialize(bool force_software_renderer); +static bool FastForwardToFirstFrame(); static bool UpdateGameSettingsLayer(); static void UpdateRunningGame(const char* path, CDImage* image, bool booting); @@ -140,6 +141,7 @@ static std::string s_running_game_serial; static std::string s_running_game_title; static System::GameHash s_running_game_hash; static bool s_running_unknown_game; +static bool s_was_fast_booted; static float s_throttle_frequency = 60.0f; static float s_target_speed = 1.0f; @@ -331,6 +333,11 @@ bool System::IsRunningUnknownGame() return s_running_unknown_game; } +bool System::WasFastBooted() +{ + return s_was_fast_booted; +} + const BIOS::ImageInfo* System::GetBIOSImageInfo() { return s_bios_image_info; @@ -520,7 +527,7 @@ bool System::GetGameDetailsFromImage(CDImage* cdi, std::string* out_id, GameHash pos++; } } - + if (out_id) { if (id.empty()) @@ -635,7 +642,7 @@ std::string System::GetExecutableNameForImage(CDImage* cdi, bool strip_subdirect } bool System::ReadExecutableFromImage(CDImage* cdi, std::string* out_executable_name, - std::vector* out_executable_data) + std::vector* out_executable_data) { ISOReader iso; if (!iso.Open(cdi, 1)) @@ -644,7 +651,8 @@ bool System::ReadExecutableFromImage(CDImage* cdi, std::string* out_executable_n return ReadExecutableFromImage(iso, out_executable_name, out_executable_data); } -bool System::ReadExecutableFromImage(ISOReader& iso, std::string* out_executable_name, std::vector* out_executable_data) +bool System::ReadExecutableFromImage(ISOReader& iso, std::string* out_executable_name, + std::vector* out_executable_data) { const std::string executable_path = GetExecutableNameForImage(iso, false); Log_DevPrintf("Executable path: '%s'", executable_path.c_str()); @@ -1295,9 +1303,15 @@ bool System::BootSystem(SystemBootParameters parameters) g_settings.bios_patch_fast_boot)) { if (s_bios_image_info && s_bios_image_info->patch_compatible) + { + // TODO: Fast boot without patches... BIOS::PatchBIOSFastBoot(Bus::g_bios, Bus::BIOS_SIZE); + s_was_fast_booted = true; + } else + { Log_ErrorPrintf("Not patching fast boot, as BIOS is not patch compatible."); + } } // Good to go. @@ -1337,6 +1351,9 @@ bool System::BootSystem(SystemBootParameters parameters) if (parameters.load_image_to_ram || g_settings.cdrom_load_image_to_ram) CDROM::PrecacheMedia(); + if (parameters.fast_forward_to_first_frame) + FastForwardToFirstFrame(); + if (g_settings.audio_dump_on_boot) StartDumpingAudio(); @@ -1519,6 +1536,7 @@ void System::DestroySystem() s_bios_hash = {}; s_bios_image_info = nullptr; + s_was_fast_booted = false; Host::OnSystemDestroyed(); } @@ -1540,6 +1558,24 @@ void System::ClearRunningGame() #endif } +bool System::FastForwardToFirstFrame() +{ + // If we're taking more than 60 seconds to load the game, oof.. + static constexpr u32 MAX_FRAMES_TO_SKIP = 30 * 60; + const u32 current_frame_number = s_frame_number; + const u32 current_internal_frame_number = s_internal_frame_number; + + SPU::SetAudioOutputMuted(true); + while (s_internal_frame_number == current_internal_frame_number && + (s_frame_number - current_frame_number) <= MAX_FRAMES_TO_SKIP) + { + System::RunFrame(); + } + SPU::SetAudioOutputMuted(false); + + return (s_internal_frame_number != current_internal_frame_number); +} + void System::Execute() { while (IsRunning()) diff --git a/src/core/system.h b/src/core/system.h index 3d2d8cc46..8eda2c988 100644 --- a/src/core/system.h +++ b/src/core/system.h @@ -45,6 +45,7 @@ struct SystemBootParameters u32 media_playlist_index = 0; bool load_image_to_ram = false; bool force_software_renderer = false; + bool fast_forward_to_first_frame = false; }; struct SaveStateInfo @@ -113,7 +114,6 @@ ConsoleRegion GetConsoleRegionForDiscRegion(DiscRegion region); std::string GetExecutableNameForImage(CDImage* cdi, bool strip_subdirectories); bool ReadExecutableFromImage(CDImage* cdi, std::string* out_executable_name, std::vector* out_executable_data); -bool IsValidGameImage(CDImage* cdi); std::string GetGameHashId(GameHash hash); bool GetGameDetailsFromImage(CDImage* cdi, std::string* out_id, GameHash* out_hash); DiscRegion GetRegionForSerial(std::string_view serial); @@ -187,6 +187,7 @@ const std::string& GetGameSerial(); const std::string& GetGameTitle(); GameHash GetGameHash(); bool IsRunningUnknownGame(); +bool WasFastBooted(); const BIOS::ImageInfo* GetBIOSImageInfo(); const BIOS::Hash& GetBIOSHash();