Commit Graph
235 Commits
Author SHA1 Message Date
Henrik RydgårdandClaude Opus 5.5 f6f9a00eb7 UI: Move file I/O off the render thread in a few screens
On Android the render thread runs the UI, and surfaceDestroyed waits for
it, so slow storage (SAF especially) there stutters and can become an ANR.

- Store: only check whether the game is installed when an install or
  uninstall finishes, not every frame.
- Savedata: read the modification time with SIZE on the GameInfo worker.
  The popup asked for it every frame, and each button on first draw.
- FirmwareScreen: scan the NAND, and erase it, on a worker thread. It
  rescanned on every RecreateViews, which is after every popup.
- GameScreen: look up the installed update, plugins and what the firmware
  can play on a worker thread. They ran on every RecreateViews, which
  happens as each piece of game info arrives.
- LaunchFile: wait only for the file type, and for PARAM.SFO just in the
  cases that use it.

Also add --start-screen=firmware.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-30 12:01:36 +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ård 4cb7ddb50c More misc UI polish 2026-10-26 12:10:10 +01:00
Henrik RydgårdandClaude Opus 5.5 34a0090a18 Install PS1 discs from zip and 7z archives, and show them as playable only with a firmware that runs them
A zip or 7z with a PS1 disc in it (a cue sheet and the files it names, a
.ccd with its .img and .sub, or a lone raw .bin or .img) is now installed
like a zipped ISO. A disc of several files goes into a folder of its own,
named after the cue sheet or .ccd. An ISO in the archive still takes
priority, and a lone .bin or .img only counts when nothing else does.

The game screen offers Play for a PS1 disc image only when the installed
firmware's POPS can run it: 3.95 to 6.61, with popsman.prx.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-23 15:01:22 +02:00
Henrik RydgårdandClaude Opus 5.5 23dffa9db3 POPS: Boot PS1 disc images as converted EBOOTs made on the fly
A cue sheet, a CloneCD .ccd, or a bare .bin, .img or .iso of a PS1 disc
now boots on the firmware's POPS, as the converted EBOOT.PBP popstation
would make from it. PS1EbootFileLoader builds the PBP header, PARAM.SFO
(the disc ID from SYSTEM.CNF) and the PSISOIMG header, TOC and block
index, and serves the disc image from the image's own files. Each block
of 16 sectors is a stored DEFLATE block: the manager won't read an image
of uncompressed blocks in its own format, but the converted PBP's inflate
takes stored ones, and with every block the same size, reads map straight
onto the files. Nothing is compressed or written anywhere.

Cue sheets can have any number of files, AUDIO tracks, INDEX 00 and
PREGAP, and a missing FILE falls back to the cue sheet's own name. A
2048-byte .iso gets Mode 2 Form 1 sectors made around its user data.

The EBOOT is mounted as the only file in host0:, through BlobFileSystem,
which now saves its open handles in savestates. The game browser lists
.cue, .ccd, .bin and .img, leaving out the .bin and .img files a cue
sheet or .ccd next to them describes, and a bare image opened directly
goes through the cue sheet that names it. GameInfoCache reads the title
and ID of these, and of real PS1 EBOOTs, from their PARAM.SFO.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-23 15:01:22 +02:00
Henrik RydgårdandClaude Opus 5.5 69ef4ce9fb UMD Video: Say which firmware is needed, instead of that it isn't supported
Without firmware that can play UMD Video (2.71 or later), the info screen and the boot error said
"PPSSPP doesn't support UMD Video", which is no longer true. They now say the firmware version
needed, from UMD_VIDEO_MIN_FIRMWARE, the same constant the check uses.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-23 11:36:50 +02:00
Henrik RydgårdandClaude Opus 5.5 d331bd6c8c UI: Play UMD Video discs in the XMB, straight from the game list
With firmware 2.71 or later installed, picking a UMD Video disc boots the XMB with the disc in the
drive and UMD auto-start forced on for that boot, so the disc's menu comes up. Without one, the
info screen saying UMD Video isn't supported shows as before. The info screen's Play does the same.

A disc with both a game and video asks which to start. For the video, the XMB comes up with
auto-start forced off, since auto-start runs the game.

Older firmware can't play these: 1.50, 2.00 and 2.60 crash in video_plugin or paf with a video disc
in the drive, and 2.50 refuses it. 2.71 through 6.61 reach Bourne Supremacy's menu.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-23 10:46:59 +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 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 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
Claude 363d816789 Game screen: Compress game as CSO
"Compress game" in the game screen's ... menu, for ISO, CSO, CHD and PSN
EBOOT.PBP games. It opens a list of the CSO presets (and Extract to ISO
for anything that's not an ISO already):

- Best: libdeflate level 12, 64K blocks
- PSP Compatible: zlib level 9, 2K blocks, readable by custom firmware

These match maxcso's presets, and the CSOs come out byte-identical to its.
The writer, Core/FileSystems/CSOCompress, reads the input through PPSSPP's
own block devices, so recompressing is a single pass with no temporary
file.

The original is deleted when done, unless "Keep the original file" is
checked (off by default). When the new name is taken, by a kept original
or another file, a number is added to it.

The work runs on a thread using every core, with a progress bar and time
left at the bottom of the game screen. It keeps going when the screen is
left, and the ... menu offers Cancel meanwhile. On the game list the
game's icon is covered by "Compressing...", and clicking it opens the
game screen instead of playing. When done, recents follow the new file
and the game screen and lists refresh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CCxekYqPnzNr5d8Tp1q7aZ
2026-10-19 16:01:53 +02:00
Henrik RydgårdandClaude Opus 5.5 0066599f9a Game browser: Add an XMB-style large list mode
- Fixes #22202

A third view mode next to grid and list: a list with full size icons,
scaled by the grid icon size setting. Like the XMB, the selected (or
hovered) game plays its ICON1.PMF in place of the icon.

The per-tab grid bools become GameBrowserView1-4 ints. The old GridView
keys are still read, to pick the default, but no longer saved.

The PMF decoding moved out of GameScreen's PMFView into a shared
PMFVideoTexture.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-14 10:24:32 +02:00
Henrik RydgårdandClaude Opus 5.5 82ae32d985 GameScreen: Return to the main screen properly after removing a game
"Remove From Recent" and "Delete Game" called switchScreen(new MainScreen)
from a popup, which only replaces the top screen, so the old MainScreen
and the GameScreen of the removed game stayed in the stack underneath.

Close the GameScreen instead once the popups above it are gone, and have
MainScreen refresh its browsers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:16:11 +02:00
Henrik RydgårdandClaude Opus 5 29c5d1baf1 Offer to install the disc's firmware updater from the game context menu
The game screen already reports which updater a disc carries, but there was no
way to act on it - the only route to installing one was picking an updater PBP
out of the browser. The unpacker already handles being pointed at a disc, so
this just wires the menu entry to it.

Shown only when the disc actually has one, and not while a game is running:
installing wipes the NAND that game has mounted.

InstallUpdateScreen takes the archive size now, because for a disc the size of
the file it was handed is the game's and says nothing about the firmware.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 16:25:13 -06:00
Henrik RydgårdandClaude Opus 5 f0dafdee10 Show and remove installed game updates from the game info screen
An installed update silently replaces what the game boots, so the info
pane now says when there is one - version, size and where it lives - and
the context menu offers to remove it again.

Removing takes the whole PSP/GAME/<DISC_ID> folder when the update is all
that's in it. When a digital game shares the folder, only PBOOT.PBP goes,
since deleting the folder would take the game with it and nothing records
what the install wrote. The confirmation names the exact path either way.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018izZ1mGTWhz2RqeudqsDQR
2026-09-08 11:15:15 -06:00
Henrik RydgårdandClaude Opus 5 396f9e802d GameInfoCache: report the firmware updater bundled on a game disc
Adds GameInfoFlags::BUNDLED_UPDATE_INFO, holding the version, title, size
and timestamp of the updater in PSP_GAME/SYSDIR/UPDATE. It comes from the
PARAM.SFO and the directory entry next to the archive, so it's a couple of
small reads on the ISOFileSystem the worker already has open - no
decryption, and DATA.BIN itself is only sniffed for its magic. Only
computed for ISOs; everything else is marked complete with an empty struct.

ISOFileSystem now parses the date out of the ISO9660 directory record,
stored as Unix UTC seconds and reported as the PSP's atime/ctime/mtime.
Those used to always read back as zero, so games calling sceIoGetstat on a
UMD file saw 1900 where hardware gives the mastering date.

Shown on GameScreen as e.g. "Firmware update on disc: 6.60 (2011-10-05),
25.6 MB".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149QcTVgZEXKXbgHyvXF4ZY
2026-08-23 16:44:38 +02:00
James0124 f38cbfd7b1 Show the (fallback) title on the game info screen even when there's no region ID
The fallback title was not shown on the game info screen when `PARAM.SFO` was missing.
Hoist the `TextView` creation from the `!regionID.empty()` branch.
2026-08-10 01:01:39 +02:00
Henrik Rydgård 7219cd2f5a Split off ScreenManager from Screen.cpp 2026-08-07 14:30:36 +02:00
Henrik Rydgård 5d10f281ef Fix integer overflow in PMF video frame buffer allocation
pmf_init reported stream dimensions without a cap, and PMFView::Draw
allocated width * height * 4 with 32-bit int arithmetic, so a crafted
ICON1.PMF could overflow the allocation to a small buffer while
sws_scale wrote the full frame.

- Reject videos with dimensions outside 1..720x480 in pmf_init (PMFs on
  the PSP never exceed 720x480).
- Use size_t arithmetic for the frame buffer allocation.
2026-08-01 11:57:27 +02:00
Henrik Rydgård 4d018cd7e5 Fix back behavior in GameScreen
Fixes #21884
2026-07-14 15:44:17 +02:00
Henrik Rydgård 6165edd445 Show the MEMSIZE parameter on the game screen if present in PARAM.SFO 2026-05-13 16:13:50 +02:00
Henrik Rydgård e0a5a3e2bf iOS: Add basic deep link support.
Fixes #21577
2026-04-28 22:17:24 +02:00
Henrik Rydgård fdfcda8859 Fix issue where the background remained when removing a game from recent
Fixes #21438
2026-03-15 12:08:53 +01:00
Henrik Rydgård 4f8cdbe165 Minor code cleanup (inline event handlers) 2026-03-15 11:43:18 +01:00
Henrik Rydgård 9097dd935a Somewhat improve the UI of the adhoc server list 2026-02-26 17:17:42 +01:00
Henrik Rydgård e50199ad0a Fix the gemini-written video player to actually work 2026-02-26 09:33:26 +01:00
Henrik Rydgård f13d339ed3 Set the CRC banner on the game screen to fit contents, instead of the screen.
Also make sure it's not visible when it shouldn't be
2026-02-25 00:52:25 +01:00
Henrik Rydgård dac8ccff1d Gamescreen: Reload savedataSize on open 2026-02-23 11:48:34 +01:00
Henrik Rydgård 40a5cd1509 Minor logging improvement, refresh gamescreen on deleted savedata 2026-02-19 16:05:00 +01:00
Henrik Rydgård e65013201f Fix color of setting hints. Minor tweak to clipboard notifications
See #21223
2026-02-17 11:32:10 +01:00
Henrik Rydgård 1cc2b7233a Fix some minor visual UI issues
See #21223
2026-02-15 19:57:56 +01:00
Nab 0b51d74bb2 Add icon to Create new shortcut option 2026-02-14 17:40:05 +00:00
Henrik Rydgård 1846163985 Replace Path::ToVisualString with GetFriendlyPath which shortens. Much better on iOS 2026-02-13 21:16:00 +01:00
Henrik Rydgård ca127b0e5b More fixes, more gamescreen button fixes 2026-02-12 01:35:57 +01:00
Henrik Rydgård 2bc43810a8 Improve display of homebrew without an icon in the game browser 2026-02-10 11:26:01 +01:00
Henrik Rydgård 936c344a52 misc 2026-02-09 16:41:51 +01:00
Henrik Rydgård cdd9d34af9 Improve handling of UMD Video (still unsupported but show background and icon, fix info screen) 2026-02-03 13:46:59 +01:00
Henrik Rydgård 998d385119 Bubble up CSO corruption errors so the user can see them 2026-02-03 11:57:05 +01:00
Henrik Rydgård cbcec3e27f Bugfix GetFriendlyPath, use in more places 2026-01-29 23:15:32 +01:00
Henrik Rydgård 1c80e93070 Improve the appearance of unsupported ISO files 2026-01-28 11:00:04 +01:00
Henrik Rydgård 24f2deeb2e Improve file identification.
Fixes #21154
2026-01-28 10:21:09 +01:00
Henrik Rydgård 34938e3de6 Move Notice to Common/UI 2026-01-25 15:10:26 +01:00
Henrik Rydgård 46e82f3c63 Game screen: Add a button to reset the played time counter 2026-01-23 18:54:22 +01:00
Henrik Rydgård f8ab0fab1d Clean up the "Use background as UI background" code 2025-11-25 15:47:03 +01:00
Henrik Rydgård 3116eba395 More UI work (#21035)
* Improve a couple of on-screen buttons (menu, fastforward)

* Fix the new continue button, oops

* Add some missing translations

* Split a translation string to make portrait look better

* More GameScreen redesign

* Don't accidentally go into game-specific mode

* Fix layout issue with popupscreens, fix context menu positioning

* One more icon
2025-11-24 20:33:13 +01:00
Henrik Rydgård 6cc945e57a Rework the reporting screen a bit 2025-11-23 01:15:07 +01:00
Henrik Rydgård 77c7ba1435 Rework the pause screen in portrait mode. Right-align popup menus if too far to the right on the screen. 2025-11-22 14:31:01 +01:00
Henrik Rydgård 57507ec9e6 GameScreen: New look in portrait mode 2025-11-15 20:44:14 +01:00
Henrik Rydgård 09d195c9ef More layout work. Use GameDB titles on the top of the game screen. 2025-11-15 20:44:14 +01:00
Henrik Rydgård 1ae76e871b Partial game-info-screen rework 2025-11-15 20:44:14 +01:00