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 b743328920..47d92815bf 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 @@ -2,7 +2,6 @@ package org.dolphinemu.dolphinemu.activities -import android.annotation.SuppressLint import android.content.DialogInterface import android.content.Intent 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.SaveLoadStateFragment import org.dolphinemu.dolphinemu.fragments.SaveLoadStateFragment.SaveOrLoad +import org.dolphinemu.dolphinemu.model.SAVESLOT.* import org.dolphinemu.dolphinemu.overlay.InputOverlay import org.dolphinemu.dolphinemu.overlay.InputOverlayPointer 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.DirectoryInitialization import org.dolphinemu.dolphinemu.utils.FileBrowserHelper +import org.dolphinemu.dolphinemu.utils.Log import org.dolphinemu.dolphinemu.utils.ThemeHelper import kotlin.math.roundToInt @@ -456,6 +457,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider { MENU_ACTION_PAUSE_EMULATION -> { hasUserPausedEmulation = true NativeLibrary.PauseEmulation(false) + saveOnExit() } MENU_ACTION_UNPAUSE_EMULATION -> { @@ -464,22 +466,22 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider { } MENU_ACTION_TAKE_SCREENSHOT -> NativeLibrary.SaveScreenShot() - MENU_ACTION_QUICK_SAVE -> NativeLibrary.SaveState(9, false) - MENU_ACTION_QUICK_LOAD -> NativeLibrary.LoadState(9) + MENU_ACTION_QUICK_SAVE -> NativeLibrary.SaveState(QUICKSAVE.slot, false) + MENU_ACTION_QUICK_LOAD -> NativeLibrary.LoadState(QUICKSAVE.slot) MENU_ACTION_SAVE_ROOT -> showSubMenu(SaveOrLoad.SAVE) MENU_ACTION_LOAD_ROOT -> showSubMenu(SaveOrLoad.LOAD) - MENU_ACTION_SAVE_SLOT1 -> NativeLibrary.SaveState(0, false) - MENU_ACTION_SAVE_SLOT2 -> NativeLibrary.SaveState(1, false) - MENU_ACTION_SAVE_SLOT3 -> NativeLibrary.SaveState(2, false) - MENU_ACTION_SAVE_SLOT4 -> NativeLibrary.SaveState(3, false) - MENU_ACTION_SAVE_SLOT5 -> NativeLibrary.SaveState(4, false) - MENU_ACTION_SAVE_SLOT6 -> NativeLibrary.SaveState(5, false) - MENU_ACTION_LOAD_SLOT1 -> NativeLibrary.LoadState(0) - MENU_ACTION_LOAD_SLOT2 -> NativeLibrary.LoadState(1) - MENU_ACTION_LOAD_SLOT3 -> NativeLibrary.LoadState(2) - MENU_ACTION_LOAD_SLOT4 -> NativeLibrary.LoadState(3) - MENU_ACTION_LOAD_SLOT5 -> NativeLibrary.LoadState(4) - MENU_ACTION_LOAD_SLOT6 -> NativeLibrary.LoadState(5) + MENU_ACTION_SAVE_SLOT1 -> NativeLibrary.SaveState(SLOT1.slot, false) + MENU_ACTION_SAVE_SLOT2 -> NativeLibrary.SaveState(SLOT2.slot, false) + MENU_ACTION_SAVE_SLOT3 -> NativeLibrary.SaveState(SLOT3.slot, false) + MENU_ACTION_SAVE_SLOT4 -> NativeLibrary.SaveState(SLOT4.slot, false) + MENU_ACTION_SAVE_SLOT5 -> NativeLibrary.SaveState(SLOT5.slot, false) + MENU_ACTION_SAVE_SLOT6 -> NativeLibrary.SaveState(SLOT6.slot, false) + MENU_ACTION_LOAD_SLOT1 -> NativeLibrary.LoadState(SLOT1.slot) + MENU_ACTION_LOAD_SLOT2 -> NativeLibrary.LoadState(SLOT2.slot) + MENU_ACTION_LOAD_SLOT3 -> NativeLibrary.LoadState(SLOT3.slot) + MENU_ACTION_LOAD_SLOT4 -> NativeLibrary.LoadState(SLOT4.slot) + MENU_ACTION_LOAD_SLOT5 -> NativeLibrary.LoadState(SLOT5.slot) + MENU_ACTION_LOAD_SLOT6 -> NativeLibrary.LoadState(SLOT6.slot) MENU_ACTION_CHANGE_DISC -> { val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) intent.addCategory(Intent.CATEGORY_OPENABLE) @@ -1167,4 +1169,26 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider { 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") + } + } + } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt index 0b6945ff13..1c06929a89 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt @@ -136,6 +136,12 @@ enum class BooleanSetting( "EnableSaveStates", 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_DSP_JIT(Settings.FILE_DOLPHIN, Settings.SECTION_INI_DSP, "EnableJIT", true), MAIN_TIME_TRACKING( diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt index 25acccb2fc..38a188db81 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt @@ -291,6 +291,14 @@ class SettingsFragmentPresenter( 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) { 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 04db24c03a..94c4b5af27 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 @@ -111,6 +111,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { Log.debug("[EmulationFragment] Pausing emulation.") NativeLibrary.PauseEmulation(true) } + // create exitsave here too, in case android kills the paused process + emulationActivity?.saveOnExit() super.onPause() } @@ -161,6 +163,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { } fun stopEmulation() { + emulationActivity?.saveOnExit() Log.debug("[EmulationFragment] Stopping emulation.") NativeLibrary.StopEmulation() } @@ -220,6 +223,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { EmulationActivity.stopIgnoringLaunchRequests() }, "NativeEmulation") emulationThread.start() + emulationActivity?.loadExitsaveOnStart() } else { if (!EmulationActivity.hasUserPausedEmulation && !NativeLibrary.IsShowingAlertMessage()) { Log.debug("[EmulationFragment] Resuming emulation.") diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/SAVESLOT.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/SAVESLOT.kt new file mode 100644 index 0000000000..988a0906e4 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/SAVESLOT.kt @@ -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) +} \ No newline at end of file diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index 51406cd7e3..6005092e23 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -32,6 +32,7 @@ Extension Device + TEST Create Mappings for Other Devices Detects inputs from all devices, not just the selected device. Profile @@ -126,6 +127,8 @@ Fallback Region Enable Savestates 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. + Enable Exitsave and Quickload + 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. Enable usage statistics reporting 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. Generate a New Statistics Identity