Gate all macOS-only system APIs behind TARGET_OS_IPHONE checks across the shared core: ApplicationServices, IOKit, mouse APIs, AppKit, MetalFX, CDVD Darwin sources, USB, discord-rpc, cubeb CoreAudio HAL, and BSD networking headers in DEV9. Port TARGET_OS_IPHONE guards for DEV9 AdapterUtils with iOS fallbacks for sockaddr_dl, rt_msghdr, and sysctl. Add ARMSX2_ROOT to the include path for the frontend's common include style. Drop the global _M_ARM64 define that triggered fast_float MSVC intrin.h inclusion since __aarch64__ covers the core paths. Gate MTLFeatureSet_macOS_GPUFamily1_v1 behind !TARGET_OS_IPHONE. Fix missing unistd.h and gate pthread_jit_write_protect_np which is unavailable on iOS. Add stubs for DarwinMisc JIT diagnostics, Achievements stats and info APIs, Discord_Register, Host capture callbacks, and the host hotkeys map so the frontend links cleanly. Merge upstream master.
Strip the legacy Android, React Native, Java, Gradle, and res/ directories from platforms/ios that were inherited from the original port. Configure the CMake build for the iOS target with local module discovery, PCAP and CURL guards, rapidyaml source path fixes, Vulkan disabled, lz4 build flags scoped, libjpeg-turbo skipped on iOS, and the Qt UI and test runners turned off. Set CMAKE_SYSTEM_PROCESSOR to arm64 for cross-compilation. Add a self-contained GitHub Actions workflow that builds an unsigned IPA for real devices using the iphoneos SDK, named with the commit SHA. Merge upstream master to stay current.
The pinned bottom toolbar rendered edge-to-edge (full width) while the top one is
inset by the grid's 8dp + cutout content padding, so it read wider. Apply the same
side inset to the bottom bar's Box so both placements are identical width (vivi).
- Add a Library-toolbar position setting (App tab, Top/Bottom). Both placements
render the SAME ArmsTopBar rounded-pill (bottomEdge just swaps the status-bar
inset for the navigation-bar inset), so top and bottom look identical — the old
bottom bar's top-only-rounded shape was the mismatch vivi flagged.
- At the bottom, the controller reaches the toolbar by pressing Down off the grid's
last row; the grid reserves the matching top/bottom content inset per position.
- Fix Recently Played being skipped in shelf view for real: replace the
selectedIndex<columns 'top row' guess (fragile when the per-row count is off) with
a move-then-check — attempt moveSelection, and if the selection didn't move we're
on the edge row, so step into the chrome zone. Works regardless of shelf/grid
column count in either direction (up->chrome, down->bottom toolbar).
- Revert the library toolbar back to the top (bottom bar looked worse).
- Camera-follow: the grid only scrolled to the selection while searching, so
normal controller browsing never followed the selector. Now it follows always,
targeting the selected cover's real lazy-grid index (accounts for the leading
toolbar/search/recents/header items and shelf rows) and only scrolls when the
cover is off-screen. This also lets the selector visibly climb to the top row
and into the Recently Played shelf in shelf view.
- Make the search field a controller Search zone (Toolbar -> Search -> Recents ->
Grid): highlights when focused, A focuses it and opens the keyboard.
- Language screen: LazyColumn -> scrolling Column so every language row composes
and registers in the nav registry — controller nav no longer sticks on the last
on-screen language (Italian) and scrolls to follow the selection.
- Add a Fixes tab to the in-game pause overlay rendering the full FixesTab,
live-applying via InGameOverlay's shared Settings; its controls are
SettingsControllerNav items so the overlay's content-pane nav drives them.
- Move the library view toolbar (menu/refresh/sort/layout/2D-3D/background) to a
pinned bottom bar (vivi's mockup). Controller reaches it by pressing Down off
the grid's last row; grid reserves bottom padding + owns the status-bar inset.
- Shift the night palette toward the OG ARMSX2 blue (deep navy backdrop/surfaces).
- BootSplashActivity plays the refresh intro video (res/raw/boot_intro.mp4)
once per process with tap/back/timeout/error fallthrough; new App-settings
toggle (ui.bootLogo, default on) skips it straight to Main when off.
- Shelf view: report per-shelf column count so D-pad up/down move between
rows and the top row can reach the Recently Played zone (was left/right only).
- Controller-nav skip fixes: Language row, split GPU-driver source groups,
UI-size + in-game framerate sliders now register/adjust.
- Add Ukrainian + Kurdish languages; re-translate Russian for accuracy.
- Drop a duplicate EN i18n key (games.toolbar.background).
Re-apply the Android-specific GS deltas on top of the canonical GS as guarded hunks so
PC/mac/Linux/Windows stay byte-for-canonical:
- VK: restore the push-descriptor fallback (Adreno/Mali stall inside
vkCmdPushDescriptorSetKHR -> textures never bind -> black screen) as a capability-gated
path; desktop keeps push descriptors unchanged. Mobile vendor gates
(Mali/Adreno/PowerVR/Xclipse), dyn_shaderc, FIFO_RELAXED present mode, PowerVR swapchain
width-align. depth_feedback forced off only under #if __ANDROID__ (desktop keeps
feedback_loops()).
- OGL: re-apply GLES support (EGL context, is_gles shader branches, GLES query objects),
runtime-gated by is_gles; guard 3 desktop-reachable riders (present-path
glInvalidateFramebuffer -> is_gles, EGL SetDisplay body -> #if __ANDROID__, restore the
negative-swap-interval probe).
- RA toast: guard the AddRect call on IMGUI_VERSION_NUM (desktop imgui 1.92.8 swapped the
thickness/flags args; Android vendors 1.92.6) so the toast border renders on both.
- Suppress the 'Graphics API is not set to Automatic' OSD warning on Android
(#if !__ANDROID__); desktop keeps the canonical warning.
- REFACTOR_STATUS: mark the GS re-apply resolved; note the imgui two-copies version skew.
Drop the aR5900*.android.cpp EE fork; Android now builds the canonical Phase-7 aR5900* like every other arm64 target. Device A/B (canonical EE+VU + force-float, PGO tuned for the mac-port so rigged against canonical) showed canonical EE at refresh parity on Android: GoW2 combat EE ~12.8ms, 100% speed / 60fps. The real Android perf lever is the force-float in VMManager::SetEmuThreadAffinities, not the backend. Restores the single shared-core goal.
Back-port the set_user_data() setter onto the Android-vendored rapidyaml 0.10.0 so common/YAML.cpp (from the pcsx2master merge) compiles; the PC/mac build resolves a newer system ryml via find_package. Minimal shim pending the 3rdparty rapidyaml de-duplication (REFACTOR_STATUS #4).
The PC arm64 jobs are already blocking; make explicit that they are the guardrail
against a mobile-motivated change silently mutating the shared core, and that
mobile specifics must be guarded or forked (never grafted unguarded).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Three shared-core behavioral changes rode into PC unguarded via ecfebfd6b2 and are
reverted to canonical; the genuinely Android-only pieces around them (force-float +
nice-priority in VMManager, guarded #if __ANDROID__) are kept:
* MTVU: WaitForWork() -> WaitForWorkWithSpin() spin-wait swap (all platforms)
* VMManager: removal of the 'Graphics API is not set to Automatic' OSD warning
* VMManager: s_thread_affinities_set tracked new_pin_enable instead of the
canonical EmuConfig.EnableThreadPinning (desktop pinning-flag behavior)
Kept as legitimate additive/guarded shared changes: the new ThreadHandle API
(SetNicePriority/GetAffinity/GetCurrentCpu) + semaphore cache-line alignment, the
GetThreadPlacementDebug helper, Oboe/SoC-name/OSD-label Android features, and the
armsx2_overrides.yaml GameDB loader (PC-safe; no override file shipped).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The ~47 pcsx2/GS/* deltas in ecfebfd6b2 were not Android rendering fixes: they were
a wholesale copy of refresh-experimental's *divergent* GS subsystem, landed
unguarded. It touched Windows-only DX11/DX12 and Metal backends (e.g. DX11
depth_feedback / multidraw_fb_copy feature-flag flips) that cannot be Android
changes, so it silently regressed the PC renderers to a stale branch state.
The GS device interface headers all moved together, so GS is an all-or-nothing
snapshot; reverting the whole subsystem restores canonical PC/mac/Linux/Windows
exactly. Android GS parity must be re-earned on top of canonical, behind __ANDROID__
guards and device-tested -- tracked in REFACTOR_STATUS.md #2. The graft remains
available in origin/master history (ecfebfd6b2) as the reference.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ecfebfd6b2 grafted the mac-port EE backend into the canonical aR5900* files as 57
hunks interleaved through the shared code, unguarded, replacing the Phase-7 EE for
every arm64 target. Inline #ifdef guarding of an interleaved codegen rewrite is
unmaintainable, so fork at the file level instead:
* canonical Phase-7 EE restored at arm64/aR5900*.cpp (PC mac/Linux/Windows)
* mac-port graft preserved at arm64/aR5900*.android.cpp (Android only)
* CMakeLists selects between them with if(ANDROID)
Both share the canonical aR5900.h/aR5900Analysis.h (the graft only added comments
there; the cross-TU interface is identical). PC arm64 returns to canonical codegen;
Android keeps its device-tested EE win.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The VU graft in ecfebfd6b2 replaced the shared canonical microVU codegen with the
mac-port variant for ALL arm64 targets (mac/Linux/Windows), unguarded. It is
redundant: the Android VU slam was root-caused to thread PINNING (VU1 worker locked
off the prime core), not VU codegen, and is fixed backend-agnostically by the
guarded force-float in VMManager::SetEmuThreadAffinities. Reverting to canonical
restores the PC arm64 recompiler with zero Android perf loss.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>