Commit Graph
6591 Commits
Author SHA1 Message Date
Henrik RydgårdandClaude Opus 5.5 bab3a4e181 TabbedDialog: Move the settings search into the base screen
Any tabbed screen can now add tabs described by a SettingsPage with
AddSettingsTab, and gets the search tab that shows matching settings with
arrows to jump to them. The game settings screen is the first to use it.
Screens without settings tabs keep the old filter for now.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 14:54:39 +02:00
Henrik RydgårdandClaude Opus 5.5 cae048f74a ShaderList: Don't show a search tab
Its tabs are lists of shaders, not settings, so the filter was of no use.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 14:52:25 +02:00
Henrik RydgårdandClaude Opus 5.5 54e4b3a1c4 Settings: Show matching settings directly in the search tab
Instead of hiding the non-matching views in every tab and disabling the tabs
without matches, the search tab now builds each page and shows the matching
settings right there, where they can be changed, grouped under their tab and
section. Matching a section header shows the whole section, and matching a
hint shows its setting. Searches match both the translated and the English
text.

Each result has an arrow that switches to the setting's tab, scrolls it to the
middle and highlights it.

The other tabbed screens with search (Developer Tools) keep the old filter for
now.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 14:46:46 +02:00
Henrik RydgårdandClaude Opus 5.5 6f798dfa99 Settings: Describe the remaining tabs as data too
Graphics, Controls, Networking, Tools, System and VR now fill in a
SettingsPage like Audio does, and each tab is listed in a table with its
builder. The tabs look and behave the same as before. Views that the item
types can't describe (the MAC address chooser, the ad hoc server row, text
inputs, the language and theme pickers) are custom items, so they still have
searchable text.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 14:46:30 +02:00
Henrik RydgårdandClaude Opus 5.5 2af86ed389 SettingsPage: Add the item types the other settings tabs need
Buttons, float sliders, slider steps and units, negative labels, a disabled
pointer, a separate category for choice names, and a setup callback for
one-off tweaks. CreateSettingView is now public, so single items can be
created (for search results), and CreateSettingViews can report the view
created for each item.

Also fixes the no-default slider assert, where NO_DEFAULT_INT was ambiguous
between the UI and config ones.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 14:45:17 +02:00
Henrik RydgårdandClaude Opus 5.5 b6f79261a2 Settings: Describe the Audio tab as data, then create views from it
Adds SettingsPage, a list of setting items (header, bool, int/string
choice, int slider, info, hint, or a custom view) that keeps its texts as
translation keys. CreateSettingViews() turns a page into the same widgets as
before. Since a page can be built without creating any views, search can
later work from it directly, in English as well as translated.

Slider defaults come from the config's own defaults unless given. The Audio
tab is the first one converted, and looks the same as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 14:38:51 +02:00
Henrik Rydgård 55f10e5590 Merge pull request #22712 from hrydgard/mapped-volume-keys
Input: Let mapped volume keys reach the menus, and consume them in game
2026-10-22 11:37:47 +02:00
Henrik Rydgård 57dc5bf956 Fix the enabled state of some settings hints 2026-10-22 10:59:44 +02:00
Henrik RydgårdandClaude Opus 5.5 9e6fdb5be7 Settings: Make the two nickname fields behave the same
The Networking copy showed a warning for the default name but didn't fill
in an empty infrastructure username; the System one did the reverse, and
didn't refresh the views. Both now use one helper that does both.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:31 +02:00
Henrik RydgårdandClaude Opus 5.5 b530b477f7 DevTools: Don't touch a deleted view when the trace file is picked
The save dialog's callback set the path on a stored InfoItem pointer. If
the views were recreated while the dialog was open, that view was gone.
Recreate the views instead, which reads the path from the tracer.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:31 +02:00
Henrik RydgårdandClaude Opus 5.5 b5b37954b3 Achievements: Don't crash recreating a leaderboard screen after the game is unloaded
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:31 +02:00
Henrik RydgårdandClaude Opus 5.5 0eeaeef610 Pause: Don't offer Load State on a screenshot in hardcore mode
The slot list already hides it. From the screenshot view, the load was
refused, but the pause menu still closed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:31 +02:00
Henrik RydgårdandClaude Opus 5.5 a897b95b75 GameScreen: Know whether the game is homebrew before creating either pane
isHomebrew_ was set in CreateSettingsViews, but CreateContentViews uses it
too, and in portrait it's created first.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:31 +02:00
Henrik RydgårdandClaude Opus 5.5 75b0fbe30c CustomButtonMapping: Keep unsaved button choices when the views are recreated
The checkbox array was reloaded from the config on every view creation,
but only saved when a popup closed or the screen finished. Rotating the
device reverted the choices. Also stop leaking a handler per button on
each rebuild.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:31 +02:00
Henrik RydgårdandClaude Opus 5.5 75ac7b6de8 DisplayLayout: Fix a few stale states
- The aspect ratio slider captured a copy of the layout config, so its
  enabled state never followed the Stretch and Integer scale checkboxes.
- Reset didn't refresh the views, which depend on the rotation.
- The shader list popup kept its old index mapping when recreated, so the
  current shader wasn't highlighted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 fbf101de36 Touch controls: Rotate with the current orientation's display layout
The D-pad and sticks always used the landscape layout's rotation settings,
while the screen and physical pads use the current orientation's.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 20686814a3 ControlMapping: Fix Autoconfigure in portrait, and Escape on the analog limiter
- In portrait the settings pane is a popup, so it got the list's
  dialogFinished and the pad was never autoconfigured. Use a callback.
- Escape was meant to cancel mapping the analog speed limiter (3cb4207369),
  but since the combo mapping rewrite it got mapped to it instead.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 8fc75c0344 Settings: Write the alternative speeds back only when they're changed
The percentages were converted back to frame rates whenever any dialog
closed with OK. That overwrote the values Restore Defaults had just set,
and the integer rounding drifted unchanged values down (100 fps became 99
on any unrelated change). Restoring defaults also had the old reporting
choice written back on exit; it's now re-read too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 0c8c447284 Settings: Fix a blank page when reopening settings on the Search tab
The saved tab was selected before the Search tab was added, so the index
was out of range and no tab was created. Select it after adding Search, and
create the current tab anyway if the saved one no longer exists (Search is
hidden on small screens).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 f5059f9948 DevTools: Encode the notification positions like the other screens do
None is -1, but the developer tools list had it last at index 8, which is
CENTER. Building the tab clamped None to Bottom Left, and picking None
showed notifications centered instead.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 33e700350e MemStick: Fix the missing file browser popup and the folder switch error
- Cancel on the "missing file browser" popup opened the help page anyway,
  and More info closed the memstick screen as if a folder had been picked,
  because any child dialog finishing with DR_OK did that.
- When switching to the new folder failed, the error was set but never
  shown. After a move, the screen was left with no buttons.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 5de5a1b74a CwCheat: Fix import error messages, a file leak, and a download on Back
- Importing showed "File not found" when the file existed and the import
  failed, and the other message when it was missing.
- The game ID check returned without closing the cheat file.
- Closing the download popup with Back started a download of an empty URL.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 a79fbbc606 GameScreen, CwCheat: Use the game ID from the info cache
Both worked out the ID themselves with a copy of the homebrew rule that
lacks the PS1 exception added to GameInfoCache in 7ced173c17. For a PS1
EBOOT in PSP/GAME, Game Settings then edited the global config even though
Create Game Config had made a per-game one under the real ID.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 bba29944e6 InstallZip: Don't let each pane forget the other's views
CreateSettingsViews and CreateContentViews both cleared all the view
pointers, and which runs first depends on orientation. In landscape, Install
and Play were never disabled during an install; in portrait, the done and
error notices never showed. Reset them once in BeforeCreateViews instead.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 3e46790a00 Store: Make Retry download the listing again
It only recreated the views, which showed the same connection error.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 8a7b64daa3 Adhoc: Start editing the server address from the current one
The static string was only initialized on the first call, so the text
editor (used where there's no native input dialog) showed whatever was
typed the first time, even after picking another server from the list.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 bbe84de2fe Store: Tag the product panel, not the list, so both keep their scroll position
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 edae3049f3 SystemInfo: Show the CPU name again, and use the right translation category
The static analysis cleanup in d6ebfed432 dropped the negation, so the CPU
name was only shown when it was "Unknown".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 9ba1d569e7 Settings: Show the analog alternative speed as a percentage
The format was set on the wrong slider (alternative speed 2, which already
had it).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 7139aa6aaf Settings: Remove side effects from building the tabs
Building a settings tab should only create views, so that the tabs can
later be described as data and searched without being shown.

- Don't reset the MSAA level when the device has none. The GPU already
  falls back to no MSAA (UpdateMSAALevel), and the reset overwrote the
  setting, including per-game ones.
- Read the reporting state in the constructor. It was only read when the
  System tab was built, but always written back on exit, so leaving
  settings without opening System turned reporting off.
- Move the Windows memstick location probe (which writes a temp file next
  to the exe) out of the System tab, and keep the checkboxes' enabled
  state in members instead of poking at the views.
- Show the Android/UWP memstick path through a callback instead of a
  copy made at build time, and drop a USB path computation whose result
  was never used.
- Make the reliable-UDP checkbox follow the UDP setting directly instead
  of recreating all views when it changes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 10:55:30 +02:00
Henrik RydgårdandClaude Opus 5.5 c51bcd458c Input: Let the key mapping dialog see volume keys, mapped or not
The volume key filter in NativeKey left unmapped volume keys to the OS, so
they never reached the dialog and couldn't be mapped. A new InputMode::AllKeys
lets a screen ask for them; the dialog consumes them so the volume doesn't
change while mapping.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 00:01:34 +02:00
Henrik RydgårdandClaude Opus 5.5 598645db08 Input: Let mapped volume keys reach the menus, and consume them in game
A recent input refactor made NativeKey return false for volume keys before
queueing them, so mapping them to L/R (handy on a phone without a controller)
stopped working in the menus, and in game the OS changed the volume as well.

In the menus they still change the volume too. Unmapped volume keys go to the
OS only, as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 23:53:59 +02:00
Henrik Rydgård 1adf3c553d Merge pull request #22549 from Kethen/aemu_postoffice_enet
UDP(ENet) mode for adhocctl & aemu_postoffice relay
2026-10-21 23:51:28 +02:00
Henrik Rydgård 03457d559b Merge pull request #22716 from hrydgard/vsh-mount-iso
Allow --mount in the app, and make VSH UMD autoboot a setting
2026-10-21 20:57:42 +02:00
Henrik RydgårdandClaude Opus 5.5 3a5c5a51c5 Allow --mount in the app, so --vsh can boot with a disc inserted
--mount ISO used to be headless-only, and EmuScreen always cleared
CoreParameter::mountIso. Pass it from the command line into the first
EmuScreen, which keeps it across resets and drops it when another game
is booted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 19:47:51 +02:00
Henrik RydgårdandClaude Opus 5.5 7d2663bf73 VSH: Insert and eject UMDs from the pause screen
While the XMB is running, the pause screen offers "Insert UMD" with the
drive empty, opening the Switch UMD game picker, and "Eject UMD" with a disc
in. The XMB notices the change through its drive callback, as it does over
the debugger's game.umd.insert/eject. Games keep "Switch UMD".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 17:32:43 +02:00
Henrik Rydgård 2c235b585e Merge pull request #22707 from hrydgard/me-pops
Boot PS1 EBOOTs through the firmware's POPS emulator
2026-10-21 14:42:06 +02:00
Katharine Chui 880158cfdb initial enet mode for adhocctl & aemu_postoffice relay 2026-10-21 14:19:54 +02:00
Henrik RydgårdandClaude Opus 5.5 7ced173c17 UI: List PS1 EBOOTs, with their own disc ID
The game browser left out EBOOTs with the PS1 category, which couldn't
run. Now they're listed where the Media Engine can be emulated
(Memory::CanCreateMESpace). And as a PS1 game's PARAM.SFO has no
DISC_TOTAL, the browser took it for homebrew and gave it a made-up ID
(SCUS00580 for Crash Bandicoot's SCUS94900): its own is kept now.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 13:15:30 +02:00
Henrik RydgårdandClaude Opus 5.5 fbf0cc2df4 Android: Detect the accelerometer and gyro instead of assuming them
SYSPROP_HAS_ACCELEROMETER was true for every phone and tablet, whether or
not it had the sensor. The activity now tells the native side what the
sensor manager found, which also answers the new SYSPROP_HAS_GYRO. VR
headsets still report neither. Every other platform returns false for the
gyro for now.

The "Use gyroscope" checkbox uses the new property instead of waiting for
gyro data to show up.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 12:20:20 +02:00
Henrik RydgårdandClaude Opus 5.5 010a9c7e2a Tilt: Add the right analog stick as a tilt output
Appended to the end of the tilt types, so stored values keep their meaning.
It shares the left stick's deadzone settings and preview, and like other
right-stick input it goes to CTRL_STICK_RIGHT.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 10:49:00 +02:00
Henrik RydgårdandClaude Opus 5.5 f84e63f753 Tilt: Steady the tilt input with the gyroscope where there is one
Tilt used the raw accelerometer as the gravity vector, which jitters with
sensor noise and jumps when the device is shaken. Now, when gyro data is
coming in, a complementary filter integrates the gyro rates and only pulls
the result toward the accelerometer with a 0.5 s time constant, trusting
the accelerometer less the further it reads from 1g. The fused vector goes
through the same ProcessTilt path, so calibration and sensitivity work as
before. Without a gyro, nothing changes.

The fusion lives in TiltEventProcessor behind NativeGyroscope(), so other
sources (DualSense) can feed it too. Android registers TYPE_GYROSCOPE next
to the accelerometer. A "Use gyroscope" checkbox (on by default, per game)
appears in tilt setup once gyro data has been seen.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 10:45:37 +02:00
Henrik Rydgård a51fe51055 Merge pull request #22690 from hrydgard/me-core
Media Engine part 1: Address space and core (off by default)
2026-10-21 08:37:22 +02:00
Henrik RydgårdandClaude Opus 5.5 deb9693f6a EmuScreen: Restart after a failed savestate load before drawing the frame
The restart shut the GPU down after PrepareCopyDisplayToOutput had bound its
pipelines in the open backbuffer pass, which trips the pipelinesToCheck_
assert in VulkanRenderManager::CheckNothingPending. The failed load already
stops the frame from running, so nothing is lost by restarting first.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 07:24:56 +02:00
Henrik RydgårdandClaude Opus 5.5 fef84cf0ca CPU: Add the Media Engine core, off by default
MeCore owns a second MIPSState in the ME's address space, held in reset
until released (SetReset). It runs on the interpreter, a slice behind the
main CPU: CoreTiming runs it for the cycles the main CPU has just used, in
Advance and ForceCheck. Its own PRId (COP0 22) and mfic/mtic flag; MMIO
counts as kernel mode on it, and a syscall stops it with an error rather
than reaching HLE. The interpreter's block stepping reads delay slots
through the stepping CPU's memory, and cache instructions log at verbose
level, as ME code flushes its caches in a loop.

Created at boot only for homebrew (PBP with MG category or no SFO, ELF;
the VSH counts, as vshmain.prx loads as an ELF), when "Enable ME
emulation for homebrew" is on: a global checkbox in developer settings,
off by default and not translated yet, or --me-core. Saved in its own
section after MMIO (SaveStart v5), with its own memory; loading a state
creates or removes the ME to match.

The boot page now starts with a reset stub that sends the ME on to
0xBFC00040, where homebrew puts its code (from the firmware's reset code,
read on a PSP-1000).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 22:22:40 +02:00
Henrik Rydgård 2b4a7ba5a2 Merge pull request #22684 from hrydgard/misc-fixes
Fix Font= in language inis, misc
2026-10-20 18:25:29 +02:00
Henrik Rydgård 4f71d62c28 Frameskipping is a gross hack, so move it in under "Speed hacks" 2026-10-20 16:32:44 +02:00
Henrik RydgårdandClaude Opus 5.5 7dd1475ed7 HLE: Pass the MIPSState to syscalls and their implementations
HLEFunc and ReplaceFunc now take the MIPSState they run on. The dispatch
paths (both interpreters and every JIT backend) pass in the state they
belong to, and CallSyscall*, hleFinishSyscall and the HLE mips call
machinery use it instead of currentMIPS.

The wrappers in FunctionWrappers.h take the function as `auto` and call it
through HLECall, which also accepts an implementation with an extra leading
MIPSState * parameter and passes the state to it. Any other signature still
fails to compile, as before. PARAM/RETURN now refer to a local `mips`.

The HLE functions (and replacement functions) that used currentMIPS now take
the state that way. Callers outside a syscall's own frame - CoreTiming
events, the adhoc matching thread, dialogs, PPGe, the debugger UIs - pass
currentMIPS or &mipsr4k explicitly. The kernel's thread internals still use
currentMIPS.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 15:45:14 +02:00
Henrik Rydgård aba3a99888 Merge pull request #22679 from hrydgard/exit-on-game-exit
Android frontends: --pause-menu-exit exits when the game ends, Args extra with URIs, Copy deep link
2026-10-20 13:25:53 +02:00
Henrik RydgårdandClaude Opus 5.5 55f02684f5 Android: Enable "Copy deep link" on the game screen, copying the content URI
PPSSPP has access to the URI, so a frontend or adb can launch the game with it,
which isn't true of a plain path on modern Android.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 12:42:07 +02:00