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>
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>
The name lists (extensions, flags) become InfoItems, which have the
background a ChoiceGroup needs.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Links to other pages already had one. SettingItem::OpensScreen() gives the same to
choices (and custom items that are choices) that open a full screen, like control
mapping or the savedata manager. Ones that open popups don't get it.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Games in Android's scoped storage are opened through JNI, and getEnv()
asserts on a thread that isn't attached, so compression crashed on its
first file access.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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>
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>
A "Bar height" setting in the Misc menu, 166% by default on phones.
The item spacing in the bar grows along with it, so the menu titles can
be hit anywhere in the bar's height. The menus themselves keep the
normal style.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Instead of a hook and four Android_* functions declared in
ImDebugger.cpp, the debugger calls System_SetSoftKeyboardForced(), and
the platform reports a closed keyboard with
UIMessage::SOFT_KEYBOARD_HIDDEN.
"Keep keyboard after switching apps" is passed along with the request,
and the activity's onStop ends a keyboard that shouldn't persist, so the
native side no longer tracks app pauses.
The debugger is now also told when it's hidden. Frame() isn't called
then, so hiding it with the hotkey used to leave the keyboard up.
The keyboard button and its Misc menu options are only shown when
SYSPROP_KEYBOARD_IS_SOFT is set, which Android now reports too. iOS and
UWP on Xbox report it as well, but don't implement the request yet.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A "Show Keyboard" button in the menu bar brings up the soft keyboard and
keeps it up, typing into the debugger. On Android, NativeSurfaceView
acts as a text editor while it's forced, so showSoftInput actually works
for it, and passes typed text and key presses on to the native side.
Closing the keyboard with Back unticks the toggle.
The Misc menu can hide the button (which also turns the keyboard off)
and choose whether the keyboard comes back after switching apps.
Other platforms can provide an implementation through
ImDebugger_SetSoftKeyboardHook.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A thin floating strip on the right edge with Top, PgUp, Up, Down, PgDn
and End buttons, acting on the last debugger window the user touched
(its name is shown under the buttons). Regular ImGui windows are
scrolled directly. The CPU disassembly and the memory viewers get key
presses instead, and Top/End go to the start or end of RAM.
The strip can be collapsed to a single button, or turned off from the
Misc menu.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The menus are split into lambdas, so they can be shown either side by
side or as submenus of a single "Menu" dropdown. The compact layout is
used on narrow screens, or when chosen from the Misc menu (the default
on phones).
The bar also gets an adjustable left margin (to keep the first button
clear of rounded screen corners, on by default on phones), slightly
taller menu rows in the compact layout, and a Running/Stepping
indicator.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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>
Also adds the missing "Latency" key for the header of that name, and removes
the unused "Performance" key.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The system info screen's "Copy summary" kept the draw context it was
created with, and the GPU driver test screen kept its pipelines and
sampler, using and finally releasing them into a deleted context after
Android lost the surface. Look up the draw context when clicked, and
release the test objects on device loss (they're recreated on draw).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Android replaces both when it loses the surface (a recreate, which
changing the display resolution does, or switching away), but the
settings screen and its views live on. The external display setting's
enabled check, which runs on every draw, then called into the deleted
DrawContext ("Pure virtual function called!"). The UI scale and
"Reload UI atlas" handlers had the same problem with the UIContext.
Look them up through the screen manager when needed instead.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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>
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
It gets the UI page, Language and "Help the PPSSPP team" from the System tab, and
its General group. Its title and the General headers are looked up in MainSettings.
Translations: Move "General" from System to MainSettings
Done with langtool move-key.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
On the iPhone Duo's cover screen, the camera sits in a box in the top right
corner, which gives a side inset down the whole right edge in portrait. The
controls are far below it, so they lose width for nothing. iOS 27.1 reports
the box as an occlusion region, and from that we report how far down the side
insets are needed (SYSPROP_DISPLAY_SIDE_INSETS_BOTTOM). When that's within the
top third, the game screen and the touch layout editor skip the side insets.
The rest of the UI, including the FPS counter, still keeps them.
The regions can show up after the size and insets have settled, so the insets
are now recomputed on every layout, and a screen recreates its views when its
layout mode changes, since the touch controls are placed for the bounds they
were created in.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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>
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>
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>
The screenshot readback ran in ScreenManager's post-render callback, and
on Vulkan it ends the backbuffer render step. renderImDebugger() draws
after that, so taking a screenshot with the debugger open made its first
SetViewport() write through a null render step (an assert in debug
builds, a Play crash report in release). Do the readback at the end of
the frame in NativeFrame instead, which also puts the debugger in the
screenshot, and remove the now unused callback.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Like the other tabs, except that the screen keeps what the page edits that
isn't a config setting (the compatibility reports flag, which is written
back when the screen closes, and the Windows memstick checkboxes' state) in
a SystemPageState it passes in. The page's handlers move with it, as
functions taking the page host or that state.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Nothing calls CallbackMemstickFolder or sets pendingMemstickFolder_, which
are left over from an older way of changing the folder on Android.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>