An external display (like an Apple TV over AirPlay) becomes a Game
output, when the backend is Metal. The game is shown there full screen,
and the phone shows the touch controls with "Playing on TV" in place of
the game. The menus stay on the phone. With other backends, iOS keeps
mirroring.
Up to iOS 26 the external display scene comes from the Info.plist role.
iOS 27 ignores that, and only offers the scene to apps that register a
scene accessory for it, so we do that too. The registration is withdrawn
when the view controller shuts down, so it follows a backend change, and
a restart now goes to the app's scene rather than the first one.
An Apple TV 4K only offers 3840x2160 over AirPlay, so the stream stays
4K, but we render at 1920x1080 and let the layer scale it up.
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>
Shares the iOS frontend, with camera, location, motion, photo/document
pickers, share sheet, clipboard, microphone, battery and rotation compiled
out. The view controller is a GCEventViewController, so controllers only
reach us through GCController, and the Siri Remote is read as a micro
gamepad and sent as arrow/enter/escape/back keys. tvOS has no persistent
storage besides NSUserDefaults, so the memory stick lives in Caches for now.
Configure with -DIOS_PLATFORM=TVOS. The MoltenVK submodule gets the tvOS
slice from the same stock v1.4.2 release.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceUsbMic input comes from the input side of the RemoteIO unit that
already does the output. The input callback only copies samples into a
lock-free ring buffer, sized so it never allocates, and the CPU thread
drains it into Microphone::addAudioData when sceUsbMic polls, the way
the SDL backend works. Reconfiguring the unit happens on the main thread.
Whether the game is recording is kept apart from whether the unit's
input is on, so recording resumes after an interruption or a trip to
the background, which shut the unit down. The unit also runs, silently,
when sound is off but the game is recording.
While recording, the session is PlayAndRecord, with Bluetooth through
A2DP so headphones keep full quality and the built-in mic is the input.
Permission is asked for on iOS 17+ through AVAudioApplication.
Also moves the microphone recorder homebrew used to test this from
Tools/psp-microphone to pspautotests, as demos/microphone, and updates
the submodule.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An unused IAPManager startObserving (which would have registered the
observer twice), the obsolete UILaunchImageFile, debug logging of the
SceneDelegate class loading, and a commented-out JIT version check.
Also bring the file overview at the top of main.mm up to date.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Request an orientation update with setNeedsUpdateOfSupportedInterfaceOrientations
on iOS 16+, where attemptRotationToDeviceOrientation is deprecated.
- Open the document picker with UTTypes on iOS 14+, and present it from
sharedViewController rather than through the deprecated keyWindow.
- List cameras with a discovery session instead of devicesWithMediaType.
- IS_IPAD() instead of UI_USER_INTERFACE_IDIOM().
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- AudioEngine.mm/.h: not in the source list at all, only in the ARC
set_source_files_properties list, and written for manual retain/release
([super dealloc]), so it couldn't have compiled under ARC anyway. The actual
audio path is iOSCoreAudio.mm.
- DisplayManager.mm: empty file, referenced nowhere.
- iOSCoreAudioSetDisplayConnected: never called, so g_displayConnected was
always false and the external-display branch in UpdateSession unreachable.
Also dropped an unused local there.
- AppDelegate: the "screen" property was never assigned, so both view
controllers were setting their frame from [nil bounds], i.e. CGRectZero. The
window sizes the root view anyway. Also removed the stale launchPPSSPP:argv:
declaration (it lives on SceneDelegate now), a forward declaration of a
PPSSPPViewController protocol that doesn't exist, and an unreachable return.
- getView: declared on the base class and implemented identically in both
subclasses, called by nobody.
- bindDefaultFBO: moved the empty implementation to the base class so it isn't
missing there, and dropped the Metal no-op override.
- The unused delta/lastTimestamp computation in displayLinkFired.
Also fixed the viewWillAppear/viewWillDisappear log messages in the GL view
controller, which claimed to resume and pause the display link but don't.
The getView and bindDefaultFBO changes clear three -Wincomplete-implementation
warnings, and the AppDelegate.h one clears a fourth.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZk5y4Fzw811WJoNWZb8Sc
* Rename LogType to Log
* Explicitly use the Log:: enum when logging. Allows for autocomplete when editing.
* Mac/ARM64 buildfix
* Do the same with the hle result log macros
* Rename the log names to mixed case while at it.
* iOS buildfix
* Qt buildfix attempt, ARM32 buildfix
By setting up a Mach exception handler, we can try to handle most
signals before they cause the system to hang. Since PT_TRACE_ME enables
CS_DEBUGGED on the parent process as well, we can simplify some of the
code as well.