Commit Graph
68 Commits
Author SHA1 Message Date
Henrik RydgårdandClaude Opus 5.5 7e4127ae69 Pause menu: Don't close on a state load until the state is in place
Loading a state from the pause menu closed it right away, and the game
ran a few frames from where it was (seen and heard) before the state
was applied. Now savestate operations run while the game is paused under
the menu, and the menu closes once the load (or rewind, or load undo) is
done. Rewind snapshots aren't taken while paused.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 20:42:14 +02:00
Henrik RydgårdandClaude Opus 5.5 3cc61d3f8e SaveState: Report failed writes, and call back on network refusals
- A failed final flush (a full disk) or a failed rename into place was
  reported as "Saved State". A failed load undo rename still pointed load
  undo at the current game, while the file was another game's state.
- Refusing a save or load for being online didn't call the callback,
  unlike every other refusal.
- A rewind dropped after its decode started stayed active, and stopped
  rewind snapshots until the next clear.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 20:18:46 +02:00
Henrik RydgårdandClaude Opus 5.5 a62aa69986 libretro: Use the real SaveStart
libretro declared its own, which no longer matched once SaveStart got a
member, so serializing read an uninitialized byte. It's in SaveState.h
now.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 20:18:46 +02:00
Henrik RydgårdandClaude Opus 5.5 86e420b9ce EmuScreen: Show the loading spinner while a savestate saves or loads
The boot spinner, in the same corner without the background, while a
save, load or rewind is queued or in progress. Only after a quarter of a
second, so it doesn't flash up on every quick save; on desktop that's
rarely reached, but slow devices get some feedback.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 18:51:10 +02:00
Henrik RydgårdandClaude Opus 5.5 821fd301e6 SaveState: Compress and write savestates on a worker thread
Saving and loading stalled the emu thread for 30-75 ms, long enough to
glitch audio. Now only the snapshot and the apply run there; compression
and file I/O run on a savestate worker thread, in order.

- Save: snapshot in Process(), then compress, write and (for a slot) move
  the old state to its undo name on the worker. The callback runs once the
  file is written. Saving again to a path with a save pending is a repeat
  key press, and gets that save's result without a message.
- Load: read and decompress on the worker while the game runs, then apply.
  A slot load keeps the state it replaces for load undo at that point,
  rather than saving it in full before starting.
- Rewind: compression and decoding are worker jobs, and the deltas get
  zstd level 1 on top, which makes them about a third of the size.
- At most two save snapshots are in memory at once, and buffers are freed
  when their operation is done.
- Shutdown waits for pending writes, and drops callbacks as before.

On desktop, a save now costs the emu thread 2-3 ms, a load or rewind
12-15 ms.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 18:43:27 +02:00
Henrik RydgårdandClaude Opus 5.5 e3916c0acc SaveState: Fix rewind ring and savestate slot bugs
Rewind:
- first_ never wrapped, so after about 40 snapshots rewinding past the
  oldest state jumped back to the newest ones. Track a count instead.
- States whose base had been replaced stayed in the ring, and each one
  failed a rewind with an empty error. Drop them when the base goes.
- Rewinding after pausing for longer than the snapshot interval restored a
  snapshot taken just before the rewind ran.
- Rewind snapshots (and verification) counted as saves for IsStale().

Slots:
- Loading an empty slot replaced the load undo backup before failing.
- A refused save (hardcore mode) rotated the slot's screenshots first.
- Refused or dropped operations never called their callback, so auto-load
  didn't notice it had failed.
- The slot listing went stale after a save until something rescanned.

Also: Verify always failed (its write pass never set the buffer start),
and corrupt or truncated files were reported as being from an older
version.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 17:29:01 +02:00
Henrik RydgårdandClaude Opus 5.5 681a60b3ca Debugger: Fail game.state.load/save when the savestate is refused
SaveState::Load and Save silently drop the operation when the network or
achievements hardcore mode forbids it, but the debugger still answered as if
it had been queued. Return whether it was, and check the boot state in the
same CPU-thread call.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 10:07:30 +02:00
Henrik RydgårdandClaude Opus 5 6600d1c05f Savestate browser: delete the screenshot and name file along with the state
Deleting a savestate from the savedata screen goes through GameInfo::Delete,
not SaveState::DeleteSlot, and it only knew about the .jpg - so the slot's
.name.txt was left behind with nothing to belong to.

Rather than teach the UI the naming scheme a third time, SaveState now answers
what sits beside a state.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 13:58:20 -06:00
lain 78a00399ab Allow to define and modify custom names for saved states 2026-09-12 13:58:20 -06:00
Henrik Rydgård 231aefe476 Code cleanup for save state notification, add metadata field 2026-05-19 11:07:07 +02:00
Henrik Rydgård 386fc442a6 Rework the internal screenshot API, fix bug causing screenshotting to get stuck 2026-02-13 12:34:26 +01:00
Henrik Rydgård 1599ea7b1d SaveState: Separate screenshot operations from other ops 2026-02-08 16:11:44 +01:00
Henrik Rydgård 884d3c46d5 Rework listing of savestates - a single scan operation instead of lots of File::Exists and ModTime calls.
Needed to improve scalability on Android for when we increase the number
of states.
2026-01-09 11:17:21 +01:00
Henrik Rydgård 2959ad214c Fix the internal savestate API to better reflect how it actually works 2026-01-09 10:29:37 +01:00
Henrik Rydgård e6e82c9ad3 Add java-side prefix filtering for ContentUri directory listing 2026-01-09 10:12:15 +01:00
Henrik Rydgård e33ff46ffd Extract the rewind code from SaveState.cpp, to make it more managable. 2026-01-08 22:22:46 +01:00
Henrik Rydgård 77b9a6e2e8 Prepare for adjustable save state slot count by making the Win32 menu dynamic 2026-01-08 16:07:48 +01:00
Henrik Rydgård 038f1a139e Implement save state deletion in the save state popup screen
Fixes #16223
2025-08-15 15:49:03 +02:00
Henrik Rydgård 9a86101769 Avoid getting stuck in a load-loop when auto-loading a bad savestate. Make some code clearer. 2025-05-16 01:55:18 +02:00
Henrik Rydgård a698486f9c Savestate: The callback is already an std::function, so no cbUserdata value is needed. 2025-05-16 01:55:15 +02:00
Henrik Rydgård 9bee4192ba Implement exit confirmation when closing the window on Windows. 2025-02-17 13:09:11 -06:00
Henrik Rydgård 408d1b0916 Track execution time after save, add new setting for exit confirmation 2025-02-17 12:29:23 -06:00
Henrik Rydgård b43abd2015 Fix issues with savestates and non-buffered rendering 2024-10-17 21:09:04 +02:00
Henrik Rydgård c5791764d8 Make the i18n T function use std::string_view
Buildfixes, crashfixes

One more

Android buildfix

Buildfix Qt
2024-02-12 18:44:39 +01:00
Henrik Rydgård e3177ac870 Make some global string pointers const, not just the strings.
Minor cleanup.
2023-12-29 14:09:45 +01:00
Unknown W. Brackets cec9dbbdf7 Build: Add some missing include guards. 2023-09-07 17:14:58 -07:00
Nicolas Adenis-Lamarre f32b0dc9c3 previous slot shortcut
Signed-off-by: Nicolas Adenis-Lamarre <nicolas.adenis.lamarre@gmail.com>
2023-05-25 11:32:49 +00:00
Henrik Rydgård 229e18420a Merge pull request #14434 from unknownbrackets/savestate
SaveState: Show a warning when loading if saved after savestate
2021-08-07 17:23:26 +02:00
iota97 b643d60f72 Undo last save 2021-08-07 13:28:43 +02:00
Unknown W. Brackets eba67d5fcd SaveState: Show a warning if saved after savestate.
If you load a save state from before you created savedata (or from a
different path of savedata), some games will refuse to save.  This shows a
warning since it can be a confusing situation.

We could potentially add an undo for loading state, to give an option for
getting back after this warning.
2021-08-07 00:01:20 -07:00
iota97 157bbb99ae Address feedback 2021-08-05 09:16:10 +02:00
iota97 626dfb5bd7 Savestate load undo 2021-08-03 11:10:54 +02:00
Unknown W. Brackets b74ecd5fa0 SaveState: Use Path instead of strings. 2021-05-14 23:00:22 -07:00
Henrik Rydgård 025bcb1673 Introduce Path, start using it all over the place.
Still lots left to convert!

Convert GetSysDirectory to return Path.

More buildfixing

Remove unnecessary Path( constructors
2021-05-13 10:39:16 +02:00
Unknown W. Brackets 8c655750fe SaveState: Delay restart handling until end frame.
Otherwise, we end up having unmatched pushbuffer map/unmap.
2021-02-21 08:18:13 -08:00
Unknown W. Brackets b8342fb8ec SaveState: Rename ChunkFile files to Serialize.
Makes more sense and less weird than ChunkFileDoMap, etc.
2020-08-10 08:04:05 +00:00
Henrik Rydgård bf4db22165 SaveState: On section version failure, log out the name of the bad section.
Also some other minor improvements to logging and comments.
2020-08-02 17:11:09 +02:00
Henrik Rydgård 5e7a837ff9 Display the savestate slot number when saving and loading state through shortcuts. 2020-05-16 15:20:22 +02:00
hissingshark 7fd7afeba9 Added "oldest save" and "slots 1-5" as options for "auto load savestate" 2018-06-25 21:45:51 +01:00
Unknown W. Brackets a5efb85ab7 SaveState: Show warning on old / long use state.
Using save states instead of in game saves causes bugs in games, and
preserves bugs from bad settings and old PPSSPP versions.

This tells users when they might be affected.
2018-06-14 18:29:55 -07:00
Unknown W. Brackets 2ee8dd7752 SaveState: Keep an undo for each slot by default. 2018-03-17 23:18:25 -07:00
Florent Castelli e0ff68b3f6 c++11: Remove compat header base/functional.h
We want a proper C++11, not tr1. We don't target those compilers anyway.
2016-10-12 11:32:45 +02:00
Unknown W. Brackets 5faa65d9a9 Compress rewind snapshots off thread.
This can take a chunk of time, and doesn't need to finish until next frame
anyway, so we have plenty of time to do it.
2016-09-24 10:37:30 -07:00
Unknown W. Brackets 27d135d48a Decouple save states from UI.
It's the UI's job to decide how and what things are displayed, not Core's.
This also reduces reasons for linkage issues.
2016-05-27 21:25:05 -07:00
Unknown W. Brackets ef566a3adf SaveState: Clean up some constant usage. 2016-02-28 18:21:57 -08:00
Unknown W. Brackets 9ff8d719de Add function to determine ppst title. 2016-01-23 13:06:30 -08:00
Unknown W. Brackets 6a5096e546 Save the game title in savestates, if available.
So that the UI can show them.  Old savestates still load fine, just don't
have the title.
2016-01-23 12:56:36 -08:00
Henrik Rydgard 8996f58693 Generate save state IDs for homebrew using the elf or directory name where applicable. 2015-09-25 19:27:40 +02:00
Henrik Rydgard 001eda39e0 Add really primitive save preview on "Next Slot". Improve pause screen layout a little. 2015-02-01 18:04:50 +01:00
Henrik Rydgard a125178b0b Add a popup dialog when clicking savestate screenshots 2014-12-31 20:43:29 +01:00