diff --git a/src/duckstation/sdl_interface.cpp b/src/duckstation/sdl_interface.cpp index 4e20c9715..e4927fc10 100644 --- a/src/duckstation/sdl_interface.cpp +++ b/src/duckstation/sdl_interface.cpp @@ -274,6 +274,31 @@ void SDLInterface::ConnectDevices() m_system->SetController(0, m_controller); } +void SDLInterface::ResetPerformanceCounters() +{ + if (m_system) + { + m_last_frame_number = m_system->GetFrameNumber(); + m_last_internal_frame_number = m_system->GetInternalFrameNumber(); + m_last_global_tick_counter = m_system->GetGlobalTickCounter(); + } + else + { + m_last_frame_number = 0; + m_last_internal_frame_number = 0; + m_last_global_tick_counter = 0; + } + m_fps_timer.Reset(); +} + +void SDLInterface::ShutdownSystem() +{ + m_system.reset(); + m_paused = false; + m_display_texture = nullptr; + UpdateAudioVisualSync(); +} + std::unique_ptr SDLInterface::Create(const char* filename /* = nullptr */, const char* exp1_filename /* = nullptr */, const char* save_state_filename /* = nullptr */) @@ -942,7 +967,8 @@ void SDLInterface::DrawPoweredOffWindow() ImGui::PushStyleColor(ImGuiCol_ButtonHovered, 0xFF575757); ImGui::SetCursorPosX(button_left); - ImGui::Button("Resume", button_size); + if (ImGui::Button("Resume", button_size)) + DoResume(); ImGui::NewLine(); ImGui::SetCursorPosX(button_left); @@ -1131,25 +1157,34 @@ void SDLInterface::DrawOSDMessages() void SDLInterface::DoReset() { m_system->Reset(); - m_last_frame_number = 0; - m_last_internal_frame_number = 0; - m_last_global_tick_counter = 0; - m_fps_timer.Reset(); + ResetPerformanceCounters(); AddOSDMessage("System reset."); } void SDLInterface::DoPowerOff() { Assert(m_system); - - m_system.reset(); - m_paused = false; - m_display_texture = nullptr; + ShutdownSystem(); AddOSDMessage("System powered off."); - UpdateAudioVisualSync(); } -void SDLInterface::DoResume() {} +void SDLInterface::DoResume() +{ + Assert(!m_system); + if (!InitializeSystem()) + return; + + if (!LoadState(RESUME_SAVESTATE_FILENAME)) + { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Load state failed", + "Failed to load the resume save state. Stopping emulation.", m_window); + ShutdownSystem(); + return; + } + + ResetPerformanceCounters(); + ClearImGuiFocus(); +} void SDLInterface::DoStartDisc() { @@ -1163,6 +1198,7 @@ void SDLInterface::DoStartDisc() if (!InitializeSystem(path, nullptr)) return; + ResetPerformanceCounters(); ClearImGuiFocus(); } @@ -1174,6 +1210,7 @@ void SDLInterface::DoStartBIOS() if (!InitializeSystem(nullptr, nullptr)) return; + ResetPerformanceCounters(); ClearImGuiFocus(); } @@ -1189,6 +1226,9 @@ void SDLInterface::DoChangeDisc() AddOSDMessage(SmallString::FromFormat("Switched CD to '%s'", path)); else AddOSDMessage("Failed to switch CD. The log may contain further information."); + + ResetPerformanceCounters(); + ClearImGuiFocus(); } void SDLInterface::DoLoadState(u32 index) @@ -1197,10 +1237,7 @@ void SDLInterface::DoLoadState(u32 index) return; LoadState(GetSaveStateFilename(index)); - m_last_frame_number = m_system->GetFrameNumber(); - m_last_internal_frame_number = m_system->GetInternalFrameNumber(); - m_last_global_tick_counter = m_system->GetGlobalTickCounter(); - m_fps_timer.Reset(); + ResetPerformanceCounters(); ClearImGuiFocus(); } @@ -1317,4 +1354,16 @@ void SDLInterface::Run() } } } -} + + // Save state on exit so it can be resumed + if (m_system) + { + if (!SaveState(RESUME_SAVESTATE_FILENAME)) + { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "Save state failed", + "Saving state failed, you will not be able to resume this session.", m_window); + } + + ShutdownSystem(); + } +} \ No newline at end of file diff --git a/src/duckstation/sdl_interface.h b/src/duckstation/sdl_interface.h index 7183c973c..cb50d2590 100644 --- a/src/duckstation/sdl_interface.h +++ b/src/duckstation/sdl_interface.h @@ -39,6 +39,7 @@ public: private: static constexpr u32 NUM_QUICK_SAVE_STATES = 10; + static constexpr char RESUME_SAVESTATE_FILENAME[] = "savestate_resume.bin"; struct OSDMessage { @@ -61,6 +62,8 @@ private: bool InitializeSystem(const char* filename = nullptr, const char* exp1_filename = nullptr); void ConnectDevices(); + void ResetPerformanceCounters(); + void ShutdownSystem(); // We only pass mouse input through if it's grabbed bool IsWindowFullscreen() const;