- Fixes#13722
Opening the chat with focus left the stick directions and keys held in-game
in the UI's held-key list, so the focus started moving right away. And while
the chat is open, stick movements don't reach the control mapper, so a stick
let go inside the chat stayed pushed for the game after it closed. Clear the
held keys when focus movement turns on, and release the mapper's input on
the next update (OpenChat can run under the mapper's lock).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
On Windows, a key released while Alt is held comes as WM_SYSKEYUP, which
raw input dropped, so after Alt+Up the UI kept the arrow held and the focus
kept moving. Handle it like WM_KEYUP. Alt+arrows also no longer move the
focus, since they're shortcuts.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Headless used ~/.ppsspp, which nothing else uses, while the app uses
~/.config/ppsspp (or $XDG_CONFIG_HOME/ppsspp on Linux). The derivation
is now shared, and the app's default is unchanged. Windows and iOS keep
their own.
test.py and frametests.py pass a memory stick next to the binary, as
Windows headless already defaulted to, so the tests still don't write
into the user's memory stick or see its firmware.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
NativeInit loaded ppsspp.ini from the platform's memory stick and only
then applied the command line, so with --memstick the app still read
its config from the default location and saved it back there (seen on
Mac, with ~/.config/ppsspp). Set it before the config is loaded.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Smaller framebuffers are mostly effects (blur, bloom), and MSAA changes
how those come out, like a higher resolution would. Syphon Filter:
Logan's Shadow grew a glow around its lit floor panels that the PSP
doesn't have. Effects in Call of Duty: Road to Victory and Assassin's
Creed: Bloodlines shifted too.
A framebuffer that grows to full size gets MSAA from then on. The
temporary buffer that shifts depth for offset rendering now takes the
samples of the framebuffer it shifts, since they can differ.
Over the frame dumps at 2x and 4x, the differences away from edges
compared to no MSAA drop by a fifth and 53 dumps get closer. The one
that moved away, Silent Hill: Origins' flashlight shadow, now matches
the PSP; without MSAA it shows a known replay artifact there.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Fixes#17664
With no symbol for the current function, the scan for a prologue ran on
into the function before it, took that one's entry and stack frame, and
read a bogus ra from the stack, so the walk ended there. Now a jr ra above
the current pc ends the scan: the innermost frame is taken as a leaf
starting right after it, using ra from the register.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Fixes#12082
The bit-exact VFPU dot product is the default everywhere and fast enough,
so the plain multiply-add paths in the interpreter and the IR frontend go,
along with the AccurateVdot setting, --accurate-vdot, the ForceAccurateVdot
compat flag and the Vec4Dot IR op, which nothing emits any more.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ScrollView dropped every mouse event without the left button, so views inside
one never saw hovers or right clicks. This kept nested scroll views from
tracking hover for the mouse wheel, and GameButton's right-click info only
worked once a left click had set its hover flag.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
With touch or the mouse, the video started as soon as you pressed a game,
so watching it without launching the game took a careful drag-and-release.
Touch and mouse users can still see the video from the info button or a
long press.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The PSP's AVC decoder follows the H.264 output process (Annex C),
measured in the new pspautotests video/mp4/avchold on streams that
differ only in their headers, and video/mpeg/decodeend. With HRD
parameters and picture timing SEI, a picture comes out dpb_output_delay
after its access unit; Sony's movies have a one frame delay. Without, it
is bumped out of a buffer three frames deep, whatever the stream
declares. sceMpegAvcDecodeStop hands back what's left, and streams with
more than three reference frames are refused with 0x80628002.
We handed each picture back as soon as it was decoded. MGS Peace
Walker's movie player only checks for the end of a movie while its
clock is short of the movie's length, so its last picture landed right
on that limit and the game hung on a black screen after the cutscene.
ffmpeg still decodes the pixels, in display order; each access unit is
tagged with its index so frames can be matched back, and ffmpeg's H.264
parser supplies the picture timing. A call can now hand back several
pictures, as consecutive 0x2C byte descriptors the way mpeg.prx's
sceMpegAvcDecodeStop reads them, each in a frame buffer slot of its own
(reallocated when a savestate brings a block too small for that).
Not followed: with B-frames and no picture timing, the PSP can complete
several pictures in one call; here they come out one a call. All of
the game movies checked have picture timing.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Loading a savestate kept the current session's netAdhocInited,
netAdhocctlInited and matching-inited flags rather than the saved ones.
Loaded into a fresh boot, a state saved with adhocctl initialized (but not
connected) then failed every adhocctl call with NOT_INITIALIZED. MGS Peace
Walker shuts ad hoc down before a cutscene and retried
sceNetAdhocctlDisconnect forever, leaving the screen black.
Take the flags from the state, and bring the host side in line: start the
friendFinder and log in again when the state has adhocctl up and we don't,
stop it in the opposite case. Also save the product code, which that login
sends.
Also add a game.state.save debugger command, used to reproduce this.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The transposed extents f7ec86c5d5 worked around came from the size race
the previous commit fixed: with the size now applied between frames, the
workaround didn't fire once in 38 rotations on the Galaxy S8+ that hit it
in about one in four.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
backbufferResize comes from the UI thread, and changed g_display while the
render thread was drawing with it. Like iOS, it now leaves the new size for
the render thread to apply before its next frame, or applies it directly if
no render loop is running. A rotation in a resize that's superseded before
it's applied still forces the swapchain recreate.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
joystickAxis copies the axes in batches on the stack instead of allocating
per event, and bounds the count by the arrays it got. queryGameInfo's cache
is a local, in a helper so it's gone before the thread manager is torn down.
Removes Android_GetFreeSpaceByFilePath (never called) with its Java side, and
isLandscape, which only existed to call NativeGetAppInfo early.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Scoped storage no longer flips on while no activity is registered: whether
legacy storage was preserved is fixed per install, so it's asked once.
- Free space reads as unknown (-1), not 0 bytes, without an activity.
- Strings from Java (file listings and info, crash history, the camera list,
the input debug string) go through GetJavaString, so names with characters
outside the BMP aren't mangled, and a null string can't crash the crash
history.
- Requests (inputbox, browse_*) whose command can't be delivered are failed
instead of left waiting forever.
- A font that fails to load uses the default typeface (-1) instead of font 0,
and is retried later if there was no activity yet. Missing exception checks
added in the text renderer.
- Method IDs and the storage callbacks are looked up once in JNI_OnLoad.
- Unknown permissions are logged correctly.
Also removes what was left of Moga support, the unused backbuffer format and
a stray MessageBox macro, and tidies System_GetCameraDeviceList.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The location permissions imply android.hardware.location as required,
on top of the .gps and .network subfeatures we already marked optional.
Also skip the permission prompt on devices without location hardware.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
RECORD_AUDIO implies android.hardware.microphone with required=true
unless declared otherwise, which hides the app from devices without one.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Fixes#17608
Text fields took Ctrl or Cmd for copy/paste/undo; now it's Cmd on Apple
platforms and Ctrl elsewhere, as is Ctrl+F (Cmd+F) for game search. Word
delete in the search filter is Option+Backspace on Apple.
The ImGui debugger never got Super, so with ImGui's Mac Cmd/Ctrl swap,
its paste and other Ctrl shortcuts could not be reached at all on Mac.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The savedata tests printed the utility's results on every poll, so they
failed when PPSSPP's IO thread was caught partway through writing them.
They now print them once the utility reports FINISHED.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The hook on the decode function fixed hit-testing, but the solid color
picking frames could stay visible on screen, more so at high render
resolutions. Reading back at sceGeDrawSync(0), right after the game
waits for the pass, doesn't show them. Only the framebuffer the last
list drew to is read back. Rularia found and tested this at 10x on
ULJS00216.
The new ColorPickingDrawSyncReadback compat flag replaces the
ReplaceTables hook, and ULJS00247 (the third game's UMD) is added
alongside the others.
Co-Authored-By: Rularia <Rularia@outlook.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Fixes#22514
The 3D investigation mode renders an ID picking pass into VRAM and reads
it back on the CPU to build the hit-test table. Hook the decode function
to flush the framebuffers to VRAM first, and force lower resolution for
effects to avoid stutter.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Big games fill 16 MB in normal play. It's now one constant shared by
every backend. ARM32's 32 MB branch range is the limit on going higher
there.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The native code space fills long before the arena did: Tekken 6 has it
30% full with the arena at 3%. The old limit was the 24 bits an emuhack
opcode had for the offset, which the block shadow no longer needs.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Shows the number of blocks, how full the native code space and the IR
arena are, and how many times each filling up cleared the cache.
The "Ran out of block numbers" message was logged for both of those, and
there is no block number limit. It now says which one filled up.
Also hide the GPU profile and allocator overlays by value on backends
that lack them. Cutting the last two off the list had been hiding the
framebuffer list since it was added after them.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
StopWebServer() only stopped a RUNNING server, while ShutdownWebServer()
joined in any state but STOPPED. Shutting down while the server was
still STARTING joined a thread nobody had told to stop, which then
entered its loop and never left. Stop it while STARTING too, and only
switch to RUNNING if no stop came in meanwhile.
Also make the report.ppsspp.org registration cancellable. It runs at
startup and every nine minutes, and couldn't be interrupted, so exiting
during a stalled one waited out its connect and 900s header timeouts.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>