Commit Graph
49924 Commits
Author SHA1 Message Date
Henrik RydgårdandClaude Sonnet 5.5 cbb553ccc7 Build as C++20
Switch CMake (including the Core and GPU compile features and the Android
flag), the Visual Studio projects (stdcpp20), the legacy Android NDK
makefiles, the libretro makefiles and .ycm_extra_conf.py from C++17 to
C++20.

[=] lambdas that use this implicitly become [=, this], to avoid
-Wdeprecated-this-capture.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 00:02:06 +01:00
Henrik RydgårdandClaude Sonnet 5.5 cbdc38f68f Fix volatile ++/-- and anonymous enum arithmetic
Avoids the C++20 deprecation warnings (-Wdeprecated-volatile and
-Wdeprecated-anon-enum-enum-conversion). No behaviour change.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 00:02:06 +01:00
Henrik Rydgård 302e408069 Merge pull request #22817 from hrydgard/play-crash-fixes-3
Fixes for crashes from the 1.20.5 beta Play reports: savedata list count, GL startup race
2026-10-27 23:07:17 +01:00
Henrik Rydgård 8d96fdb6cd Merge pull request #22816 from hrydgard/popup-round-corners
UI: Round corners and a little padding on popups and notifications
2026-10-27 22:36:18 +01:00
Henrik Rydgård 5c84203bbe Merge pull request #22512 from hrydgard/inet-select-wait
sceNetInet: Wait in emulated time instead of blocking the host
2026-10-27 22:17:24 +01:00
Henrik RydgårdandClaude Opus 5.5 ad9c65ae39 EmuThread: Run the graphics context's ThreadStart before starting the emu thread
On OpenGL the render thread's ThreadStart fills in the GL strings and
picks the buffer strategy, while the emu thread, started just before
it, could already be in NativeInitGraphics reading them. A Play report
crashed walking the strings map in BuildReportingInfo. ThreadStart also
resets the exit flags, which could undo an early exit by the emu
thread. Libretro already starts its emu thread in this order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 22:11:09 +01:00
Henrik RydgårdandClaude Opus 5.5 e10ebbeb44 Savedata: Keep the list count at 0 when a name in the list is rejected
The multi-name path counted names straight into saveDataListCount, so
returning on a path traversal name left a count behind with the list
already freed by Clear(). The next savestate then serialized that many
entries from a null list and crashed in Do(std::string). Count on the
side, and don't write entries for a list that isn't there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 22:04:45 +01:00
Henrik Rydgård 0a2568f4ef Round more things. Remove the underline from popup titles, cleaner look 2026-10-27 21:58:32 +01:00
Henrik RydgårdandClaude Opus 5.5 e289b3d895 OSD: Pad the notifications like a NoticeView
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 21:50:20 +01:00
Henrik RydgårdandClaude Opus 5.5 810634c899 OSD: Make the notification corners 75% of a Choice's
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 21:49:06 +01:00
Henrik RydgårdandClaude Opus 5.5 6ea7cf7be2 OSD: Round the corners of on-screen notifications
Half the radius of a Choice. Covers notices, progress bars, the
leaderboard tracker and RetroAchievements popups (not the listed
achievements on the achievement screens).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 21:49:06 +01:00
Henrik RydgårdandClaude Opus 5.5 e67543d604 UI: Pad the inside of popups
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 21:47:06 +01:00
Henrik RydgårdandClaude Opus 5.5 6efdad7cea UI: Round the popup buttons
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 21:47:06 +01:00
Henrik RydgårdandClaude Opus 5.5 916dfab834 UI: Round the corners of popups
FillRoundRect falls back to a square FillRect for drawables it can't
round, and a ViewGroup with round corners set rounds its background.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 21:47:06 +01:00
Henrik Rydgård 476d020c58 Merge pull request #22810 from hrydgard/custom-driver-options
Implement support for setting two common driver flags for Turnip (custom Adreno driver)
2026-10-27 18:03:09 +01:00
Henrik Rydgård 2f5f91f7ae Merge pull request #22815 from hrydgard/adhoc-tests
Ad hoc and inet pspautotests, multi-instance headless, NULL pointer crash fixes
2026-10-27 17:56:12 +01:00
Henrik RydgårdandClaude Opus 5.5 475e548878 Add the net/inet/offline pspautotest to tests_next
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:13:45 +01:00
Henrik RydgårdandClaude Opus 5.5 1d9cccb877 Add the net/adhoc/alerts and net/inet/stats pspautotests to tests_next
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:13:45 +01:00
Henrik RydgårdandClaude Opus 5.5 a4fe8e8f17 sceNetAdhoc: Don't fault on NULL pointers the PSP accepts
sceNetAdhocPdpSend with NULL data and a length of 0, sceNetAdhocPdpRecv
with a NULL sender MAC or port, and sceNetAdhocPtpSend with a NULL length
pointer all raised a memory exception before the call ran, which stopped
the game. On a PSP the first two succeed and the last returns INVALID_ARG
(net/adhoc/pdp and net/adhoc/ptp in pspautotests).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:13:45 +01:00
Henrik RydgårdandClaude Opus 5.5 6056ec419a Headless: Run several instances that talk to each other over ad hoc
--instance=N sets PPSSPP_ID, so each instance gets its own 127.0.0.N address
and MAC; headless left it at 0, which made its address 127.0.0.0.
--realtime keeps emulated time from running ahead of the wall clock. Only
display flips paced headless, and a test that doesn't draw never flips, so
two instances waiting for each other over the network timed out at once.
--adhoc-server runs the built-in ad hoc server.

Tools/adhoc_multi.py runs a multi-console pspautotest (X_host, X_client,
X_client2, ...) on one instance per role, with the built-in server or, with
--relay, a local aemu_postoffice in relay mode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:13:45 +01:00
Henrik RydgårdandClaude Opus 5.5 5629c233e0 Add the new net/inet and net/adhoc/limits pspautotests to tests_next
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:13:45 +01:00
Henrik RydgårdandClaude Opus 5.5 78151eadca Add the net/adhoc discover and loopback pspautotests to tests_next
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:13:45 +01:00
Henrik RydgårdandClaude Opus 5.5 54df259d6e Add the remaining single-console net/adhoc pspautotests to tests_next
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:13:45 +01:00
Henrik RydgårdandClaude Opus 5.5 5fd1afffd8 Add the net/adhoc pspautotests to tests_next
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:13:45 +01:00
Henrik RydgårdandClaude Opus 5.5 bd56e07bb0 sceNetInet: Fix the blocking socket waits on Windows
Headless only started Winsock (net::Init) for the debugger, so on Windows
every socket call failed with WSANOTINITIALISED. Start it always.

Winsock's select() fails on empty sets, where POSIX waits out the timeout, so
a select() used as a sleep (the VSH's Skype) returned an error at once. With
no host sockets to check, select and poll now just report nothing ready.

Look up host sockets without GetHostSocketFromInetSocket, which asserts on a
socket closed while a call waits for it, and whose -1 can't be caught with
< 0 on Windows, where SOCKET is unsigned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:04:09 +01:00
Henrik RydgårdandClaude Opus 5.5 be9383c08f sceNetInetPoll: The timeout is in milliseconds
Like POSIX poll(), as pspautotests net/inet/blocking shows. We took it as
microseconds, so every poll timeout was a thousand times too short.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:03:59 +01:00
Henrik RydgårdandClaude Opus 5.5 22e0a1a536 sceNetInet: Wait for blocking socket calls in emulated time
Host sockets are always non-blocking, so a game's blocking recv(), accept()
and so on came back with EAGAIN at once, and connect() and poll() blocked the
whole emulator in the host call instead. Now recv, recvfrom, send, sendto,
accept, connect, poll and select try once, and if the call would block on a
blocking socket (no SO_NBIO or MSG_DONTWAIT), the thread waits and a
CoreTiming event retries it every millisecond. It ends when the call completes
or fails, or when SO_RCVTIMEO/SO_SNDTIMEO runs out in emulated time.

Sockets accepted on Linux are made non-blocking too: unlike BSD and Windows,
Linux doesn't pass that on from the listening socket. select() rejects a
tv_usec of a second or more with EINVAL.

Hardware behaviour from pspautotests net/inet/blocking.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:03:59 +01:00
Henrik RydgårdandClaude Opus 5.5 4e156e8945 Headless: Act as the only instance
Headless doesn't join the instance counter, so PPSSPP_ID stayed 0 and the
localhost IP derived from it came out as 127.0.0.0, which macOS won't bind.
Every sceNetInetBind failed with EADDRNOTAVAIL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:02:03 +01:00
Henrik RydgårdandClaude Opus 5.5 72a0cd1879 sceNetInetSelect: Wait in emulated time instead of blocking the host
select() ran on the CPU thread with the guest's timeout (5.5 seconds when it
gave none), so the whole emulator stopped for as long as it waited. The VSH's
Skype uses select() with no sockets as a sleep, 0.65-0.95 s at a time, and ran
at a crawl: almost no emulated time passed, and the UI barely moved.

Now the sockets are checked without blocking. If none is ready, the thread
waits and a CoreTiming event polls again every millisecond until one is, or
the timeout runs out in emulated time. A null timeout now waits for as long as
it takes. Pending waits are saved in savestates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:02:03 +01:00
Henrik Rydgård 422887edf8 Merge pull request #22814 from Kethen/adhoc_regression_fix
fix adhocctl regression by restoring wrongly removed logic
2026-10-27 15:47:44 +01:00
Katharine Chui 262416ad90 fix adhocctl regression by restoring wrongly removed logic
- 23efd22efb : Fix Stuck issue on some games (Dissidia 012, Full Auto 2, etc) when Failed to connect to Adhoc Server (faked success)
- 7ec860c24f : Adhoc: Stop waiting for a login that has already failed
2026-10-27 15:02:04 +01:00
Henrik Rydgård 4c49233a39 Merge pull request #22813 from hrydgard/notice-view-style
NoticeView: Round corners like a Choice, pad the contents, fill the width
2026-10-27 14:30:09 +01:00
Henrik RydgårdandClaude Opus 5.5 adf905ce7a NoticeView: Take the padding from the theme's corner radius
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 13:29:01 +01:00
Henrik Rydgård 2ee1a0bea7 Merge pull request #22811 from hrydgard/misc-logic-fixes
Misc logic fixes from a Claude code review
2026-10-27 12:35:59 +01:00
Henrik RydgårdandClaude Opus 5.5 a941ad634d NoticeView: Round corners like a Choice, pad the contents, fill the width
RenderNotice and MeasureNotice take padding (added inside the background)
and the corners to round. The drop shadow moves out of RenderNotice to the
floating OSD notices, since views don't have one. Without layout params, a
NoticeView is FILL_PARENT wide like a Choice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 12:17:31 +01:00
Henrik RydgårdandClaude Opus 5.5 fd17b7725d Add a "firmware" start screen, for testing the firmware screen
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 12:17:31 +01:00
Henrik Rydgård 26ead02a59 Merge pull request #22812 from hrydgard/textdrawer-measure-style
TextDrawer: Measure in a given style without switching fonts
2026-10-27 12:17:10 +01:00
Henrik Rydgård 176f56da8d Implement support for setting two common driver flags for Turnip (custom Adreno driver)
enable_tp_ubwc_flag_hint and storage_8bit are now available as check
boxes on the driver setup screen.

Fixes #22808
2026-10-27 12:16:25 +01:00
Henrik RydgårdandClaude Opus 5.5 4c7dd44351 TextDrawer: Remove the current font and scale
Drawing now takes the style and scale too, like measuring, so the text
drawers have no font state left. UIContext keeps its current style and
passes it, and fills it in from the theme if nothing has set one yet.
PPGe passes its one font.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 11:54:10 +01:00
Henrik RydgårdandClaude Opus 5.5 dc1e9e50fc TextDrawer: Measure in a given style without switching fonts
Measuring took the current font and scale, so UIContext switched to the
style being measured and back. On first draw the font to switch back to
could be an empty one, which the UWP drawer asserts on.

MeasureString and MeasureStringRect now take the style and scale, and the
backends' MeasureStringInternal measures in the style it's given.
SetOrCreateFont, which sets the font drawing uses, is shared, and the
backends only implement EnsureFont, which creates a font if needed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 11:45:04 +01:00
Henrik RydgårdandClaude Opus 5.5 561badca05 sceAudio: Check sceAudioInput's arguments and routing modes like the PSP
pspautotests audio/sceaudio/input and audio/sceaudio/routing.

- sceAudioInput fails until sceAudioInputInit, then checks that the
  sample count is a nonzero multiple of 64 before checking the rate
  (11025, 22050 or 44100 only). A rate of 0 now gets the PSP's error
  instead of the USB mic's. Init takes about 3ms.
- A blocking mic input woke with the byte count rather than the sample
  count that the non-blocking call returns.
- The routing functions are exported by both sceAudio and
  sceAudioRouting, and the latter had its own copy that ignored the
  stored modes. Both now share the one in sceAudio, with the ranges
  checked. SetVolumeMode returns 0, not the previous mode, and both
  modes start at 0.

sceAudio's savestate section goes to version 5 for the input init flag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 10:56:46 +01:00
Henrik RydgårdandClaude Opus 5.5 3880999ada Misc HLE: Fix heap leak, USB waits, RNG indices and small races
- sceHeapDeleteHeap never freed the heap's memory. Allocation failure
  returned -1 rather than a null pointer, and a near-4GB size wrapped.
- The USB wait timeout resumed threads that were no longer waiting on
  USB, and UsbUpdateState resumed them too, and never rescheduled.
- The Mersenne Twister drew from mt_[index_] with the index taken from
  guest memory. It's now taken modulo the state size. sceSfmt19937
  checks its index, and that fill arrays are at least a state long,
  which the library writes regardless of the length it's given.
- sceCccEncodeUTF16's surrogate test also caught U+F800 - U+FFFF, which
  includes the fullwidth forms.
- sceAudioRoutingSetVolumeMode stored the routing mode.
- A sample rate of 0 to sceAudioInput or the camera mic divided by zero,
  and a huge sample count sized a host buffer. sceP3daBridgeCore's sizes
  could wrap. sceRtc's tz offset could overflow tm_min.
- Camera shutdown freed the frame buffer and config without the lock
  the capture thread uses. GPS data is set from the platform's location
  thread, so it's now locked too, and the satellite index is bounded.
- A loop in the sys event handler list hung the unregister.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-27 10:39:45 +01:00
Henrik RydgårdandClaude Opus 5.5 0b30638e65 HLE: Fix SAS thread wakeup, SAS raw output size, ME and syscon bounds
- The SAS thread waited without checking the state first, so a mix
  queued before it got to the wait was missed, and the next drain hung.
  The state is now atomic too.
- SAS raw output mode writes four planes, twice the size it asked for.
- DMACplus colour conversion with a huge stride overflowed its size
  math. The syscon serial data index wasn't bounded on reads, writes or
  load.
- Replace_memcpy_swizzled copies whole 16x8 blocks, more than the
  pitch * h it asked for. The God Eater depth hook tested the color
  buffer twice instead of the depth buffer, and its size could wrap.
- GranularMixer used 1/0 before the first FPS sample, and read the
  granule being written next when the queue was empty.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-27 10:38:32 +01:00
Henrik Rydgård 57161a245e Merge pull request #22803 from hrydgard/more-ui-work
DisplayLayoutScreen layout tweaks, fix sceImpose "HOME" screen issues
2026-10-27 09:53:02 +01:00
Henrik Rydgård 81a7c7e78c Code cleanup, logging improvement 2026-10-27 09:32:52 +01:00
Henrik Rydgård 0142876cef Remove some slop from the sceImpose Home screen (confusing touch input) 2026-10-27 09:23:57 +01:00
Henrik Rydgård 83d73bb88e Merge pull request #22804 from hrydgard/fix-net-logic
Net Claude code review: Fix use-after-pop, the resolver after loads, inet sockaddr/poll
2026-10-27 09:15:05 +01:00
Henrik Rydgård ebf0d99d36 Merge pull request #22809 from hrydgard/translations-fill-in
Fill in untranslated UI strings in 40 languages, fix wrong-language strings
2026-10-27 09:13:11 +01:00
Henrik RydgårdandClaude Opus 5.5 455209b43e Net: Fix use-after-pop, the resolver after loads, inet sockaddr/poll
- The apctl, NpAuth and NpMatching2 event loops kept references to the
  front of their deque after popping it, so callbacks could get the
  next event's arguments. NpMatching2 also dereferenced its optional
  opt param when it was null.
- The resolver was left stopped after any savestate load or reboot,
  which broke Outrun 2006 (it relies on it starting out running).
- Getpeername/Getsockname with a namelen under 2 copied a negative size.
  They now write the PSP's 16-byte sockaddr truncated to namelen, with
  sa_len 16, as pspautotests net/inet/poll shows on hardware.
- Poll handed an fd that isn't open (-1) to FD_SET. It now reports
  POLLNVAL for it and counts it, as on hardware (net/inet/poll).
  Setsockopt read past a local u32 for larger options, and passed a
  negative optlen to the host. A zero cmsg_len looped forever.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 08:43:28 +01:00
Henrik RydgårdandClaude Opus 5.5 1b20f4685e Lang: Give the MMPX and xBRZ texture shaders their real names
en_US had the raw section names ("TexMMPX"), which also shadowed the shader's
own Name= fallback, so the UI showed those. Now they match the Spline36/NNEDI3
entries, in every language.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 08:36:15 +01:00