A replay looks compat.ini up by the ID in the dump's header, so PS1 games'
dumps now get the PS1 emulator's settings when replayed with them
(--dump-compat). The file name keeps the game's own ID.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Which list slot and id the next sceGeListEnQueue gets wasn't saved, so
after a load it depended on the session before it, and replays and
rewinds diverged. Older states start it at 0, and also get the default
EDRAM translation and visible matrices they don't carry, rather than the
previous session's.
- A frame dump recording during a load replayed the loaded state's
commands on the registers from before it. It now starts over from the
loaded state.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Silent Hill: Origins shows each frame one late: the first draw of a frame
copies the previous one into its 565 display buffer. A dump of one frame
then displays a copy of the frame before it, taken from memory, and none
of what it draws. When the display buffer's last write came before most of
the frame's drawing, the recorder now records the next frame too, whose
copy puts the recorded frame on the display.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With a hardware renderer, a framebuffer only exists on the GPU, so a dump
copied whatever stale data RAM held when a game sampled a buffer it drew
in an earlier frame. Silent Hill: Origins shows the previous frame by
copying it into its 565 display buffer at the start of the next one, so
its dumps displayed old scratch data. The recorder now reads such buffers
back once before copying them out (not ones drawn during the recording,
which replay draws again).
It asks for the copy without creating a framebuffer: with
BlockTransferAllowCreateFB (which Silent Hill has) a plain readback makes
a new framebuffer at the destination and never writes RAM.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both DirtyVRAM and GetTargetFlags counted blocks from the size alone, so a
range starting partway into a block missed its last block: a write there didn't
mark it dirty, and a snapshot didn't check it. And GetTargetFlags marked the
partly covered last block clean, since its `i < blocks` was always true. Either
way a later snapshot could be flagged unchanged while the dump didn't have the
data. Memcpy and memset also marked partly covered blocks clean.
Checked against the recorder's own copy of what the dump delivered: recording
from savestates, 4511 of Cars Race-O-Rama's unchanged snapshots and 103 of MX
vs ATV Reflex's didn't match VRAM (small textures at unaligned addresses), and
none do now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blobs were appended back to back, so anything after an odd-sized one (vertex
data, often) started misaligned, and the PSP replayer crashed reading such a
register block as words (Burnout Dominator). Pad every append to 4 bytes.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
RecordNextFrame now refuses while a recording is active and during frame
dump playback (which asserted on the next replay). The callback handoff to
the CPU thread is locked, and a failed file open no longer crashes.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* 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
If it's less than 256 bytes, we can't mark the entire VRAM area copied.
This still helps frame dumps avoid excessively slow VRAM recopying
situations, but fixes issues like missing trees in #12738.
See #15251, the framedump here reused a VRAM texture for many draws, and
this caused it to recopy the texture over and over again. Use a flag to
skip if possible.