From 9ff98c8b4c3f33a4bdfbe9931e109ecabc7eafd4 Mon Sep 17 00:00:00 2001 From: izzy2lost Date: Fri, 14 Nov 2025 03:02:29 -0500 Subject: [PATCH] Fix some common crashes --- app/build.gradle | 12 +++--- app/src/main/cpp/native-lib.cpp | 14 ++++++- .../java/com/izzy2lost/psx2/MainActivity.java | 41 ++++++++----------- build.gradle | 2 +- 4 files changed, 36 insertions(+), 33 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 5367257..3b33dba 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,8 +29,8 @@ android { applicationId = "com.izzy2lost.psx2" minSdk = 26 targetSdk = 36 - versionCode 15 - versionName "1.1.3" + versionCode 16 + versionName "1.1.4" // APK base.archivesName = "PSX2_${versionCode}_${new Date().format('yyyyMMddHHmm')}" @@ -101,11 +101,9 @@ android { useLegacyPackaging = true keepDebugSymbols += ['**/*.so'] } - exclude 'META-INF/DEPENDENCIES' - exclude 'META-INF/LICENSE' - exclude 'META-INF/LICENSE.txt' - exclude 'META-INF/NOTICE' - exclude 'META-INF/NOTICE.txt' + resources { + excludes += ['META-INF/DEPENDENCIES', 'META-INF/LICENSE', 'META-INF/LICENSE.txt', 'META-INF/NOTICE', 'META-INF/NOTICE.txt'] + } } buildToolsVersion = '36.0.0' } diff --git a/app/src/main/cpp/native-lib.cpp b/app/src/main/cpp/native-lib.cpp index 8d2a276..2cd0cf4 100644 --- a/app/src/main/cpp/native-lib.cpp +++ b/app/src/main/cpp/native-lib.cpp @@ -204,8 +204,10 @@ Java_com_izzy2lost_psx2_NativeApp_initialize(JNIEnv *env, jclass clazz, si.SetBoolValue("InputSources", "SDL", true); si.SetBoolValue("InputSources", "XInput", false); - // we don't need any sound output - si.SetStringValue("SPU2/Output", "OutputModule", "nullout"); + // Use Oboe audio backend for Android (low-latency audio) + si.SetStringValue("SPU2/Output", "Backend", "Oboe"); + si.SetIntValue("SPU2/Output", "BufferMS", 100); // 100ms buffer for stability + si.SetIntValue("SPU2/Output", "OutputLatencyMS", 20); // 20ms output latency // none of the bindings are going to resolve to anything Pad::ClearPortBindings(si, 0); @@ -1186,8 +1188,16 @@ Java_com_izzy2lost_psx2_NativeApp_runVMThread(JNIEnv *env, jclass clazz, // Apply per-game settings (if any) before applying core settings ApplyPerGameSettingsForPath(_szPath); + // Ensure VM is properly shut down before initializing + if (VMManager::HasValidVM()) { + Console.Warning("VM still running from previous session, shutting down..."); + VMManager::Shutdown(false); + } + if (!VMManager::Internal::CPUThreadInitialize()) { + Console.Error("CPUThreadInitialize failed"); VMManager::Internal::CPUThreadShutdown(); + return false; } VMManager::ApplySettings(); diff --git a/app/src/main/java/com/izzy2lost/psx2/MainActivity.java b/app/src/main/java/com/izzy2lost/psx2/MainActivity.java index f2269de..f7167ea 100644 --- a/app/src/main/java/com/izzy2lost/psx2/MainActivity.java +++ b/app/src/main/java/com/izzy2lost/psx2/MainActivity.java @@ -496,13 +496,20 @@ public class MainActivity extends AppCompatActivity implements GamesCoverDialogF f.setCancelable(false); f.show(getSupportFragmentManager(), "setup_wizard"); } else { - // Don't auto-open games dialog on app start - // User can open it manually via home button or controller - // This prevents crashes on devices where BIOS boot + dialog opening is too much at once + // Only auto-open games dialog if this is NOT the first boot after setup + // (Setup wizard handles opening the games dialog on first completion) boolean hasOpenedGamesAfterSetup = prefs.getBoolean("has_opened_games_after_setup", false); - if (!hasOpenedGamesAfterSetup) { - // Mark as opened so we don't show this message again - prefs.edit().putBoolean("has_opened_games_after_setup", true).apply(); + if (hasOpenedGamesAfterSetup) { + try { + final View decor = (getWindow() != null) ? getWindow().getDecorView() : null; + if (decor != null) { + decor.postDelayed(() -> { + if (!isFinishing() && !mSetupWizardActive) { + openGamesDialog(); + } + }, 1600); // small delay to let BIOS boot briefly + } + } catch (Throwable ignored) {} } } @@ -567,17 +574,6 @@ public class MainActivity extends AppCompatActivity implements GamesCoverDialogF if (btn_settings != null) { btn_settings.setOnClickListener(v -> { try { - // Pause the emulation (BIOS or game) before opening drawer - // This prevents crashes on some devices when drawer opens during emulation - if (isThread() && !NativeApp.isPaused()) { - try { - NativeApp.pause(); - android.util.Log.d("MainActivity", "Paused emulation before opening drawer"); - } catch (Throwable e) { - android.util.Log.e("MainActivity", "Error pausing before drawer open: " + e.getMessage()); - } - } - // Open the drawer via post() to avoid reentrancy/layout timing issues // (programmatic open can sometimes race with layout/insets handling) DrawerLayout drawer = findViewById(R.id.drawer_layout); @@ -2505,21 +2501,20 @@ public class MainActivity extends AppCompatActivity implements GamesCoverDialogF mDrawerOpen = false; android.util.Log.d("DrawerTracking", "Drawer closed. Dialog count: " + mOpenDialogCount); if (mOpenDialogCount == 0 && !mDrawerOpen) { - // All dialogs closed and no drawers open, resume the emulation (game or BIOS) with a small delay + // All dialogs closed and no drawers open, resume the game with a small delay View root = findViewById(android.R.id.content); if (root != null) { root.postDelayed(() -> { try { - // Resume if emulation thread is running and paused (works for both game and BIOS) - if (isThread() && NativeApp.isPaused()) { - android.util.Log.d("DrawerTracking", "Resuming emulation on drawer close"); + if (hasSelectedGame() && isThread() && NativeApp.isPaused()) { + android.util.Log.d("DrawerTracking", "Resuming game on drawer close"); NativeApp.resume(); updatePausePlayButton(); } else { - android.util.Log.d("DrawerTracking", "Not resuming - isThread: " + isThread() + ", isPaused: " + (isThread() ? NativeApp.isPaused() : "N/A")); + android.util.Log.d("DrawerTracking", "Not resuming - hasGame: " + hasSelectedGame() + ", isThread: " + isThread() + ", isPaused: " + (isThread() ? NativeApp.isPaused() : "N/A")); } } catch (Throwable e) { - android.util.Log.e("DrawerTracking", "Error resuming emulation: " + e.getMessage()); + android.util.Log.e("DrawerTracking", "Error resuming game: " + e.getMessage()); } }, 100); // Small delay to let drawer fully close } diff --git a/build.gradle b/build.gradle index 06e590f..29df2dc 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id 'com.android.application' version '8.11.1' apply false + id 'com.android.application' version '8.13.1' apply false }