Add delete option for save state slots

Add deleteState method to EmulatorCore interface and implement in
Ps1Core and NesCore. Delete button (trash icon) in the in-game
Save/Load menu removes the state file and its screenshot, then
refreshes the slot list.
This commit is contained in:
2026-04-10 19:36:04 -04:00
parent 981ac2eed9
commit 2e41f1e6ea
4 changed files with 38 additions and 0 deletions

View File

@@ -42,6 +42,8 @@ interface EmulatorCore {
fun loadState(slot: Int): Boolean
fun deleteState(slot: Int): Boolean = false
fun getSaveSlotInfo(slot: Int): SaveSlotInfo
fun getScreenshotPath(slot: Int): String? = null

View File

@@ -120,6 +120,14 @@ class NesCore(
return NativeLibretro.nativeLoadState(path)
}
override fun deleteState(slot: Int): Boolean {
val state = File(savesDir, "state_$slot.sav")
val screenshot = File(savesDir, "state_$slot.jpg")
val deleted = state.exists() && state.delete()
if (screenshot.exists()) screenshot.delete()
return deleted
}
override fun getSaveSlotInfo(slot: Int): SaveSlotInfo {
val file = File(savesDir, "state_$slot.sav")
val screenshot = File(savesDir, "state_$slot.jpg")

View File

@@ -140,6 +140,14 @@ class Ps1Core(
return NativeLibretro.nativeLoadState(path)
}
override fun deleteState(slot: Int): Boolean {
val state = File(savesDir, "state_$slot.sav")
val screenshot = File(savesDir, "state_$slot.jpg")
val deleted = state.exists() && state.delete()
if (screenshot.exists()) screenshot.delete()
return deleted
}
override fun getSaveSlotInfo(slot: Int): SaveSlotInfo {
val file = File(savesDir, "state_$slot.sav")
val screenshot = File(savesDir, "state_$slot.jpg")

View File

@@ -27,6 +27,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.AspectRatio
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.Pause
import androidx.compose.material.icons.filled.PlayArrow
@@ -309,6 +310,11 @@ fun GameScreen(
if (!isPaused) c.resume()
showGameMenu = false
},
onDelete = { slot ->
val c = core ?: return@GameMenu
c.deleteState(slot)
saveSlots = c.getAllSaveSlots()
},
onResume = {
if (!isPaused) core?.resume()
showGameMenu = false
@@ -436,6 +442,7 @@ private fun GameMenu(
slots: List<SaveSlotInfo>,
onSave: (slot: Int) -> Unit,
onLoad: (slot: Int) -> Unit,
onDelete: (slot: Int) -> Unit,
onResume: () -> Unit
) {
val dateFormat = remember { SimpleDateFormat("MMM d, yyyy h:mm a", Locale.getDefault()) }
@@ -534,6 +541,19 @@ private fun GameMenu(
) {
Text("Load", style = MaterialTheme.typography.labelMedium)
}
// Delete button
IconButton(
onClick = { onDelete(slot.slot) },
enabled = slot.exists,
modifier = Modifier.size(36.dp)
) {
Icon(
Icons.Default.Delete,
contentDescription = "Delete save",
tint = if (slot.exists) Color.White.copy(alpha = 0.7f) else Color.White.copy(alpha = 0.2f)
)
}
}
}