From c3be0495719104fa0bc7a450aac1a6ae5d4711b9 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 26 Jul 2025 19:48:52 +0200 Subject: [PATCH] Android: Don't let RetroAchievements override onPause When Android sends Dolphin to the background, emulation *must* pause, otherwise emulation continues running and continues outputting audio to the user. RetroAchievements mustn't be allowed to override it. --- .../main/java/org/dolphinemu/dolphinemu/NativeLibrary.java | 2 +- .../dolphinemu/dolphinemu/activities/EmulationActivity.kt | 2 +- .../dolphinemu/dolphinemu/fragments/EmulationFragment.kt | 2 +- Source/Android/jni/MainAndroid.cpp | 6 ++++-- Source/Core/Core/Core.cpp | 4 ++-- Source/Core/Core/Core.h | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java index e9ab837619..69b9a94595 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java @@ -362,7 +362,7 @@ public final class NativeLibrary /** * Pauses emulation. */ - public static native void PauseEmulation(); + public static native void PauseEmulation(boolean overrideAchievementRestrictions); /** * Stops emulation. diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.kt index 112b780df0..b743328920 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.kt @@ -455,7 +455,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider { MENU_ACTION_REFRESH_WIIMOTES -> NativeLibrary.RefreshWiimotes() MENU_ACTION_PAUSE_EMULATION -> { hasUserPausedEmulation = true - NativeLibrary.PauseEmulation() + NativeLibrary.PauseEmulation(false) } MENU_ACTION_UNPAUSE_EMULATION -> { diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.kt index eeb223c3db..04db24c03a 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.kt @@ -109,7 +109,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { override fun onPause() { if (NativeLibrary.IsRunningAndUnpaused() && !NativeLibrary.IsShowingAlertMessage()) { Log.debug("[EmulationFragment] Pausing emulation.") - NativeLibrary.PauseEmulation() + NativeLibrary.PauseEmulation(true) } super.onPause() } diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index be1d168730..7f4daf54dd 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -271,10 +271,12 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_UnPauseEmula Core::SetState(Core::System::GetInstance(), Core::State::Running); } -JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_PauseEmulation(JNIEnv*, jclass) +JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_PauseEmulation( + JNIEnv*, jclass, bool override_achievement_restrictions) { HostThreadLock guard; - Core::SetState(Core::System::GetInstance(), Core::State::Paused); + Core::SetState(Core::System::GetInstance(), Core::State::Paused, true, + override_achievement_restrictions); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_StopEmulation(JNIEnv*, jclass) diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index a122a467e9..ccb1ad68bd 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -672,7 +672,7 @@ static void EmuThread(Core::System& system, std::unique_ptr boot // Set or get the running state void SetState(Core::System& system, State state, bool report_state_change, - bool initial_execution_state) + bool override_achievement_restrictions) { // State cannot be controlled until the CPU Thread is operational if (s_state.load() != State::Running) @@ -682,7 +682,7 @@ void SetState(Core::System& system, State state, bool report_state_change, { case State::Paused: #ifdef USE_RETRO_ACHIEVEMENTS - if (!initial_execution_state && !AchievementManager::GetInstance().CanPause()) + if (!override_achievement_restrictions && !AchievementManager::GetInstance().CanPause()) return; #endif // USE_RETRO_ACHIEVEMENTS // NOTE: GetState() will return State::Paused immediately, even before anything has diff --git a/Source/Core/Core/Core.h b/Source/Core/Core/Core.h index 8ff3b32626..68a402772a 100644 --- a/Source/Core/Core/Core.h +++ b/Source/Core/Core/Core.h @@ -146,7 +146,7 @@ bool WantsDeterminism(); // [NOT THREADSAFE] For use by Host only void SetState(Core::System& system, State state, bool report_state_change = true, - bool initial_execution_state = false); + bool override_achievement_restrictions = false); State GetState(Core::System& system); void SaveScreenShot();