From 80a11e8cbef249b5c2f347acd692419a0b4fd72a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 12 May 2025 13:33:27 +0200 Subject: [PATCH 1/7] Add sleep_random function for debugging purposes --- Common/TimeUtil.cpp | 9 +++++++++ Common/TimeUtil.h | 3 +++ 2 files changed, 12 insertions(+) diff --git a/Common/TimeUtil.cpp b/Common/TimeUtil.cpp index 1f16898d18b8..8522109d66cc 100644 --- a/Common/TimeUtil.cpp +++ b/Common/TimeUtil.cpp @@ -4,6 +4,7 @@ #include #include "Common/TimeUtil.h" +#include "Common/Data/Random/Rng.h" #include "Common/Log.h" #ifdef HAVE_LIBNX @@ -339,3 +340,11 @@ void GetCurrentTimeFormatted(char formattedTime[13]) { // Now tack on the milliseconds snprintf(formattedTime, 11, "%s:%03u", tmp, milliseconds % 1000); } + +// We don't even bother synchronizing this, it's fine if threads stomp a bit. +static GMRng g_sleepRandom; + +void sleep_random(double minSeconds, double maxSeconds) { + const double waitSeconds = minSeconds + (maxSeconds - minSeconds) * g_sleepRandom.F(); + sleep_precise(waitSeconds); +} diff --git a/Common/TimeUtil.h b/Common/TimeUtil.h index 2d33b5b9543d..f300cbdea5fd 100644 --- a/Common/TimeUtil.h +++ b/Common/TimeUtil.h @@ -25,6 +25,9 @@ void sleep_ms(int ms, const char *reason); // Precise sleep. Can consume a little bit of CPU on Windows at least. void sleep_precise(double seconds); +// Random sleep, used for debugging. +void sleep_random(double minSeconds, double maxSeconds); + // Yield. Signals that this thread is busy-waiting but wants to allow other hyperthreads to run. void yield(); From 988d4ad2c906d28056ce0ded0dcd77f3f17a5bf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 12 May 2025 13:45:48 +0200 Subject: [PATCH 2/7] Fix various translations --- assets/lang/ru_RU.ini | 2 +- assets/lang/sv_SE.ini | 36 ++++++++++++++++++------------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/assets/lang/ru_RU.ini b/assets/lang/ru_RU.ini index b7a7523634a4..33c39b4f4a0b 100644 --- a/assets/lang/ru_RU.ini +++ b/assets/lang/ru_RU.ini @@ -1380,7 +1380,7 @@ Off = Выкл. Oldest Save = Самое старое сохранение Only JPG and PNG images are supported = Поддерживаются только изображения в формате JPG и PNG Path does not exist! = Пути не существует! -Pause when not focused = &Пауза, когда окно не в фокусе +Pause when not focused = Пауза, когда окно не в фокусе Plugins = Плагины PSP Memory Stick = Карта памяти PSP PSP Model = Модель PSP diff --git a/assets/lang/sv_SE.ini b/assets/lang/sv_SE.ini index 3982d664c7e4..a2b357fe4eb3 100644 --- a/assets/lang/sv_SE.ini +++ b/assets/lang/sv_SE.ini @@ -487,7 +487,7 @@ Cannot boot ELF located outside mountRoot. = Kan inte starta upp en ELF som ligg Could not save screenshot file = Misslyckades med att spara skärmdump. D3D9or11 = Direct3D 9? (eller "nej" för Direct3D 11) D3D11CompilerMissing = D3DCompiler_47.dll saknas. Installera den eller tryck Ja för att försöka igen med Direct3D 9 istället. -D3D11InitializationError = Direct3D 11 initieringsfel +D3D11InitializationError = Fel under initiering av Direct3D 11 D3D11Missing = Ditt operativsystem inkluderar inte D3D11. Kör Windows Update.\n\nTryck Ja för att försöka igen med Direct3D 9 istället. D3D11NotSupported = Din GPU verkar inte klara av Direct3D 11.\n\nVill du försöka igen med Direct3D 9 istället? Disk full while writing data = Disken blev full under dataskrivning. @@ -838,7 +838,7 @@ Left = D-pad Vänster Load State = Läs in tillstånd Mute toggle = Mute toggle Next Slot = Nästa slot -None = None +None = Ingen Note = Not OpenChat = Öppna chatt Pause (no menu) = Paus @@ -902,7 +902,7 @@ Chat Screen Position = Chatt-rutans position Disconnected from AdhocServer = Bortkopplad från Adhoc-servern DNS Error Resolving = DNS-fel vid addressupplösning DNS server = DNS-server -Enable built-in PRO Adhoc Server = Enable built-in PRO Adhoc Server +Enable built-in PRO Adhoc Server = Kör den inbyggda PRO Adhoc-servern Enable network chat = Nätverkschatt Enable networking = Nätverk/wlan Enable UPnP = Använd UPnP (tar några sekunder att detektera) @@ -1030,12 +1030,12 @@ iOS builds = iOS builds license = Fri mjukvara enligt GPL 2.0+ list = forums och development-information PPSSPP Forums = PPSSPP Forums -Privacy Policy = Privacy policy -Share PPSSPP = Share PPSSPP +Privacy Policy = Integritetspolicy +Share PPSSPP = Dela PPSSPP specialthanks = Särskilt tack till: specialthanksKeithGalocy = at NVIDIA (hardware, advice) -specialthanksMaxim = for his amazing Atrac3+ decoder work -testing = testing +specialthanksMaxim = för hans stora arbete med Atrac3+-avkodning +testing = testning this translation by = denna översättning av: title = En snabb och portabel PSP-emulator tools = Gratisverktyg @@ -1176,27 +1176,27 @@ Date = Datum Filename = Filnamn No screenshot = Ingen skärmdump None yet. Things will appear here after you save. = None yet. Things will appear here after you save. -Nothing matching '%1' was found. = Nothing matching '%1' was found. +Nothing matching '%1' was found. = Ingenting som matchar '%1' hittades. Save Data = Sparad data Save States = Sparade states Savedata Manager = Savedata manager -Showing matches for '%1'. = Showing matches for '%1'. +Showing matches for '%1'. = Visar matchande rader för '%1'. Size = Size [Screen] Cardboard VR OFF = Cardboard VR av -Chainfire3DWarning = WARNING: Chainfire3D detected, may cause problems. +Chainfire3DWarning = WARNING: Chainfire3D detekterat, kan orsaka problem. ExtractedISOWarning = Extracted ISOs often don't work.\nPlay the ISO file directly. Failed to load state = Misslyckades ladda state Failed to save state = Misslyckades spara state -GLToolsWarning = WARNING: GLTools detected, may cause problems. +GLToolsWarning = WARNING: GLTools detecterat, kan orsaka problem. In menu = I menyn Loaded State = State laddat Loaded. Game may refuse to save over different savedata. = Loaded. Game may refuse to save over different savedata. Loaded. Game may refuse to save over newer savedata. = Loaded. Game may refuse to save over newer savedata. Loaded. Save in game, restart, and load for less bugs. = Loaded. Save in game, restart, and load for less bugs. -LoadStateDoesntExist = Misslyckades ladda state: Savestate doesn't exist! -LoadStateWrongVersion = Misslyckades ladda state: Savestate is for an older version of PPSSPP! +LoadStateDoesntExist = Misslyckades ladda state: Savestatet finns inte! +LoadStateWrongVersion = Misslyckades ladda state: Savestatet är för en annan version av PPSSPP! norewind = No rewind save states available. Playing = Spelar PressESC = Tryck ESC för att öppna pausemenyn. @@ -1206,7 +1206,7 @@ Saved State = State sparat saveNewTextures_false = Textur-sparning avstängt saveNewTextures_true = Texturer sparas State load undone = State load ogjort -Untitled PSP game = Untitled PSP game +Untitled PSP game = PSP-spel utan namn [Search] Clear filter = Rensa filter @@ -1273,7 +1273,7 @@ JIT available = JIT är tillgänglig Lang/Region = Språk/Region Memory Page Size = Minnessidesstorlek Native resolution = Native upplösning -No GPU driver bugs detected = No GPU driver bugs detected +No GPU driver bugs detected = Inga buggar i GPU-drivern upptäckta OGL Extensions = OGL extensioner OpenGL ES 2.0 Extensions = OpenGL ES 2.0 extensioner OpenGL ES 3.0 Extensions = OpenGL ES 3.0 extensioner @@ -1311,9 +1311,9 @@ App switching mode = App switching mode Ask for exit confirmation after seconds = Ask for exit confirmation after seconds Auto = Auto Auto Load Savestate = Ladda savestate automatiskt -AVI Dump started. = AVI dump started -AVI Dump stopped. = AVI dump stopped -Cache ISO in RAM = Cachea hela ISO:n i RAM +AVI Dump started. = AVI-dump startad +AVI Dump stopped. = AVI-dump stoppad +Cache ISO in RAM = Cache-a hela ISO:n i RAM Change CPU Clock = Ändra CPU-frekvens (kan orsaka instabilitet) Color Saturation = Färgmättnad Color Tint = Färgförskjutning From c59cec4c975deeff5ae5de2b4b4a08840b610830 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 12 May 2025 14:06:17 +0200 Subject: [PATCH 3/7] gradle: Use file(...).text instead of new File, .write. See #20326 --- android/build.gradle | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index b5fc122301e0..dc10ecaceaf1 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -73,9 +73,8 @@ android { } else { println "(not using these:) Android Version Name, Code: " + androidGitVersion.name() + " " + androidGitVersion.code() } - - new File("versionname.txt").write(androidGitVersion.name()) - new File("versioncode.txt").write(androidGitVersion.code().toString()) + file("versionname.txt").text = androidGitVersion.name() + file("versioncode.txt").text = androidGitVersion.code().toString() minSdk 9 targetSdk 35 From e920556319d0b1210ee71b341fd9cf7691d88e66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 12 May 2025 14:39:36 +0200 Subject: [PATCH 4/7] Yet another gradle upgrade. --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9e156b14f921..222765d355f1 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.9.1' + classpath 'com.android.tools.build:gradle:8.9.2' } } From c984897b2ec8dad8b06c1b7ace08f2871ff79e68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 13 May 2025 10:46:06 +0200 Subject: [PATCH 5/7] Minor cleanup, check --- UI/EmuScreen.cpp | 34 ++++++++++++++++------------------ UI/EmuScreen.h | 2 -- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 894c52cd29b7..b9cdebc15afe 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -440,8 +440,10 @@ void EmuScreen::bootComplete() { saveStateSlot_ = SaveState::GetCurrentSlot(); - loadingViewColor_->Divert(0x00FFFFFF, 0.2f); - loadingViewVisible_->Divert(UI::V_INVISIBLE, 0.2f); + if (loadingViewColor_) + loadingViewColor_->Divert(0x00FFFFFF, 0.2f); + if (loadingViewVisible_) + loadingViewVisible_->Divert(UI::V_INVISIBLE, 0.2f); std::string gameID = g_paramSFO.GetValueString("DISC_ID"); g_Config.TimeTracker().Start(gameID); @@ -1217,7 +1219,14 @@ void EmuScreen::CreateViews() { root_->Add(buttons); resumeButton_ = buttons->Add(new Button(dev->T("Resume"))); - resumeButton_->OnClick.Handle(this, &EmuScreen::OnResume); + resumeButton_->OnClick.Add([this](UI::EventParams &) { + if (coreState == CoreState::CORE_RUNTIME_ERROR) { + // Force it! + Memory::MemFault_IgnoreLastCrash(); + coreState = CoreState::CORE_RUNNING_CPU; + } + return UI::EVENT_DONE; + }); resumeButton_->SetVisibility(V_GONE); resetButton_ = buttons->Add(new Button(dev->T("Reset"))); @@ -1237,7 +1246,10 @@ void EmuScreen::CreateViews() { backButton_->SetVisibility(V_GONE); cardboardDisableButton_ = root_->Add(new Button(sc->T("Cardboard VR OFF"), new AnchorLayoutParams(bounds.centerX(), NONE, NONE, 30, true))); - cardboardDisableButton_->OnClick.Handle(this, &EmuScreen::OnDisableCardboard); + cardboardDisableButton_->OnClick.Add([](UI::EventParams &) { + g_Config.bEnableCardboardVR = false; + return UI::EVENT_DONE; + }); cardboardDisableButton_->SetVisibility(V_GONE); cardboardDisableButton_->SetScale(0.65f); // make it smaller - this button can be in the way otherwise. @@ -1331,11 +1343,6 @@ UI::EventReturn EmuScreen::OnDevTools(UI::EventParams ¶ms) { return UI::EVENT_DONE; } -UI::EventReturn EmuScreen::OnDisableCardboard(UI::EventParams ¶ms) { - g_Config.bEnableCardboardVR = false; - return UI::EVENT_DONE; -} - UI::EventReturn EmuScreen::OnChat(UI::EventParams ¶ms) { if (chatButton_ != nullptr && chatButton_->GetVisibility() == UI::V_VISIBLE) { chatButton_->SetVisibility(UI::V_GONE); @@ -1357,15 +1364,6 @@ UI::EventReturn EmuScreen::OnChat(UI::EventParams ¶ms) { return UI::EVENT_DONE; } -UI::EventReturn EmuScreen::OnResume(UI::EventParams ¶ms) { - if (coreState == CoreState::CORE_RUNTIME_ERROR) { - // Force it! - Memory::MemFault_IgnoreLastCrash(); - coreState = CoreState::CORE_RUNNING_CPU; - } - return UI::EVENT_DONE; -} - // To avoid including proAdhoc.h, which includes a lot of stuff. int GetChatMessageCount(); diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index a18d2866c66f..17c5d64eaa41 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -74,9 +74,7 @@ class EmuScreen : public UIScreen { private: void CreateViews() override; UI::EventReturn OnDevTools(UI::EventParams ¶ms); - UI::EventReturn OnDisableCardboard(UI::EventParams ¶ms); UI::EventReturn OnChat(UI::EventParams ¶ms); - UI::EventReturn OnResume(UI::EventParams ¶ms); void ProcessGameBoot(const Path &filename); bool bootAllowStorage(const Path &filename); From 1ec9ba509ece194a0ad9b9ff5c504834ed3a8958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 13 May 2025 12:01:17 +0200 Subject: [PATCH 6/7] Small refactor of vblank callbacks --- Core/HW/Display.h | 5 ++- UI/EmuScreen.cpp | 102 +++++++++++++++++++--------------------------- UI/EmuScreen.h | 8 +++- 3 files changed, 51 insertions(+), 64 deletions(-) diff --git a/Core/HW/Display.h b/Core/HW/Display.h index 1f0497c13994..a76a474b94b0 100644 --- a/Core/HW/Display.h +++ b/Core/HW/Display.h @@ -18,11 +18,12 @@ #pragma once #include +#include class PointerWrap; -typedef void (*VblankCallback)(); -// Listen for vblank events. +typedef std::function VblankCallback; +// Listen for vblank events. Callbacks are cleared in DisplayHWShutdown(). void __DisplayListenVblank(VblankCallback callback); typedef void (*FlipCallback)(void *userdata); void __DisplayListenFlip(FlipCallback callback, void *userdata); diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index b9cdebc15afe..80c074451345 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -111,11 +111,6 @@ using namespace std::placeholders; static AVIDump avi; #endif -// TODO: Ugly! -static bool frameStep_; -static int lastNumFlips; -static bool startDumping; - extern bool g_TakeScreenshot; static void AssertCancelCallback(const char *message, void *userdata) { @@ -127,35 +122,6 @@ static void AssertCancelCallback(const char *message, void *userdata) { emuScreen->SendImDebuggerCommand(ImCommand{ ImCmd::SHOW_IN_CPU_DISASM, currentMIPS->pc }); } -static void __EmuScreenVblank() -{ - auto sy = GetI18NCategory(I18NCat::SYSTEM); - - if (frameStep_ && lastNumFlips != gpuStats.numFlips) { - frameStep_ = false; - Core_Break(BreakReason::FrameAdvance, 0); - lastNumFlips = gpuStats.numFlips; - } -#ifndef MOBILE_DEVICE - if (g_Config.bDumpFrames && !startDumping) - { - avi.Start(PSP_CoreParameter().renderWidth, PSP_CoreParameter().renderHeight); - g_OSD.Show(OSDType::MESSAGE_INFO, sy->T("AVI Dump started."), 1.0f); - startDumping = true; - } - if (g_Config.bDumpFrames && startDumping) - { - avi.AddFrame(); - } - else if (!g_Config.bDumpFrames && startDumping) - { - avi.Stop(); - g_OSD.Show(OSDType::MESSAGE_INFO, sy->T("AVI Dump stopped."), 1.0f); - startDumping = false; - } -#endif -} - // Handles control rotation due to internal screen rotation. static void SetPSPAnalog(int stick, float x, float y) { switch (g_Config.iInternalScreenRotation) { @@ -189,10 +155,7 @@ static void SetPSPAnalog(int stick, float x, float y) { EmuScreen::EmuScreen(const Path &filename) : gamePath_(filename) { saveStateSlot_ = SaveState::GetCurrentSlot(); - __DisplayListenVblank(__EmuScreenVblank); - frameStep_ = false; lastNumFlips = gpuStats.numFlips; - startDumping = false; controlMapper_.SetCallbacks( std::bind(&EmuScreen::onVKey, this, _1, _2), std::bind(&EmuScreen::onVKeyAnalog, this, _1, _2), @@ -366,6 +329,8 @@ void EmuScreen::ProcessGameBoot(const Path &filename) { // Only call this on successful boot. void EmuScreen::bootComplete() { + __DisplayListenVblank([this]() {HandleVBlank(); }); + // Initialize retroachievements, now that we're on the right thread. if (g_Config.bAchievementsEnable) { std::string errorString; @@ -803,14 +768,6 @@ void EmuScreen::onVKey(VirtKey virtualKeyCode, bool down) { } break; - case VIRTKEY_FRAME_ADVANCE: - // Can't do this reliably in an async fashion, so we just set a variable. - // Is this used by anyone? There's no good way to resume, other than PAUSE_NO_MENU or the debugger. - if (down && !NetworkWarnUserIfOnlineAndCantSpeed()) { - doFrameAdvance_.store(true); - } - break; - case VIRTKEY_RESET_EMULATION: if (down) { System_PostUIMessage(UIMessage::REQUEST_GAME_RESET); @@ -1009,6 +966,19 @@ void EmuScreen::ProcessVKey(VirtKey virtKey) { break; } + case VIRTKEY_FRAME_ADVANCE: + // Can't do this reliably in an async fashion, so we just set a variable. + // Is this used by anyone? There's no user-friendly way to resume, other than PAUSE_NO_MENU or the debugger. + if (!NetworkWarnUserIfOnlineAndCantSpeed()) { + if (Core_IsStepping()) { + Core_Resume(); + frameStep_ = true; + } else { + Core_Break(BreakReason::FrameAdvance); + } + } + break; + default: break; } @@ -1510,6 +1480,31 @@ void EmuScreen::darken() { } } +void EmuScreen::HandleVBlank() { + if (frameStep_ && lastNumFlips != gpuStats.numFlips) { + frameStep_ = false; + Core_Break(BreakReason::FrameAdvance, 0); + lastNumFlips = gpuStats.numFlips; + } +#ifndef MOBILE_DEVICE + if (g_Config.bDumpFrames && !startDumping) + { + auto sy = GetI18NCategory(I18NCat::SYSTEM); + avi.Start(PSP_CoreParameter().renderWidth, PSP_CoreParameter().renderHeight); + g_OSD.Show(OSDType::MESSAGE_INFO, sy->T("AVI Dump started."), 1.0f); + startDumping = true; + } + if (g_Config.bDumpFrames && startDumping) { + avi.AddFrame(); + } else if (!g_Config.bDumpFrames && startDumping) { + auto sy = GetI18NCategory(I18NCat::SYSTEM); + avi.Stop(); + g_OSD.Show(OSDType::MESSAGE_INFO, sy->T("AVI Dump stopped."), 1.0f); + startDumping = false; + } +#endif +} + ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) { // Moved from update, because we want it to be possible for booting to happen even when the screen // is in the background, like when choosing Reset from the pause menu. @@ -1530,7 +1525,7 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) { ProcessQueuedVKeys(); - bool skipBufferEffects = g_Config.bSkipBufferEffects; + const bool skipBufferEffects = g_Config.bSkipBufferEffects; bool framebufferBound = false; @@ -1629,19 +1624,6 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) { PSP_UpdateDebugStats((DebugOverlay)g_Config.iDebugOverlay == DebugOverlay::DEBUG_STATS || g_Config.bLogFrameDrops); - if (doFrameAdvance_.exchange(false)) { - if (!Achievements::WarnUserIfHardcoreModeActive(false)) { - // If game is running, pause emulation immediately. Otherwise, advance a single frame. - if (Core_IsStepping()) { - frameStep_ = true; - Core_Resume(); - } else if (!frameStep_) { - lastNumFlips = gpuStats.numFlips; - Core_Break(BreakReason::FrameAdvance, 0); - } - } - } - // Running it early allows things like direct readbacks of buffers, things we can't do // when we have started the final render pass. Well, technically we probably could with some manipulation // of pass order in the render managers.. @@ -1663,7 +1645,7 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) { switch (coreState) { case CORE_NEXTFRAME: // Reached the end of the frame while running at full blast, all good. Set back to running for the next frame - coreState = CORE_RUNNING_CPU; + coreState = frameStep_ ? CORE_STEPPING_CPU : CORE_RUNNING_CPU; flags |= ScreenRenderFlags::HANDLED_THROTTLING; Achievements::FrameUpdate(); break; diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index 17c5d64eaa41..8788de5ac547 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -76,6 +76,7 @@ class EmuScreen : public UIScreen { UI::EventReturn OnDevTools(UI::EventParams ¶ms); UI::EventReturn OnChat(UI::EventParams ¶ms); + void HandleVBlank(); void ProcessGameBoot(const Path &filename); bool bootAllowStorage(const Path &filename); void bootComplete(); @@ -130,8 +131,6 @@ class EmuScreen : public UIScreen { std::string extraAssertInfoStr_; - std::atomic doFrameAdvance_{}; - ControlMapper controlMapper_; std::unique_ptr imDebugger_ = nullptr; @@ -151,6 +150,11 @@ class EmuScreen : public UIScreen { std::vector queuedVirtKeys_; ImGuiContext *ctx_ = nullptr; + + // TODO: Ugly! + bool frameStep_ = false; + int lastNumFlips = -1; + bool startDumping = false; }; bool MustRunBehind(); From 9e0c98a87b13024de759266851c97cc7d398aa2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 13 May 2025 12:10:41 +0200 Subject: [PATCH 7/7] Simplify framestep logic --- UI/EmuScreen.cpp | 29 +++++++++++++++-------------- UI/EmuScreen.h | 3 +-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 80c074451345..9089e131e5c4 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -155,7 +155,6 @@ static void SetPSPAnalog(int stick, float x, float y) { EmuScreen::EmuScreen(const Path &filename) : gamePath_(filename) { saveStateSlot_ = SaveState::GetCurrentSlot(); - lastNumFlips = gpuStats.numFlips; controlMapper_.SetCallbacks( std::bind(&EmuScreen::onVKey, this, _1, _2), std::bind(&EmuScreen::onVKeyAnalog, this, _1, _2), @@ -442,11 +441,11 @@ EmuScreen::~EmuScreen() { g_logManager.EnableOutput(LogOutput::RingBuffer); #ifndef MOBILE_DEVICE - if (g_Config.bDumpFrames && startDumping) + if (g_Config.bDumpFrames && startDumping_) { avi.Stop(); g_OSD.Show(OSDType::MESSAGE_INFO, "AVI Dump stopped.", 2.0f); - startDumping = false; + startDumping_ = false; } #endif @@ -1480,27 +1479,22 @@ void EmuScreen::darken() { } } +// TODO: We probably shouldn't even handle frame dumping at vblank, we can just as well handle it directly in EmuScreen. void EmuScreen::HandleVBlank() { - if (frameStep_ && lastNumFlips != gpuStats.numFlips) { - frameStep_ = false; - Core_Break(BreakReason::FrameAdvance, 0); - lastNumFlips = gpuStats.numFlips; - } #ifndef MOBILE_DEVICE - if (g_Config.bDumpFrames && !startDumping) - { + if (g_Config.bDumpFrames && !startDumping_) { auto sy = GetI18NCategory(I18NCat::SYSTEM); avi.Start(PSP_CoreParameter().renderWidth, PSP_CoreParameter().renderHeight); g_OSD.Show(OSDType::MESSAGE_INFO, sy->T("AVI Dump started."), 1.0f); - startDumping = true; + startDumping_ = true; } - if (g_Config.bDumpFrames && startDumping) { + if (g_Config.bDumpFrames && startDumping_) { avi.AddFrame(); - } else if (!g_Config.bDumpFrames && startDumping) { + } else if (!g_Config.bDumpFrames && startDumping_) { auto sy = GetI18NCategory(I18NCat::SYSTEM); avi.Stop(); g_OSD.Show(OSDType::MESSAGE_INFO, sy->T("AVI Dump stopped."), 1.0f); - startDumping = false; + startDumping_ = false; } #endif } @@ -1688,6 +1682,13 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) { PSP_EndHostFrame(); } + if (frameStep_) { + frameStep_ = false; + if (coreState == CORE_RUNNING_CPU) { + Core_Break(BreakReason::FrameAdvance, 0); + } + } + if (gpu && gpu->PresentedThisFrame()) { framebufferBound = true; } diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index 8788de5ac547..b0a2a8758700 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -153,8 +153,7 @@ class EmuScreen : public UIScreen { // TODO: Ugly! bool frameStep_ = false; - int lastNumFlips = -1; - bool startDumping = false; + bool startDumping_ = false; }; bool MustRunBehind();