Two small fixes that stop the emulator from writing past buffer
boundaries.
RawSPU: when loading a program onto an SPU processor, it now checks that
the program actually fits in 256 KB before copying it. Before this, a
corrupted file could write past the buffer into random host memory.
PPUInterpreter: a one-character typo fix. A modulo operation used % 127
instead of % 128 when computing cross-boundary data sizes. This caused
reservation checks to compare the wrong number of bytes on every load
that crossed a cache line. This fix was pointed out by @AniLeo in the
spam PR #18795 (Discovered by Opus 4.7)
The PS3 hardware enforces these limits:
- Each SPU has exactly 256 KB of memory (from Cell Broadband Engine
Handbook v1.1)
- The PPE cache line is 128 bytes — all reservation logic uses this
granularity
Neither fix should affect the usual games. They only applying to
corrupted or malformed files. Will highly appreciate feedback and
suggestions for this PR
Tested on CI: CI passes on my fork 9 of 10 platforms (Mac Intel failed
downloading a dependency).
Title and Desc written by Codex
- Some SPU programs inexplicably fail to compile when TBL2/TBX2 are used.
- As an insane workaround, first try to compile with TBL2/TBX2, if LLVM crashes while compiling, try to compile the same program without TBL2/TBX2.
- Saves 2 instructions in MPY, 1 instruction in MPYU, 2 instructions in MPYS, 2 instructions in MPYA, 1 instruction in MPYI, and 2 instructions in MPYUI
- Fragment state just reloads some constant buffers.
- Fragment program state recalculates the program.
- This is overkill for a variant reload, but that can be optimized later.
I observed under macOS (although the bug seems platform agnostic to me)
that when restarting a game, then subsequently quitting it, I'd get
stuck in a 'restart loop' where the game would restart upon completely
shutting down, and this would repeat every time I tried to close the
game until I gave up & force quit RPCS3. Seems like for whatever reason,
the use of std::move didn't actually guarantee that after_kill_callback
got nuked if at all, so all I've done is take a hammer to the fucker and
manually set it to nullptr after being called.
Co-authored-by: Elad <18193363+elad335@users.noreply.github.com>
The shuffle in step_track() used std::default_random_engine with a
default (fixed) seed, causing the playlist to be 'shuffled' into the
same deterministic order every time. Use std::random_device to seed the
engine so each shuffle produces a genuinely random order.
Fixes#18672
Users frequently close the game list accidentally and then can't
figure out how to restore it. Remove the DockWidgetClosable feature
so the close button is not shown. The game list visibility can still
be toggled via View > View Game List menu action.
Fixes#18518