Fix some common crashes

This commit is contained in:
izzy2lost
2025-11-14 03:02:29 -05:00
parent 9154b1f417
commit 9ff98c8b4c
4 changed files with 36 additions and 33 deletions
+5 -7
View File
@@ -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'
}
+12 -2
View File
@@ -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();
@@ -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
}
+1 -1
View File
@@ -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
}