Commit Graph
944 Commits
Author SHA1 Message Date
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 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 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 ae4b7983aa Make --pause-menu-exit quit the app whenever the game ends
- Fixes #18456

For external launchers (Android handhelds like the Retroid Pocket), which want
control back when the game ends. Before, only the pause menu's Exit quit the
app; now the game exiting by itself, a stop request and dismissing a load
error do too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 12:21:37 +02:00
Henrik RydgårdandClaude Opus 5.5 ef8961e17a Freeze frame: Keep away from GE stepping, and keep other loads
Freeze-frame saves and loads its own snapshot outside SaveState::Process,
so it missed the check for a display list stopped in the GE debugger:
stepping a draw in a frozen frame reloaded the state under the list.

And a slot load or rewind while frozen was undone by the next frame's
freeze reload, while saying "Loaded State". Now it becomes the frozen
state, and is a full load (the GPU only skips its resets for the freeze's
own reloads).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 20:54:29 +02:00
Henrik RydgårdandClaude Opus 5.5 7e4127ae69 Pause menu: Don't close on a state load until the state is in place
Loading a state from the pause menu closed it right away, and the game
ran a few frames from where it was (seen and heard) before the state
was applied. Now savestate operations run while the game is paused under
the menu, and the menu closes once the load (or rewind, or load undo) is
done. Rewind snapshots aren't taken while paused.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 20:42:14 +02:00
Henrik RydgårdandClaude Opus 5.5 86e420b9ce EmuScreen: Show the loading spinner while a savestate saves or loads
The boot spinner, in the same corner without the background, while a
save, load or rewind is queued or in progress. Only after a quarter of a
second, so it doesn't flash up on every quick save; on desktop that's
rarely reached, but slow devices get some feedback.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 18:51:10 +02:00
Henrik RydgårdandClaude Opus 5.5 b75f487dc5 SaveState: Report a state that fails to load as being from another version
When the file reads fine but a section doesn't, that's almost always a
state from another version, so say that (LoadStateWrongVersion), with the
version that saved it and the failing section on the second line.

LoadPtr() now returns just the section title, for callers to phrase.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 17:50:48 +02:00
Henrik RydgårdandClaude Opus 5.5 8d7ce57fa8 Metal: Hook up the backend on Mac, with the null GPU for now
Selectable with --graphics=metal, the backend choice in settings and the
Mac menu bar. SDL creates a Metal view for it, and headless renders
offscreen. Games run on the null GPU until there's a GPU/Metal.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 12:02:22 +02:00
Henrik RydgårdandClaude Opus 5.5 d3f33d96d3 Create the GPU on the main thread during boot
The loader thread now only loads the game. PSP_InitUpdate creates the GPU on
the thread that owns the graphics device, so device loss can't race the
creation, and the device-lost flag and the GPU init on libretro's separate
path are gone. Vulkan loads its shader cache without waiting for the
pipelines, and PSP_InitUpdate keeps the boot in Booting until they're
created. Exiting during boot joins the loader thread in PSP_Shutdown.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 09:26:15 +02:00
Henrik RydgårdandClaude Opus 5.5 1cf65ab6a4 Clarify comments from the crash fixes
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 09:10:03 +02:00
Henrik RydgårdandClaude Opus 5.5 b5982e1b84 Android: Don't block the main thread on a game boot when losing the surface
EmuScreen::deviceLost waited for the boot thread to finish, so that it
wouldn't create the GPU on a lost device. With the main thread joining the
render thread on surfaceDestroyed, backgrounding the app during a slow boot
(like the firmware auto-install from the disc) caused ANRs.

Instead, the boot thread now skips creating the GPU if the device is lost,
and PSP_InitUpdate creates it once rendering resumes, as on libretro.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 07:47:49 +02:00
Henrik RydgårdandClaude Opus 5.5 96ff2bd883 Don't draw a frame from RAM outside the backbuffer pass after toggling Skip Buffer Effects
The GPU only picks up the setting when emulation runs, so after turning
Skip Buffer Effects off in the pause menu, PreRender ran the buffered-mode
display path with a GPU still in non-buffered mode. For a frame displayed
from RAM, that draws straight to output (since b8789af997) with no render
pass bound, crashing in VulkanRenderManager::SetScissor.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 07:47:48 +02:00
Henrik RydgårdandClaude Opus 5.5 9288061212 Chat: Let go of held input when the chat opens
- 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>
2026-10-18 12:58:30 +02:00
Henrik RydgårdandClaude Opus 5.5 19e4b77be4 Android: Ask for the local network permission for ad hoc, UPnP and servers
Part of #21585

Android 17 blocks LAN traffic in both directions (TCP and UDP, including
broadcast and multicast) without ACCESS_LOCAL_NETWORK. Ask for it when
networking, the built-in ad hoc server, UPnP, share-on-startup or the
remote debugger gets turned on, when a game initializes ad hoc with
networking enabled, and at startup if a server is set to start then.

A denied ad hoc send fails with EPERM, which the games never see, so show
a message for it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 20:44:05 +02:00
Henrik Rydgård f5255eefaf Move the Hardware Transform setting to developer tools, reset by renaming the key.
This setting should always be on, not having it ruins performance.
2026-10-16 13:27:23 +02:00
Henrik Rydgård bac8668204 Merge branch 'master' into add-fading-chat-button 2026-10-14 13:28:20 +02:00
Eray Cepni d970cf74f2 UI: Fade chat button with touch controls
Apply touch-control opacity to the chat button so it fades after
inactivity and reappears on touch. Keep it visible when touch controls
are disabled.
2026-10-14 14:20:33 +03:00
Henrik RydgårdandClaude Opus 5.5 5704b972e7 iOS: Remove OpenGL support from the app
The app now always uses the Metal view controller with Vulkan (MoltenVK),
for both the App Store and sideload builds. The GL view controller is gone,
and Common/GPU/OpenGL (except GLFeatures, used by the shader generators) and
GPU/GLES are no longer compiled for it. PPSSPP_API_ANY_GL is now off for
all of iOS except the libretro core, which still uses GLES.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 16:13:28 +02:00
Henrik Rydgård 7572ac05ca Screenshot code cleanup, fix issue where the notification would be in a second fast screenshot
Fixes #22497
2026-10-11 10:56:43 +02:00
Henrik Rydgård 1862efe392 Add a bindable key to create frame dumps 2026-10-09 13:26:22 +02:00
Henrik RydgårdandClaude Opus 5 0b5a8f537e Decide on the vertex decoder JIT with CoreParameter, not the CPU core
The vertex decoder JIT was enabled only when g_Config.iCpuCore was one of the
JIT cores, which tied an unrelated GPU path to the CPU setting. Headless leaned
on that by forcing iCpuCore to the interpreter after ApplyToConfig(), to keep
the decoder JIT off in the tests.

Add CoreParameter::bUseVertexDecoderJit instead. Standalone and libretro set it
wherever the host can JIT, so IR interpreter users on such hosts now get the
decoder JIT too. Headless sets it false, which keeps the test results as they
were and lets --cpu go through ApplyToConfig() like every other option.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-21 10:31:58 -06:00
Henrik RydgårdandClaude Opus 5 be834b4446 Ban freeze-frame in hardcore mode, and tell the user when a savestate is refused
Freeze-frame restores a savestate every frame, straight through
SaveState::LoadFromRam(), so it never touched the operation queue and neither
hardcore check saw it. Blocked at the toggle in the dev menu, and again in the
render loop, since hardcore mode can come up after the fact once the game has
been identified.

Enqueue also just dropped operations silently, so a load that arrived through a
path with no check of its own (--state, auto-load) did nothing with no
explanation. Both it and Process now go through WarnUserIfHardcoreModeActive,
which is the same predicate plus the standard message. Callers that already ask
it themselves return before reaching Enqueue, so nothing shows the message twice.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgACRqkQNpfJQ4fjwyoEup
2026-09-05 13:29:50 -06:00
Henrik Rydgård 9f90512ef6 Make instruction cache invalidation (for us, jit cache invalidation) clearer 2026-08-16 16:59:52 +02:00
Henrik Rydgård db8ff4391e Enable ImDebugger everywhere, on top of the regular UI. 2026-08-07 17:35:15 +02:00
Henrik Rydgård 7219cd2f5a Split off ScreenManager from Screen.cpp 2026-08-07 14:30:36 +02:00
Henrik Rydgård e4b90c0471 Fix issue with chat button / DevMenu button becoming focusable
This made gameplay a bit difficult when these buttons were enabled.
2026-08-07 06:56:52 +02:00
Henrik Rydgård 9fc2fff68a Fix lock around vkey queue in EmuScreen 2026-07-11 22:08:18 +02:00
Henrik Rydgård b0018ab883 Remove broken exit callback execution from EmuScreen destructor 2026-07-08 19:47:33 +02:00
Henrik Rydgård a7dc184613 Reapply "Implement exit callbacks. Attempt to solve #21828"
It was a mistake to revert c4d3cc8 , need to take savestates into
account

This reverts commit d5cec86933.
2026-07-08 19:45:42 +02:00
Henrik Rydgård d5cec86933 Revert "Implement exit callbacks. Attempt to solve #21828"
This reverts commit e4d3cc841c.
2026-07-08 18:09:09 +02:00
Henrik Rydgård 444f78bf84 Don't forget to clear the event queue.. 2026-06-25 13:00:40 +02:00
Henrik Rydgård 72ee82844d Doesn't yet work 2026-06-24 23:04:17 +02:00
Henrik Rydgård 02e9deb232 Fix some input behavior that got lost in the previous commits. 2026-06-24 21:48:44 +02:00
Henrik Rydgård 0840e292ab Move some logic out to a per-frame poll instead of per input event 2026-06-24 20:41:10 +02:00
Henrik Rydgård 20a4a6974d Untangle some logic a little 2026-06-24 20:41:10 +02:00
Henrik Rydgård 6e8c76fefc Don't really need "unsync" vkeys 2026-06-24 20:41:10 +02:00
Henrik Rydgård 5ab3d6042b Move modifier key tracking out from the screen system 2026-06-16 10:57:55 +02:00
Henrik Rydgård 7b19253d05 Start moving logic out of "Unsync*" input handling 2026-06-16 10:57:55 +02:00
Henrik Rydgård 02aaa3b2b9 Don't have pauseTrigger as an output parameter from ControlMapper::Key() 2026-06-16 10:57:52 +02:00
Henrik Rydgård e4d3cc841c Implement exit callbacks. Attempt to solve #21828 2026-06-15 12:12:57 +02:00
Henrik Rydgård a317890c08 Remove the GPUDebugInterface class
Just a pointless extra layer in the class hiearchy, making it
unnecessarily hard to modify the interface.

Might as well hit GPUCommon directly.
2026-06-02 11:15:08 +02:00
Eloren1 109d1caa50 Separate TriggerFinish from parent result 2026-05-31 22:05:53 +03:00
Eloren1 938029cd6a Add screenshots + extract LoadStateConfirmScreen 2026-05-31 21:55:06 +03:00
Eloren1 2926e1118d Add load confirmation popup after shortcut 2026-05-31 21:13:03 +03:00
Henrik Rydgård 231aefe476 Code cleanup for save state notification, add metadata field 2026-05-19 11:07:07 +02:00
Henrik Rydgård ed274c8a7e Just some lint fixing 2026-05-13 11:37:26 +02:00
Henrik Rydgård 6eb0b3fd51 Fix an issue with Exit icon not showing up in MessagePopup 2026-05-13 11:04:03 +02:00
Henrik Rydgård 3a599c4714 Fix audio focus issue by tracking the cause of lost focus.
Fixes #21643
2026-05-06 00:06:32 +02:00
Henrik Rydgård 32799755e6 Add some sanity checks in TabHolder (prompted by a crash report). Minor cleanup 2026-05-05 10:36:21 +02:00