GameManager translated install errors when storing them, and the install
screens then looked the translated text up again as a key. It now stores the
category and key, and translates when asked. The raw ISO install error gets
the existing "Installation failed" string.
Some other errors went around as strings that were then used as keys:
- A missing savestate file now has its own error code, ERROR_FILE_MISSING,
instead of a key in the failure reason.
- The PKG reader's reasons are technical English, so they're now shown
untranslated under the translated "This PKG file isn't a PSP game update".
- The netconf dialog looked up the channel number. Only "Auto" is translated
now, using the WLAN Channel setting's string.
- Adds the missing "Failed to read old directory" for memstick moves.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Saving compressed into a ZSTD_compressBound() buffer, about the size of
the whole state, and loading read the whole compressed file before
decompressing it. Now saving compresses into a buffer that grows with its
output and frees the uncompressed state before writing, and loading
decompresses the file in chunks. The file format doesn't change.
Saving also compresses before opening the file, which truncates it, and
drops the unused snappy path. LoadFile and SaveFile are public, for doing
the file part away from the state itself.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
When the file reads fine but a section doesn't, that's almost always a
state from another version, so say that (LoadStateWrongVersion), with the
version that saved it and the failing section on the second line.
LoadPtr() now returns just the section title, for callers to phrase.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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>
The version comes from the file header and goes in the failure message's
metadata line. A state from another version is the usual reason a load
fails. Headless prints it too.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The size check in retro_serialize measured the state separately before
MeasureAndSavePtr measured it again, a third DoState pass on every save,
which rewind and run-ahead do every frame. MeasureAndSavePtr now takes
the capacity of a caller-provided buffer and fails after its own measure
pass if the state doesn't fit.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
SetError overwrote the first bad section with whichever section a later
error came from, and an error before any section read an uninitialized
curTitle_.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- InitContextFromTrackInfo now rejects files where sampleSize (from
blockAlign) exceeds the buffer size, instead of only clamping later in
DecodeForSas. Keep the DecodeForSas check as defense-in-depth since a
large buffer could still allow a crafted packet to overflow the fixed
assembly buffer.
- CChunkFileReader::Verify now returns ERROR_BROKEN_STATE if bounds
checking fails, so modified savestates are rejected here too.
PointerWrap tracked no end-of-buffer, so DoState() implementations could
read past the end of a crafted or truncated savestate via DoVoid's
unchecked memcpy, and DoVector could resize to an attacker-controlled
size before reading.
- PointerWrap now tracks a read end; DoVoid/ExpectVoid fail (MODE_NOOP)
before reading out of bounds.
- String reads are bounds-checked for the whole string including NUL.
- DoVector rejects sizes that can't fit in the remaining buffer.
- LoadPtr takes the buffer size and sets the read end.
- Capping the decompression buffer allocation in LoadFile.
* Rename LogType to Log
* Explicitly use the Log:: enum when logging. Allows for autocomplete when editing.
* Mac/ARM64 buildfix
* Do the same with the hle result log macros
* Rename the log names to mixed case while at it.
* iOS buildfix
* Qt buildfix attempt, ARM32 buildfix