The session category was switched before the audio unit's input was
turned off, and iOS refuses ('!pri') to leave PlayAndRecord while the
input runs. So after a game used the microphone, the session stayed in
PlayAndRecord, ignoring the silent mode setting. Switch it while the
unit is stopped instead.
Also log the two setCategory failures separately, and the route's input.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The playback categories we use route to AirPlay on their own (checked
with screen mirroring to an Apple TV, with every combination of the
silent mode and mix-with-others settings). PlayAndRecord, used while a
game records from the microphone, needs AllowAirPlay for that.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
EXIT_APP is handled on the render thread, and calling exit() there ran
the destructor of the still joinable render thread std::thread, which
calls std::terminate. Shut the view controller down on the main thread
first, which joins the render thread, then exit.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Pulling down Control Center starts a touch on our view that UIKit
doesn't always end or cancel. The tracker kept that slot down forever,
and touch input stopped working until the app was restarted.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
It was left unresolved with the kernel mutex calls, as they all let the
flash drivers reach the NAND controller during a VSH boot. It's the
mutexes that do that: with only the FPL resolved, sceIdStorage_Service
allocates from its pool and every firmware's VSH in 1.50-6.61 boots to
the same XMB picture as without it. Resolving the mutexes still hangs on
0xbd101300.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Registering with report.ppsspp.org starts with a DNS lookup that can't be
cancelled, and it ran on the server thread, so ShutdownWebServer() from
onDestroy waited for it on the main thread (an ANR on Play). It now runs on its
own thread, which the server leaves behind if it's still in the lookup.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Fixes#22365
Controllers with no sticks, like the 8BitDo FlipPad, don't get an extended
gamepad profile, so InitController ignored them. Fall back to looking up
the same buttons in the physical input profile by name, requiring at least
an A button and a D-pad, and log the element names it found.
Such a pad can have a micro gamepad profile, which InitSiriRemote would
have taken as a remote, so it now skips anything with a B button.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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>
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>
The layout editor divides by it, and drawing the grid never finishes when
it's 0. Only the slider limited it, so a hand-edited ini could hang.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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>
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>
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>
- 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>
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>
- 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>
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>
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>
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>
- 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>
- 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>
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>
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>
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>
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>
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>
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>
MeasureString was slow mostly because of wrapping: DrawStringRect and
MeasureStringRect re-ran the word wrapper every frame, and it measures
every prefix of every word. Wrapped strings are now cached. The caches
are unordered_maps with an xxhash of the key, and lookups reuse a key
buffer so a hit doesn't allocate. UIContext also skips switching fonts
when measuring in the current style. In a Mac debug build, 200 cached
measures go from 0.26 to 0.06 ms and 10 wrapped paragraphs from 2.1 to
0.01 ms per frame.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
libretro's buildbot uses Xcode 16.0, whose clang doesn't predefine them, so code
that tests TARGET_OS_IPHONE without including TargetConditionals.h (like
aemu_postoffice's enet.c) broke there and passed here.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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>
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>
The game shares Resistance: Retribution's effect engine, smoke trails and all: a trail gets a
new node on every update while the nodes expire by the effect's clock, so the faster the game
runs the more smoke there is. When the tank explodes, the smoke grows the display list past its
500KB buffer at a steady 60fps (an overclocked CPU gets there), the list runs into the heap and
the game crashes on a bone array it overwrote. Hook the same two functions as in Resistance:
nodes at most every 1/30 of the effect's clock, and the overflow guard as a backstop. At 428MHz
the list now peaks at 351KB, against 512KB and a crash before.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>