This commit is contained in:
Felix Nüsse 2025-08-10 22:24:18 +02:00 committed by GitHub
commit 0dcbad95dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 72 additions and 15 deletions

View file

@ -2,7 +2,6 @@
package org.dolphinemu.dolphinemu.activities package org.dolphinemu.dolphinemu.activities
import android.annotation.SuppressLint
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.graphics.Rect import android.graphics.Rect
@ -53,6 +52,7 @@ import org.dolphinemu.dolphinemu.fragments.EmulationFragment
import org.dolphinemu.dolphinemu.fragments.MenuFragment import org.dolphinemu.dolphinemu.fragments.MenuFragment
import org.dolphinemu.dolphinemu.fragments.SaveLoadStateFragment import org.dolphinemu.dolphinemu.fragments.SaveLoadStateFragment
import org.dolphinemu.dolphinemu.fragments.SaveLoadStateFragment.SaveOrLoad import org.dolphinemu.dolphinemu.fragments.SaveLoadStateFragment.SaveOrLoad
import org.dolphinemu.dolphinemu.model.SAVESLOT.*
import org.dolphinemu.dolphinemu.overlay.InputOverlay import org.dolphinemu.dolphinemu.overlay.InputOverlay
import org.dolphinemu.dolphinemu.overlay.InputOverlayPointer import org.dolphinemu.dolphinemu.overlay.InputOverlayPointer
import org.dolphinemu.dolphinemu.ui.main.MainPresenter import org.dolphinemu.dolphinemu.ui.main.MainPresenter
@ -60,6 +60,7 @@ import org.dolphinemu.dolphinemu.ui.main.ThemeProvider
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization import org.dolphinemu.dolphinemu.utils.DirectoryInitialization
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper import org.dolphinemu.dolphinemu.utils.FileBrowserHelper
import org.dolphinemu.dolphinemu.utils.Log
import org.dolphinemu.dolphinemu.utils.ThemeHelper import org.dolphinemu.dolphinemu.utils.ThemeHelper
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -456,6 +457,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
MENU_ACTION_PAUSE_EMULATION -> { MENU_ACTION_PAUSE_EMULATION -> {
hasUserPausedEmulation = true hasUserPausedEmulation = true
NativeLibrary.PauseEmulation(false) NativeLibrary.PauseEmulation(false)
saveOnExit()
} }
MENU_ACTION_UNPAUSE_EMULATION -> { MENU_ACTION_UNPAUSE_EMULATION -> {
@ -464,22 +466,22 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
} }
MENU_ACTION_TAKE_SCREENSHOT -> NativeLibrary.SaveScreenShot() MENU_ACTION_TAKE_SCREENSHOT -> NativeLibrary.SaveScreenShot()
MENU_ACTION_QUICK_SAVE -> NativeLibrary.SaveState(9, false) MENU_ACTION_QUICK_SAVE -> NativeLibrary.SaveState(QUICKSAVE.slot, false)
MENU_ACTION_QUICK_LOAD -> NativeLibrary.LoadState(9) MENU_ACTION_QUICK_LOAD -> NativeLibrary.LoadState(QUICKSAVE.slot)
MENU_ACTION_SAVE_ROOT -> showSubMenu(SaveOrLoad.SAVE) MENU_ACTION_SAVE_ROOT -> showSubMenu(SaveOrLoad.SAVE)
MENU_ACTION_LOAD_ROOT -> showSubMenu(SaveOrLoad.LOAD) MENU_ACTION_LOAD_ROOT -> showSubMenu(SaveOrLoad.LOAD)
MENU_ACTION_SAVE_SLOT1 -> NativeLibrary.SaveState(0, false) MENU_ACTION_SAVE_SLOT1 -> NativeLibrary.SaveState(SLOT1.slot, false)
MENU_ACTION_SAVE_SLOT2 -> NativeLibrary.SaveState(1, false) MENU_ACTION_SAVE_SLOT2 -> NativeLibrary.SaveState(SLOT2.slot, false)
MENU_ACTION_SAVE_SLOT3 -> NativeLibrary.SaveState(2, false) MENU_ACTION_SAVE_SLOT3 -> NativeLibrary.SaveState(SLOT3.slot, false)
MENU_ACTION_SAVE_SLOT4 -> NativeLibrary.SaveState(3, false) MENU_ACTION_SAVE_SLOT4 -> NativeLibrary.SaveState(SLOT4.slot, false)
MENU_ACTION_SAVE_SLOT5 -> NativeLibrary.SaveState(4, false) MENU_ACTION_SAVE_SLOT5 -> NativeLibrary.SaveState(SLOT5.slot, false)
MENU_ACTION_SAVE_SLOT6 -> NativeLibrary.SaveState(5, false) MENU_ACTION_SAVE_SLOT6 -> NativeLibrary.SaveState(SLOT6.slot, false)
MENU_ACTION_LOAD_SLOT1 -> NativeLibrary.LoadState(0) MENU_ACTION_LOAD_SLOT1 -> NativeLibrary.LoadState(SLOT1.slot)
MENU_ACTION_LOAD_SLOT2 -> NativeLibrary.LoadState(1) MENU_ACTION_LOAD_SLOT2 -> NativeLibrary.LoadState(SLOT2.slot)
MENU_ACTION_LOAD_SLOT3 -> NativeLibrary.LoadState(2) MENU_ACTION_LOAD_SLOT3 -> NativeLibrary.LoadState(SLOT3.slot)
MENU_ACTION_LOAD_SLOT4 -> NativeLibrary.LoadState(3) MENU_ACTION_LOAD_SLOT4 -> NativeLibrary.LoadState(SLOT4.slot)
MENU_ACTION_LOAD_SLOT5 -> NativeLibrary.LoadState(4) MENU_ACTION_LOAD_SLOT5 -> NativeLibrary.LoadState(SLOT5.slot)
MENU_ACTION_LOAD_SLOT6 -> NativeLibrary.LoadState(5) MENU_ACTION_LOAD_SLOT6 -> NativeLibrary.LoadState(SLOT6.slot)
MENU_ACTION_CHANGE_DISC -> { MENU_ACTION_CHANGE_DISC -> {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE) intent.addCategory(Intent.CATEGORY_OPENABLE)
@ -1167,4 +1169,26 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
return !viewBounds.contains(x.roundToInt(), y.roundToInt()) return !viewBounds.contains(x.roundToInt(), y.roundToInt())
} }
} }
fun saveOnExit() {
if (BooleanSetting.MAIN_EXIT_SAVE_AND_LOAD.boolean) {
Log.error("[EmulationActivity] Exitsave on Pause")
NativeLibrary.SaveState(EXITSAVE.slot, true)
}
}
fun loadExitsaveOnStart() {
if (BooleanSetting.MAIN_EXIT_SAVE_AND_LOAD.boolean) {
while (!NativeLibrary.IsRunningAndUnpaused()){
Thread.sleep(10)
}
Log.error("[EmulationActivity] Load Exitsave on start")
val creationTime = NativeLibrary.GetUnixTimeOfStateSlot(EXITSAVE.slot)
if (creationTime != 0L) {
NativeLibrary.LoadState(EXITSAVE.slot)
} else {
Log.error("[EmulationActivity] Exitsave-Slot not available")
}
}
}
} }

View file

@ -136,6 +136,12 @@ enum class BooleanSetting(
"EnableSaveStates", "EnableSaveStates",
false false
), ),
MAIN_EXIT_SAVE_AND_LOAD(
Settings.FILE_DOLPHIN,
Settings.SECTION_INI_CORE,
"EnableExitSaveAndLoad",
false
),
MAIN_WII_WIILINK_ENABLE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "EnableWiiLink", false), MAIN_WII_WIILINK_ENABLE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "EnableWiiLink", false),
MAIN_DSP_JIT(Settings.FILE_DOLPHIN, Settings.SECTION_INI_DSP, "EnableJIT", true), MAIN_DSP_JIT(Settings.FILE_DOLPHIN, Settings.SECTION_INI_DSP, "EnableJIT", true),
MAIN_TIME_TRACKING( MAIN_TIME_TRACKING(

View file

@ -291,6 +291,14 @@ class SettingsFragmentPresenter(
R.string.enable_save_states_description R.string.enable_save_states_description
) )
) )
sl.add(
SwitchSetting(
context,
BooleanSetting.MAIN_EXIT_SAVE_AND_LOAD,
R.string.enable_exit_save_and_load,
R.string.enable_exit_save_and_load_description
)
)
} }
private fun addInterfaceSettings(sl: ArrayList<SettingsItem>) { private fun addInterfaceSettings(sl: ArrayList<SettingsItem>) {

View file

@ -111,6 +111,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
Log.debug("[EmulationFragment] Pausing emulation.") Log.debug("[EmulationFragment] Pausing emulation.")
NativeLibrary.PauseEmulation(true) NativeLibrary.PauseEmulation(true)
} }
// create exitsave here too, in case android kills the paused process
emulationActivity?.saveOnExit()
super.onPause() super.onPause()
} }
@ -161,6 +163,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
} }
fun stopEmulation() { fun stopEmulation() {
emulationActivity?.saveOnExit()
Log.debug("[EmulationFragment] Stopping emulation.") Log.debug("[EmulationFragment] Stopping emulation.")
NativeLibrary.StopEmulation() NativeLibrary.StopEmulation()
} }
@ -220,6 +223,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
EmulationActivity.stopIgnoringLaunchRequests() EmulationActivity.stopIgnoringLaunchRequests()
}, "NativeEmulation") }, "NativeEmulation")
emulationThread.start() emulationThread.start()
emulationActivity?.loadExitsaveOnStart()
} else { } else {
if (!EmulationActivity.hasUserPausedEmulation && !NativeLibrary.IsShowingAlertMessage()) { if (!EmulationActivity.hasUserPausedEmulation && !NativeLibrary.IsShowingAlertMessage()) {
Log.debug("[EmulationFragment] Resuming emulation.") Log.debug("[EmulationFragment] Resuming emulation.")

View file

@ -0,0 +1,12 @@
package org.dolphinemu.dolphinemu.model
enum class SAVESLOT(val slot: Int) {
SLOT1(0),
SLOT2(1),
SLOT3(2),
SLOT4(3),
SLOT5(4),
SLOT6(5),
QUICKSAVE(9),
EXITSAVE(10)
}

View file

@ -32,6 +32,7 @@
<string name="wiimote_extensions">Extension</string> <string name="wiimote_extensions">Extension</string>
<string name="input_device">Device</string> <string name="input_device">Device</string>
<string name="input_test">TEST</string>
<string name="input_device_all_devices">Create Mappings for Other Devices</string> <string name="input_device_all_devices">Create Mappings for Other Devices</string>
<string name="input_device_all_devices_description">Detects inputs from all devices, not just the selected device.</string> <string name="input_device_all_devices_description">Detects inputs from all devices, not just the selected device.</string>
<string name="input_profile">Profile</string> <string name="input_profile">Profile</string>
@ -126,6 +127,8 @@
<string name="fallback_region">Fallback Region</string> <string name="fallback_region">Fallback Region</string>
<string name="enable_save_states">Enable Savestates</string> <string name="enable_save_states">Enable Savestates</string>
<string name="enable_save_states_description">WARNING: Savestates may not be compatible with future versions of Dolphin and can make it impossible to create normal saves in some cases. Never use savestates as the only way of saving your progress.</string> <string name="enable_save_states_description">WARNING: Savestates may not be compatible with future versions of Dolphin and can make it impossible to create normal saves in some cases. Never use savestates as the only way of saving your progress.</string>
<string name="enable_exit_save_and_load">Enable Exitsave and Quickload</string>
<string name="enable_exit_save_and_load_description">Pick it right up where you left it! This will save your game every time you exit the game, and loads it back when you start it again.</string>
<string name="analytics">Enable usage statistics reporting</string> <string name="analytics">Enable usage statistics reporting</string>
<string name="analytics_desc">If authorized, Dolphin can collect data on its performance, feature usage, and configuration, as well as data on your system\'s hardware and operating system.\n\nNo private data is ever collected. This data helps us understand how people and emulated games use Dolphin and prioritize our efforts. It also helps us identify rare configurations that are causing bugs, performance and stability issues. This authorization can be revoked at any time through Dolphin\'s settings.</string> <string name="analytics_desc">If authorized, Dolphin can collect data on its performance, feature usage, and configuration, as well as data on your system\'s hardware and operating system.\n\nNo private data is ever collected. This data helps us understand how people and emulated games use Dolphin and prioritize our efforts. It also helps us identify rare configurations that are causing bugs, performance and stability issues. This authorization can be revoked at any time through Dolphin\'s settings.</string>
<string name="analytics_new_id">Generate a New Statistics Identity</string> <string name="analytics_new_id">Generate a New Statistics Identity</string>