Commit Graph
48732 Commits
Author SHA1 Message Date
Henrik Rydgård 8d8009840e Merge pull request #22511 from hrydgard/android-inputbox-fixes
Claude code review: Android inputbox fixes
2026-10-12 13:20:25 +02:00
Henrik Rydgård 8c0c848a38 Merge pull request #22518 from hrydgard/input-dropout-fixes
Claude code review: Fix some control input bugs
2026-10-12 13:06:15 +02:00
Henrik Rydgård 8250585092 Merge pull request #22520 from hrydgard/coded-arms-lockon
Coded Arms Contagion: Add readback hock for lock-on, fix other readback issues
2026-10-12 12:45:03 +02:00
Henrik Rydgård 04f5994ea6 Create .nomedia files in the NAND directory when installing firmware
Avoids Android looking for images.
2026-10-12 12:43:36 +02:00
Henrik RydgårdandClaude Opus 5.5 1467ef24a7 GL: Report readback failure, and convert from the format actually read
CopyFramebufferToMemory always returned true, even when glReadPixels
failed, and then copied out whatever the readback buffer held from before.
Depth was labeled D24_S8 while GL reads it as float, and the conversion
ignored the source format, so only a D32F destination came out right.

Record the format and the result of each read, convert from that, and
return it. That also fixes the image readback reusing the aspect of an
earlier framebuffer readback.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 12:15:56 +02:00
Henrik RydgårdandClaude Opus 5.5 f04d99e952 Vulkan: Reject a delayed readback of the backbuffer
The backbuffer is a different image every frame, so there's no earlier copy
of it to return, and the lookup fell through to the sync readback buffer.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 12:15:56 +02:00
Henrik RydgårdandClaude Opus 5.5 4e12f25c70 Readback: Don't write a stale buffer on failure, and clamp the height
Depth readback and the GLES stencil readback converted whatever their
buffer last held into PSP memory when the copy failed. The generic stencil
readback asked for depth, which asserts on Vulkan and D3D11. And
ReadFramebufferToMemory clamped the width to the buffer but not the height,
which a block transfer can exceed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 12:15:56 +02:00
Henrik RydgårdandClaude Opus 5.5 b287b0fab5 GL: Fix the pre-4.5 sub-rectangle texture readback
The repack loop used the texture height instead of the row, and the pack
row length was the rect's right edge while glGetTexImage writes whole rows.
Only reachable from the texture debugger.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 12:15:56 +02:00
Henrik RydgårdandClaude Opus 5.5 d15e094ed6 Vulkan: Key delayed readbacks by position and aspect too
The OLD_DATA_OK readback cache was keyed by framebuffer and size only, so
two equal-size rects of one framebuffer shared a buffer and each read got
whichever was copied last. Add x, y and the aspect to the key.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 12:15:56 +02:00
Henrik RydgårdandClaude Opus 5.5 ae68a7e73f Coded Arms: Contagion: Read back the stencil the crosshair checks
The crosshair turns red, and lock-on works, when stencil bit 3 is set at
the centre of the frame, which the game tests by reading the pixel from
VRAM with the CPU (#17936). Hook that and read back the stencil of that
row into the alpha bytes in RAM. The alpha the hardware backends keep
doesn't follow stencil everywhere, so reading color isn't enough.

Adds PerformReadbackStencilToMemory for this (8888 only for now).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 12:15:56 +02:00
Henrik RydgårdandClaude Opus 5.5 ecad07b3b1 D3D11: Fix readback of a rectangle that doesn't start at the origin
Without the shared 512x512 pack texture, the staging texture was made
bw x bh, but the copy lands at bx, by and the read starts there. Depth and
stencil were worse: CopyResource needs the whole size, so nothing was
copied, and the read ran past the end of the mapping and crashed. Only
whole-buffer reads from 0,0 (like the debugger's) worked.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 12:15:56 +02:00
Henrik Rydgård fb5835e576 Merge pull request #22519 from hrydgard/framedump-display-copy
Framedump recorder: Fix bugs found when investigating things
2026-10-12 11:49:21 +02:00
Henrik Rydgård f79bb0a802 Merge pull request #22517 from eraycep/fix-vulkan-profiler-resize
Vulkan: Preserve active frame profiling queries when stopping threads
2026-10-12 11:48:46 +02:00
Henrik Rydgård 42afcc9fd7 Merge pull request #22516 from hrydgard/savestate-stress
Savestate stress test - results and fixes
2026-10-12 11:22:32 +02:00
Henrik Rydgård fd778f6599 Merge pull request #22515 from hrydgard/ssx-video
SSX On Tour: Recognize the game's memcpy, so its videos show
2026-10-12 10:59:05 +02:00
Henrik RydgårdandClaude Opus 5.5 1f30595b8a Docs: Mention --frame-stats for checking a game after a state load
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:52:46 +02:00
Henrik RydgårdandClaude Opus 5.5 18816b111a Savestate: Put back hooked instructions some old states saved as hook ops
Some old states have replacement hook ops in memory. Since hooks moved out of
memory, those changed the functions' hashes on load, so they weren't hooked
again, and the CPU hit the op as an illegal instruction. Restore the
instructions this session hooked at the same addresses, as the old hooking did.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:52:46 +02:00
Henrik RydgårdandClaude Opus 5.5 9bc239f081 OSK: Skip the old wstring in savestates as bytes
Its characters are as wide as the saving platform's wchar_t, so states saved on
Windows failed the length check on platforms with a 4-byte wchar_t.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:52:46 +02:00
Henrik RydgårdandClaude Opus 5.5 d5db77b736 Sas: End a voice with a bad VAG position on state load instead of failing
States from before 2018 saved idle voices uninitialized, so the position can be
garbage, which made the bounds check reject the whole state (Metal Gear Acid 2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:52:46 +02:00
Henrik RydgårdandClaude Opus 5.5 511275814b Update pspautotests
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:52:46 +02:00
Henrik RydgårdandClaude Opus 5.5 8662d85d70 Headless: add --frame-stats, flips per emulated second after a state load
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:52:46 +02:00
Eray Cepni 4158f114d0 Vulkan: Preserve active frame profiling queries when stopping threads
StopThreads is called inside the
FramebufferManagerCommon::NotifyRenderResized. Issue is, StopThreads is
called inside an active frame, then clears that active frame's timestamp
descriptions. Rendering resumes, and QueueRunner uses the empty list’s
size to select query 0, which was already written.

Fix this by preserving timestamp descriptions for the current frame
when insideFrame_ is true while retaining the cleanup for other frames.
2026-10-12 11:52:03 +03:00
Henrik Rydgård 53047f7cab Merge pull request #22510 from hrydgard/misc-improvements
Misc compat flag updates
2026-10-12 10:25:35 +02:00
Henrik RydgårdandClaude Opus 5.5 b83f2ba7c6 Debugger: Add hle.func.hash, to get a function's hash for ReplaceTables
Returns the analyzed function's start, size and code hash at an address,
and the name of the hardcodedHashes entry already matching it, if any.
Replaces patching a printf into HashFunctions() in the docs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 10:06:16 +02:00
Henrik RydgårdandClaude Opus 5.5 c5ba9bead0 docs: How to find and hash a game function for ReplaceTables
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 09:58:38 +02:00
Henrik RydgårdandClaude Opus 5.5 1f89313034 SSX On Tour: Recognize the game's memcpy, so its videos show
The game converts each video frame into RAM and copies it into the
framebuffer with its own memcpy, which we didn't recognize. The hardware
backends never saw the copy and kept showing the last frame the GE drew.
Same function in the EU (ULES00192) and Korean (ULKS46038) versions.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 09:39:46 +02:00
Henrik Rydgård 4beabce32b Update compat.ini for Echoshift, more IDs for Echochrome 2026-10-12 09:24:46 +02:00
Henrik RydgårdandClaude Opus 5.5 275fc53061 GE dump recording: Record one more frame when the display shows the previous one
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>
2026-10-12 02:04:25 +02:00
Henrik RydgårdandClaude Opus 5.5 c4da98e889 GE dump recording: Read back framebuffers drawn before the recording
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>
2026-10-12 02:04:25 +02:00
Henrik RydgårdandClaude Opus 5.5 7678336e28 Android/VR input: Lock the VR key state, fix device tracking and release
pspKeys and pspAxis were written from the input thread and the render
thread without a lock. Entering VR camera adjust "released" held keys by
sending PSP button codes as keycodes, which released nothing; use
ControlMapper::ReleaseAll instead.

Input devices are now matched by ID. InputDevice objects are replaced after
device changes, so reference comparison registered the same device again.
Removing a device now releases what it was holding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 01:56:32 +02:00
Henrik RydgårdandClaude Opus 5.5 3f1b40b54d Windows HID input: Fix stuck keys on disconnect, don't treat odd reports as disconnects
ReleaseAllKeys released on the XInput device IDs while input arrives on PAD
IDs, so whatever was held at a disconnect stayed held. Short reads and
report types we don't parse made the pad "disconnect" for several seconds,
and a simple DualSense BT report zeroed the state (pressing DPAD up, since
hat 0 is up). These now keep the previous state.

With HID input turned off we no longer open and block reading the device on
the shared input thread.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 01:56:32 +02:00
Henrik Rydgård 12f2ac3370 Merge pull request #22513 from Felipefpl/master
Updated brazilian portuguese translation
2026-10-12 01:13:22 +02:00
Felipe bfca12edac Updated brazilian portuguese translation
Updated/fixed strings.
2026-10-11 19:44:03 -03:00
Henrik Rydgård 0ee8b5adf8 Merge pull request #22509 from hrydgard/buzz-video
Upload video frames written partway into a framebuffer. Fixes Buzz Master Quiz videos
2026-10-11 23:21:39 +02:00
Henrik RydgårdandClaude Opus 5.5 75865683bb Upload video frames written partway into a framebuffer
Buzz! Master Quiz converts its question videos (sceMpegBaseCscAvcRange)
straight into the middle of the frame it has drawn, at 84,69. The
framebuffer upload only matched writes starting at a framebuffer's
address, so the hardware backends never showed the video. Pass the
written width along and draw just that rectangle into the framebuffer.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 22:50:57 +02:00
Henrik Rydgård b21ba7b3b3 Enable accurate vmmul for two games that have had math precision problems before
- #11179 - Warriors Orochi 1/2
- #9843 - Tomb Raider Anniversary
2026-10-11 22:13:57 +02:00
Henrik Rydgård 38528d4790 Remove obsolete JitInvalidationHack
See #22494
2026-10-11 22:06:06 +02:00
Henrik RydgårdandClaude Opus 5.5 0d032fa2ee Windows: Implement System_ShareFile as a Save As dialog
Win32 has no share sheet hookup yet, so sharing a file offers to save a
copy of it. ShareFilesAsZip no longer needs an app cache directory, which
Windows doesn't set; it falls back to the memstick cache folder through
DIRECTORY_APP_CACHE. The save dialog now asks before overwriting.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 21:52:38 +02:00
Henrik RydgårdandClaude Opus 5.5 78f389bd80 Close the file used to detect a background image's format
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:37:20 +02:00
Henrik RydgårdandClaude Opus 5.5 468b83a738 Android: Fix JNI string encoding, thread safety, password in debug log
GetJavaString() returned Java's modified UTF-8, so input like emoji
reached C++ as invalid UTF-8. Commands to Java now get converted the other
way. Request IDs are made on several threads, and the permissions map was
written on the Java UI thread and read on the render thread. The frame
command debug log no longer prints params, which could hold a password.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:37:19 +02:00
Henrik RydgårdandClaude Opus 5.5 2aa3e8d6d3 Android: Always answer native requests
An input box whose show() threw, a second input box open at onDestroy, and
browse commands dropped for a destroyed activity or failing in
processCommand were never answered, leaving the native side waiting (a
game's OSK forever). The image proxy also crashed the app on a picker
result without a URI, a SecurityException or an OOM.

Input boxes now answer exactly once, instead of a success followed by an
ignored failure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:37:19 +02:00
Henrik RydgårdandClaude Opus 5.5 6071983094 Android: Mask password input boxes, don't log entered text
The passwordMasking flag of System_InputBoxGetString() never reached Java,
and both sides logged the entered text, including RetroAchievements passwords.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:29:47 +02:00
Henrik RydgårdandClaude Opus 5.5 e2cda3d8f0 UI: Forget the views' pending requests when recreating them
WipeRequesterToken() only reset the screen's token, after CreateViews() had
already handed it to the new views, so nothing was ever forgotten - not even
in ~Screen(), which saw a token of -1. A text input dialog open across a
RecreateViews() (on the RetroAchievements screen, a slow login failing) would
then write through a deleted PopupTextInputChoice, possibly into the field
that took its place: #21708.

Requests made while creating views now get their own token, forgotten
before the views are deleted. Screen-level requests keep the screen's token.

RequestManager: ForgetRequestsWithToken() now locks, and also drops
responses that arrived but weren't processed yet. ProcessRequests() calls
the callbacks one at a time without holding the lock, so a callback that
closes a screen drops the rest of that screen's responses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:29:47 +02:00
Henrik Rydgård c55fff6b7d Merge pull request #22507 from hrydgard/loadmodule-deferred
sceKernelLoadModule: Put the module in memory when the wait ends (fixes SOCOM FTB2 EU)
2026-10-11 20:31:34 +02:00
Henrik Rydgård 4e2d3ab8d0 Merge remote-tracking branch 'origin/master' into loadmodule-deferred 2026-10-11 20:00:41 +02:00
Henrik Rydgård 5a3393c0a4 Merge pull request #22508 from hrydgard/savedata-no-memstick
Savedata, sceIo: Behave like hardware with the memory stick removed
2026-10-11 19:59:21 +02:00
Henrik RydgårdandClaude Opus 5.5 2f21ca6837 Savedata, sceIo: Behave like hardware with the memory stick removed
With "Memory Stick inserted" off, the savedata modes that show no dialog now
fail with their own "no memory stick" error, as recorded on a PSP with the
stick pulled out (pspautotests utility/savedata/nomemstick). ms0: opens, stats
and directory opens fail with SCE_KERNEL_ERROR_NODEV.

SOCOM: Fireteam Bravo 2's boot-time AUTOLOAD loaded its save anyway, or said
there was no data rather than no memory stick.

test.py gets a test_flags table for tests that need their own headless flags;
this one runs with --no-memstick.

Fixes #21846

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 19:30:39 +02:00
Henrik RydgårdandClaude Opus 5.5 0583bdf335 CmdLine: Fix inverse booleans, add --no-memstick
An inverse boolean option was inverted twice, so --windowed forced fullscreen
on. --no-memstick runs with the memory stick removed, for testing that from
headless (which otherwise always inserts one).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 19:30:38 +02:00
Henrik RydgårdandClaude Opus 5.5 4fda53a62e sceKernelLoadModule: Put the module in memory when the wait ends
We copied the module into memory at the start of the call, then made the caller
wait for the read. On hardware the module's bytes only arrive at the end, and
until then other threads can use that memory (pspautotests modules/loadrace).

SOCOM: Fireteam Bravo 2 EU (UCES00543) relies on this. Its loader EBOOT loads
SOCOMPSP.PRX on one thread while another builds a GU display list in a 0x40-byte
buffer at the end of its .bss. That list overruns into the free memory right after
it, which is where the game module goes. On hardware the module load later
overwrites the overrun; for us, the overrun overwrote the module's first
instructions, and the game crashed as soon as it started.

The load now runs from a CoreTiming event at the end of the wait. Pending loads
are saved in savestates.

Fixes #18842

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 19:08:11 +02:00
Henrik Rydgård 0ce2330b97 Merge pull request #22505 from hrydgard/fix-savestate-zip-install
Fix installing save state zips with certain structures
2026-10-11 18:58:41 +02:00