Commit Graph
16367 Commits
Author SHA1 Message Date
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 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 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 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å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 e9fa393546 Kernel: Match GetModuleIdList and heap allocation to hardware
pspautotests modules/idlist shows that sceKernelGetModuleIdList still
writes a partial entry at the end of the buffer (a size of 6 gives two
entries), which the previous commit had stopped. A NULL buffer or a
negative size returns ILLEGAL_ADDR without writing the count.

sysmem/kernel/heap shows sceKernelAllocHeapMemory returning null for
sizes near 4GB, rather than wrapping. The WithOption variant already
checked this. The plain one now does too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-26 22:05:55 +01:00
Henrik RydgårdandClaude Opus 5.5 22b6fcbf22 Kernel: Fix sysclib strchr/strrchr, TLS pool leak, FPL counter
- sysclib strchr/strrchr searched for the whole string, not the
  character, so they returned 0 for any nonzero c.
- A thread ending with blocks from more than one TLS pool leaked every
  other block, since the restarted loop's ++iter skipped an entry.
- FPL's nextBlock grew by up to numBlocks per allocation and eventually
  overflowed into a negative block index. Old states with a negative one
  now reset it rather than failing to load.
- sysclib strncpy bounded its copy by the source's valid size only, not
  the destination's.
- sceKernelAllocHeapMemory wrapped for sizes near 4GB, and
  sceKernelGetModuleIdList could write a partial entry past the buffer
  size and dereferenced a missing module.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-26 21:42:06 +01:00
Henrik RydgårdandClaude Opus 5.5 210be3b311 Savestate: Keep MipsCall actions of type 0
Action type IDs start at 0, and the first one registered is
ActionAfterMipsCall, but MipsCall::DoState used 0 to mean no action.
So every call made with __KernelCallAddress lost its action chain on
load: the thread's wait state was never restored when the call
returned, and chained actions never ran.

Version 2 of the section marks a missing action with -1.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-26 20:13:59 +01:00
Henrik Rydgård 85f9d8985b Merge pull request #22797 from hrydgard/ui-naming-translations
Translation sweep: missing strings, wrong categories, and a langtool scanner
2026-10-26 17:54:26 +01:00
Henrik RydgårdandClaude Opus 5.5 1b60f76e58 Translate error messages once, from keys the source names
GameManager translated install errors when storing them, and the install
screens then looked the translated text up again as a key. It now stores the
category and key, and translates when asked. The raw ISO install error gets
the existing "Installation failed" string.

Some other errors went around as strings that were then used as keys:
- A missing savestate file now has its own error code, ERROR_FILE_MISSING,
  instead of a key in the failure reason.
- The PKG reader's reasons are technical English, so they're now shown
  untranslated under the translated "This PKG file isn't a PSP game update".
- The netconf dialog looked up the channel number. Only "Auto" is translated
  now, using the WLAN Channel setting's string.
- Adds the missing "Failed to read old directory" for memstick moves.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-26 17:04:20 +01:00
Henrik RydgårdandClaude Opus 5.5 097f5e7023 Lang: Fix the wording of some UI strings
The MIPSTracer page's "log file" is the trace file, and some strings had odd
spacing, grammar or capitalization. The auto load savestate toast now uses the
setting's key instead of a duplicate one, and the English fallbacks in code
match en_US.ini.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-26 16:41:12 +01:00
Henrik RydgårdandClaude Opus 5.5 a2170728f5 UI: Look up strings in the sections where they're translated
These were looked up in a different section from the one with the translation,
so they always showed in English (the savedata error messages, "Done!" after
moving the memstick, "Switch UMD", "Ask for network permission" and others).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-26 16:20:03 +01:00
Henrik RydgårdandClaude Opus 5.5 c1f9f77a9e Fix Core.vcxproj.filters, broken by the POPS boot commit
0b1e1a9bb3 put the PopsMMIO entries inside the MeMMIO ones, leaving
unclosed tags, so Visual Studio couldn't load the filters. Also adds
the missing Util\KL4E.h.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-26 15:11:29 +01:00
Henrik Rydgård 17a61343d1 Merge pull request #22792 from hrydgard/more-ui-fixes
Settings: General tab, pause screen save state refresh, UI polish
2026-10-26 12:59:33 +01:00
Henrik Rydgård fe76beb04e Merge pull request #22789 from LunaMoo/xmb-home-exit
Xmb home exit
2026-10-26 12:59:17 +01:00
Henrik Rydgård e443e84d3c sceHprm: Write zeroes to the latch buffer in sceHprmPeekLatch too
We don't support the headphone remote buttons, so we just leave
the buffer all zeroes. Previously we didn't write, which could cause
games to register a ghost "track forward" or the other buttons.

Should fix the DJ Max 2 OST track-forwarding problem in #7468.
2026-10-26 12:46:31 +01:00
Henrik Rydgård 4cb7ddb50c More misc UI polish 2026-10-26 12:10:10 +01:00
Henrik RydgårdandClaude Opus 5.5 0ce79d4d7a Pause screen: Update the save state slots when a save finishes writing
Saves are written on a worker thread, so a state saved just before opening the pause
menu may not be on disk yet when the slots are listed, and the slot stayed empty.
Post SAVESTATE_SLOT_SAVED when a slot save is written, and recreate the pause
screen's views on it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-26 11:49:44 +01:00
LunaMooandClaude Opus 5.5 90cea302b9 HOME button quit screen, with the firmware's art when available
As on a PSP: pressing HOME in a game shows "Do you want to quit the game?"
over it. The game keeps running but gets no input while it's up (sceCtrl
samples are blanked). Left/right picks Yes or No, the confirm button (our
Confirmation button setting, or what compat forces) chooses, the other face
button or HOME closes it, and Yes/No can be tapped. The volume keys change
the game volume a step at a time, shown on the volume bar.

Yes runs the game's registered exit callback first, like the PSP does,
showing "Please wait..." meanwhile. Then, if the XMB launched the game, the
XMB is booted again; otherwise it's back to the game browser, like Exit to
menu. If the callback hasn't ended the game in 10 s, it's quit anyway. Not
in the XMB itself, the PS1 emulator (its own HOME menu) or GE dumps.

It lives in UI/ImposeHome.cpp; EmuScreen only feeds it input and frames and
draws it over the PSP display.

With a firmware dump installed, it's drawn with the firmware's own art from
flash0:/kd/resource/impose.rsc, which is what impose.prx draws it from:
prerendered text for each system language (the question, Yes/No normal and
highlighted, Enter/Back, Please wait...), the button icons, the lines, the
volume bar, the battery and the clock glyphs. The format is documented in
ImposeHome.cpp. Without one, the same screen is drawn with our font and
simple shapes at the same positions.

Where impose.rsc doesn't say where things go, the layout follows
impose_02g.prx (6.61), decrypted and disassembled:
- The screen is filled with 0x9CE7 (#393939); the images are opaque.
- Lines at (80, 96) and (80, 175); impose.prx grows them from the middle
  when it opens, which isn't done here.
- Volume bar: the speaker at (28, 223), 30 steps from x 62, 12 apart. It
  shows our game volume in the PSP's 30 steps.
- Button guide: the cross icon always left, the circle right, "Enter" and
  "Back" next to whichever confirms and cancels.
- Status bar: the battery at (450, 5) (60% and up full, 30% two bars, 12%
  one, then empty), the clock ending next to it at y 5: "M/D H:MM", or
  "D/M" for the DD/MM/YYYY format, no leading zero on the month, day or
  hour, AM/PM for the 12-hour clock.

The clock is the emulated PSP's local time (__RtcGetCurrentLocalTime, new),
in the system's date and time formats. The battery is this device's, since
the emulated PSP's is always full; a device without one shows it full.
For that, Windows now reports -1 for SYSPROP_BATTERY_PERCENTAGE without a
battery (was 100), as SDL already did; SDL polls the battery even when the
status overlay doesn't show it, and the overlay leaves it out when there's
none.

Core side: __CtrlSetGameInputBlocked; __KernelCanExitToVSH and
__KernelRequestExitToVSH to quit to the XMB from outside a syscall; and
__KernelInvokeRegisteredExitCallback(toVSH), so a callback that returns
without exiting ends in the XMB rather than powering down.

New strings: "Do you want to quit the game?", "Please wait..." (Dialog).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NB244iFpvm14JH2FbwHXeQ
2026-10-26 11:39:48 +01:00
Henrik Rydgård 3aec770b22 Set Auto rotation to default, move more settings around. 2026-10-26 11:36:59 +01:00
Henrik Rydgård 29b690eebf Merge pull request #22786 from LunaMoo/umd-inserted-reset
UMD: Put the disc back in the drive on every boot
2026-10-25 23:00:56 +01:00
Claude 66422a6123 UMD: Put the disc back in the drive on every boot
The XMB ejects the disc when it boots without one, and __UmdInit resets
the rest of the UMD state but not UMDInserted. So after visiting the XMB,
any game booted next saw an empty drive and waited forever for its disc
(Brandish: The Dark Revenant stops after registering its UMD callback),
until PPSSPP was restarted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 22:29:54 +01:00
Henrik RydgårdandClaude Opus 5.5 d0e3141f43 FFmpeg: Vendor what PPSSPP uses into ext/ffmpeg, drop the submodule
The ffmpeg submodule held prebuilt libraries for every platform next to the
sources (about 1.5 GB checked out), and nothing uses those any more. Only the
needed sources are copied in, from the submodule's commit, along with every
header and template they include. The path is new, so checking out commits on
either side of this works.

It's also cut down to what PPSSPP uses: the H.264, AAC, MP3, ATRAC3 and ATRAC3+
decoders, the H.264 parser, the demuxers as before, and the FFV1 encoder, AVI
muxer and file protocol for AVI dumping. config.h takes its CONFIG_ values from
FFmpeg 3.0.2's own configure run with just those enabled. The raw H.264 demuxer
stays even though nothing opens raw H.264: probing PSMF data uses it to identify
the video stream's codec, which otherwise comes out as none.

On top of that:
- The files nothing links (configure would build them, but they're never pulled
  out of the static library, going by the GCC link map) are left out: mostly
  libavutil's crypto and hashing and the alternative DCT/IDCT/FFT versions.
- libswresample isn't built, now that nothing uses it.
- The H.264 decoder only does 8-bit video, which is all the PSP has. The SPS
  parser rejects any other bit depth, and the DSP files no longer build their 9-
  to 16-bit variants, which the linker kept because the init functions pick one
  by bit depth at run time.

That's 160 files to compile instead of 277, and 391 of FFmpeg's vendored, about
5.8 MB. The README in ext/ffmpeg has what was done, the PPSSPP patches in the
copy, how to add a component, and the tradeoffs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 22:27:54 +01:00
Henrik RydgårdandClaude Opus 5.5 a8068d1742 AVI dump: Always use FFV1, remove the option to use MPEG-4
The lossy MPEG-4 encoder (with the MPEG-video encoding code it needs) is most
of what FFmpeg's encoders weigh, and lossy footage is better recorded from the
output with a screen recorder. Dumps are now always lossless FFV1, which also
makes for much larger files than the old default.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 22:27:54 +01:00
Henrik RydgårdandClaude Opus 5.5 e031502d27 Audio: Convert FFmpeg's output to s16 ourselves, drop libswresample
FFmpegAudioDecoder only used swresample to turn the decoders' output into
interleaved stereo s16, at the same sample rate. A small conversion does that
now, with swresample's rounding: floats go through lrintf and are clamped, and
mono goes to both channels at -3 dB, the coefficient swresample's mixing matrix
uses. Its output is sample-identical to swresample's for the MP3, AAC and
ATRAC3+ decoders, mono and stereo.

With "Use FFMPEG for all compressed audio", ATRAC3 got closed on its first
frame: its decoder sets no channel layout, and swresample refused to set up
without one. The conversion goes by the channel count, so that no longer fails.

The system-FFmpeg build no longer looks for libswresample.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 22:27:53 +01:00
Henrik RydgårdandClaude Opus 5.5 3015d1f085 Windows: Build FFmpeg from source, in a project of its own
ext/ffmpeg-build/ffmpeg.vcxproj (and UWP/ffmpeg_UWP for UWP) builds the same
sources as CMake, copied from sources.mk by update_vcxproj.py. It's optimized in
Debug too, and without /Zc:inline, since MSVC otherwise keeps references to
disabled components that FFmpeg expects the compiler to drop.

The projects that linked the prebuilt libraries reference it instead, and take
the headers from the source tree.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 22:27:53 +01:00
Henrik RydgårdandClaude Opus 5.5 99727d8fbc FFmpeg: Build it from source with CMake by default, without a configure step
ext/ffmpeg-build now has a committed config.h in place of the configure checks.
Assembly and arch-specific code are off, as in the --disable-asm builds of the
old prebuilt libraries, so only the platform has to be told apart, with a few
preprocessor checks. The sources are listed once in sources.mk, for every build
system to use, and build one static library. ATRAC3 and ATRAC3+ are enabled to
match the prebuilt libraries, and HAVE_AV_CONFIG_H is now defined, as FFmpeg's
own build does.

CMake builds this unless USE_SYSTEM_FFMPEG or FFMPEG_DIR is set, and no longer
looks for the prebuilt libraries in ffmpeg/. MinGW now builds it too, instead
of falling back to the system's.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 22:27:53 +01:00
Henrik Rydgård 3a41fca43d Merge pull request #22782 from hrydgard/play-crash-fixes-2
Fixes for crashes and ANRs from the 1.21-beta1 Play reports
2026-10-25 20:22:21 +01:00
Henrik RydgårdandClaude Opus 5.5 42f9af1744 MemBlockInfo: Clamp marked ranges to the address space
A size that makes addr + size wrap around 32 bits had Split() build a slab
that ends before it starts. Lookups then skipped it, and a later
Merge() ran FillHeads() over it with a huge count, writing far outside
heads_. Sizes come from games through HLE calls, and the large ones are
recorded even without detailed mem info. Seen in a Play crash report, on
the FlushMemInfo thread.

FillHeads() also took the address one past the end of heads_ for a slab
in the last slice, which Debug builds assert on.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 19:37:23 +01:00
Henrik RydgårdandClaude Opus 5.5 6a9b84a714 VSH: Add the 3.6x key for the XMB index
3.60's index.dat carries tag 0x0B2B10F0, which sceResmgr_9DC14891 had no key
for, so the shell couldn't read its item index and stopped on "A serious
error has occurred". The key follows the tag in 3.60's mesg_led_02g.prx, laid
out like the other versions' (3.52's mesg_led.prx has the 3.5x key the same
way). 3.60 now boots to the XMB.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 19:00:55 +01:00
Henrik RydgårdandClaude Opus 5.5 fb371af6bb PSAR: Unpack the 1.00 updater, and the pre-decrypted 3.60 archive
The 1.00 updater's DATA.PSAR is a version 1 archive, the only one there is,
and its blocks carry tag 0x06000000, which the PRX decrypter had no key for.
1.50's mesg_led.prx keeps its keys raw in a table after their tags, the
0x0E000000 one we already use among them, and the 0x06000000 one there
decrypts all of 1.00 (with KIRK code 0x49, following the other tags). Its
first record has no version text either, so the version now comes from the
firmware's own version.txt when that's missing.

Fix a zlib usage bug.

Headless --unpack-updater also exited 0 when every file failed, so now it
fails if any did.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 19:00:48 +01:00
Henrik Rydgård 16103889f4 Merge pull request #22777 from hrydgard/remove-outdated-reporting
Cut down on outdated/useless REPORTing and logging
2026-10-25 18:07:02 +01:00
Henrik Rydgård 1c329a1e44 Merge pull request #22776 from hrydgard/umd-video-interlace
UMD Video: Give a field pair one SEI record per field
2026-10-25 17:36:27 +01:00
Henrik Rydgård 518795e35f Cut down on outdated/useless REPORTing and logging 2026-10-25 17:33:44 +01:00
Henrik RydgårdandClaude Opus 5.5 22348ddbff UMD Video: Give a field pair one SEI record per field
Family Guy and The Dark Knight are coded as separate field pictures,
bottom field first. ffmpeg hands each pair back as one frame, and we
described it with the first field's SEI record only.

The UMD Video player (video_main_plugin.prx) shows such a picture a field
per vsync, and takes the field order from comparing the output times of
the picture's two records. With the second left empty it always chose
top first, so every pair ran backwards in time and the picture jittered
between frames. Now the pair carries both fields' timing, the top field's
record first.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 16:51:24 +01:00
Henrik RydgårdandClaude Opus 5.5 a64d590c94 XMB: Show it in Recents, with an icon and its firmware version as the title
The XMB (vshmain.prx) was kept out of Recents because it had no icon. Now
the game list shows it as "XMB 6.61" (the installed firmware's version, from
its version.txt), with an abstract XMB icon in white on blue, and the window
title says the same instead of "Unidentified PSP title".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 16:15:24 +01:00
Henrik RydgårdandClaude Opus 5.5 b91bd6af86 Settings: Build the settings screen from pages described as data
Each tab is now a SettingsPage: a list of items (headers, settings, buttons,
hints, links to other pages) that a function builds and views are created
from. Settings are added with page->Setting(&g_Config.x), which takes
the label, the kind of view, the range or choices, units, labels for special
values and the default from the config. The pages keep what depends on the
UI (which settings to show and when, enable rules, and behavior that needs the
screen), and reach the screen through the page's SettingsPageHost.

A page can link to other pages, which open on top of it in the same tab,
under a bar showing where you are, like Tools > Developer tools > Graphics,
where the earlier pages can be clicked to go back to them. The bar has back,
search and help buttons, and the back key also goes back a page (or out of a
search) before leaving the screen. Each page remembers its scroll position.
In portrait there's no tab strip: a page links to the tabs, and the bar shows
just the current page's title. Rotating keeps showing the same page. Moving
between pages only focuses an item when navigating with a keyboard or
controller.

The developer tools are now pages linked from the Tools tab, instead of a
screen of their own. The in-game developer menu and
--start-screen=developertools open the settings on that page. The toggles of
live state (the remote debugger and the MIPS tracer) show and change it
through functions, and pretending to be in-game for the notification tests is
a flag on the OSD. The memory map and memstick tests, only reachable from
commented-out code, are removed.

Search lists the matching settings from all tabs and the pages they link to,
grouped by where they are. Each result goes to the setting on its page,
scrolled to and highlighted (outlined, when picked with a mouse or touch), or
for a page, opens it. This replaces the search tab and the old filter that
hid the views that didn't match, and with them ShowSearchControls. Changing
tabs leaves the search.

The pages, the bar and search are in SettingsPagesDialogScreen, between the
tabbed dialog screen and the settings screen, so the other tabbed screens
keep plain tabs.

Other visible changes:
- Reset buttons that went to the wrong value now go to the real default: the
  touch control auto-hide delay (was 20 seconds instead of 8), the mouse
  wheel delay (1 ms, below its own range, instead of 80) and the UI size (0
  instead of -1 on desktop). The alternative speeds get a reset button.
- Units are shown on more sliders (frames, MHz, seconds, Hz), and popups no
  longer spell out what 0 means in the units, since the zero label does.
  Units of up to three characters (%, x, ms, MHz) aren't translated.
- The Android HW scaler hides the scales the display is too small for,
  instead of cutting the list short.
- Choices are translated in the setting's own section.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 15:26:58 +01:00
Henrik RydgårdandClaude Opus 5.5 3bb4664fd6 Config: Describe the settings for the UI, and find them by pointer
ConfigSetting gets a ConfigSettingInfo, set with constexpr chained setters:
a label, choices, a range with step and units, labels for 0 and negative
values (like Unlimited and Disabled), and a callback for what has to happen
when the UI changes the value. Using a setter on the wrong type of setting is
a compile error. The settings in the config tables now have these, so the
settings screen can take them from there instead of repeating them, including
what changing them needs (resize and GPU config messages, fullscreen, audio
and camera notifications and so on). The settings screen starts using them
in a later commit.

Config::FindSetting finds a setting from a pointer to its value. Defaults can
now also be looked up for blocks that reset as a whole (display layouts, touch
and gesture controls), by reading them from a freshly reset copy of the block.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 15:12:24 +01:00
Henrik RydgårdandClaude Opus 5.5 c88850a11a VSH: Alias sceMeBootStart's NIDs for firmware 2.80 to 6.39
The video player only gets the AAC flags it needs when the XMB has booted
the ME in mode 3, and an XMB older than 6.60 asks for that under another
NID, which stayed unresolved: on 6.00, SAMPLE.MP4 said "This video cannot
be played". The NIDs come from matching the function in each version's
me_wrapper.prx. hleKernelNids grows three columns for the generations
before 3.95.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 11:38:51 +01:00
Henrik RydgårdandClaude Opus 5.5 9daf26c01f sceMpegbase: sceMpegBaseCscVme converts two fields, like CscAvc
- Fixes #22764

pspautotests video/mpeg/cscvme shows the two luma buffers are fields, each
with its own chroma, and that the rows land as they do for
sceMpegBaseCscAvc: woven together without a second buffer, packed one per
buffer with one. The XMB's Motion JPEG player passes the second buffer
right after the first with the picture's halves as the fields, which is
why the halves model happened to work for it.

The hardware's colours match the scalar conversion exactly, so CscVme uses
that rather than swscale. Fields packed back to back now reach the GPU as
one write, so a texture over the whole picture isn't cut at the first.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 11:29:16 +01:00
Henrik RydgårdandClaude Opus 5.5 ae7f312d34 sceMpegbase: Add the Vme copy and colour conversion, fix YCrCbCopy's size
The XMB's video player renders Motion JPEG AVIs with sceMpegBaseYCrCbCopyVme
and sceMpegBaseCscVme (JPCSP's names), which take planar YCbCr in two halves
rather than the ME's tiled layout. The copy sizes follow mpegbase_260.prx.

sceMpegBaseYCrCbCopy took the frame size from the destination descriptor,
which the same player leaves unset. mpegbase_260.prx reads it from the
source, in pixels.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 11:29:16 +01:00
Henrik RydgårdandClaude Opus 5.5 fcff5a981c VSH: Play MP4 video from the memory stick
- Fixes #22763

The XMB's video player boots the ME in mode 3 through sceMeCore_driver's
sceMeBootStart (5dff5c50), where games get mode 2. Mode 3 only changes the
argument to ME command 0x185 (me_wrapper.prx), and the player sets the AAC
context flag at 0x2d on anything newer than a PSP-1000 and plays those
files, so sceAudiocodecInit now accepts the 0x2c/0x2d flags in mode 3.
Games still get the failure pspautotests audio/audiocodec/context records.

Also implements the two vaudio calls the player uses: a ChReserveBuffering
that routes each buffer through an ME effect (E8E78DC8), and the setter for
its parameter (504E4745). The effect isn't known, so audio goes out as is.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 11:29:16 +01:00
Henrik Rydgård b970cfece6 Skip the logo when launching the vsh, also add --skip-logo cmdline param 2026-10-25 10:42:12 +01:00
Henrik Rydgård daadd1a15c Change default background animation to wave. 2026-10-25 10:12:32 +01:00
Henrik RydgårdandClaude Opus 5.5 a5c90b61df Android: Use OpenSL ES for audio on TVs, add audio API and MMAP settings
An Android 11 TV played nothing over a Bluetooth headset since the switch
to Oboe, while its speakers worked. Testing on it showed AAudio with MMAP
is silent there and AAudio without MMAP works, as does OpenSL ES (also
when the headset is connected mid-game), whatever the stream usage. MMAP
should never be used for a Bluetooth route, so it's a firmware bug.

Audio settings get an Audio API choice and a Low-latency audio (MMAP)
checkbox, with hints, so other devices with the same kind of bug can be
worked around. The API defaults to OpenSL ES on TVs and before Android
8.1, where the choice isn't offered, and AAudio elsewhere. Changing them
reopens the streams right away. System Information shows the output
stream that got opened (API, MMAP or not, rate, buffers, device) and any
audio error.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 23:58:42 +02:00
Henrik Rydgård c37498808c Home key improved look 2026-10-24 14:14:41 +02:00