- OSD: reload-immune visibility snapshot (fixes won't-turn-off); on/off hotkey now keeps the user's chosen stats
- Library: hide/unhide games; optional titles under shelf covers; Clear cached data in the App tab; refreshed drawer icons
- Per-game settings: fix scope stickiness after closing a game + open correctly from the shelf layout; green Play button that actually launches
- RetroAchievements: custom achievement-unlock sound picker
- Vulkan: re-enable attachment_feedback_loop_layout on Mali so accurate blending runs in-tile instead of the per-primitive barrier fallback (big speedup)
- ANGLE (GLES 3.1): emit GL_EXT_shader_io_blocks for interface blocks + alias glColorMaski to OES/EXT — fixes Mali-G77 black screen and mid-render crash
- In-game menu: Performance tab is now a yellow lightning icon
- OpenGL-via-ANGLE renderer toggle for broken native GLES drivers, with a
driver-keyed GL shader cache so switching drivers recompiles instead of
feeding foreign program binaries to glProgramBinary (fixes Mali-G77 crash)
- Gyroscope input (aim/steering modes, sensitivity, smoothing, invert) shared
between the Pad settings tab and the in-game Controls tab
- Re-add disc swap without closing the game, and per-cheat PNACH enable
- Xclipse GPU profile + Mali-G615 freeze gate; MediaTek Tekken 5 override
- GameDB: KH2, Tekken 5, Rumble Racing, MK Shaolin, Avatar
- Folder-reuse settings recovery (reverse-map INI + config mirror)
- In-game pause menu rail icons; make new settings searchable
- Resume/auto-load: wait for the renderer to present before restoring state
and force a present after load (reduces black screen on resume)
- Boot crash guards (pad state before VM); FXAA + CAS sharpening
- ci-nightly-dualcore.sh signs nightlies with the release rotation lineage
(debug<=API32 -> release>=API33) from repo secrets, so a nightly installs over
the existing com.armsx2 build; falls back to a throwaway key (with a warning)
- versionCode = Unix seconds since 2023-11, monotonic and always above the manual
10xx codes, so each nightly out-versions the last installed build
- versionName default 2.5.9 -> 2.6.0
- Discord announcement now includes the changelog (trimmed to Discord's limit)
- tools/ci-nightly-dualcore.sh builds the core at both host page sizes and
merges both .so into one APK so 16k-page devices load their native core
- nightly builds with PGO=optimize (committed pgo/armsx2.profdata)
- trigger the nightly on push to master (was schedule + dispatch only)
- plain-language changelog in the release body from filtered commit subjects
- Global/per-game settings scope toggle at the top of the settings rail,
plus an All Settings shortcut at the bottom
- Settings search overlay + index
- BIOS manager: scrollable list so controller navigation reaches every entry
- Close-app entry with a confirm dialog
- i18n updates
- Mali Vulkan: drop the old blend-clamp band-aid; rely on dual_source_blend
feature detection so only SRC1/blend-mix draws take the SW-blend path
(no more forced Blending=Max on Mali)
- Fix intermittent stale-tile reads: input-attachment descriptor type for the
texture-barrier feedback path, vendor-scoped to Mali
- broken_mad_deinterlace weave fallback for Mali-G57 FastMAD
- Add per-vendor mobile GPU profile system (Mali/Adreno/PowerVR)
- Tie test_and_sample_depth to texture_barrier (was forced on)
- Richer Vulkan device telemetry for field diagnosis
The looping MP4 wallpaper hurt in-library performance (sbro review). Replace it with a bundled static XMB-wave still (R.drawable.library_bg_xmb, drawn edge-to-edge via ArmsBackdrop's backgroundLayer). Remove VideoBackground.kt, res/raw/xmb_wave.mp4, and the video option from the background picker.
OSD now hides via RenderOverlays mirror of EmuConfig.GS->GSConfig + seed-false on first launch. Rumble: forward SetPadVibrationIntensity to Native::onPadRumble on Android (mono core had no call site). Library: bundled PS3 XMB-wave MP4 as default background, drawn edge-to-edge via ArmsBackdrop backgroundLayer (fixes landscape strip). In-app on-screen keyboard for library search; Recently Played shelf selection highlight; settings category tabs reachable via Row+horizontalScroll. Persian (fa) translation; gold RetroAchievements trophy.
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).
Vulkan render fixes (GS device backends), Oboe audio backend, GameDB armsx2_overrides.yaml override loader, EE+VU mac-port recompiler graft, PGO=optimize, and the VU-slam fix: an Android-only force-float in VMManager::SetEmuThreadAffinities (the slam was thread pinning locking the VU1 worker off the prime core, not the VU codegen). Also: CPU-name SoC-property fallback, Mali VK attachment-feedback-loop crash gate, MediaTek fbfetch disable, and on-device thread-placement diagnostic helpers.
The recompiler grafts and GS deltas are unguarded and land in the shared core (they reach the mac/Linux arm64 builds) - see REFACTOR_STATUS.md items 2 and 3 for the reconciliation this still needs; the VU graft is reducible to just the force-float fix.
- Host::GetHTTPUserAgent: report ARMSX2/2.7.407.0 (the RA-registered client)
instead of 'PCSX2 <gitrev>', which RA rejects as an outdated emulator and so
disables hardcore unlocks.
- ImGuiFullscreen: fix ImGui 1.92 AddRect arg order (flags/thickness swapped)
that drew a ~240px border on the RetroAchievements toast.
- VMManager: suppress the false 'Controller 1 has no input bindings' warning
(Android injects pad state directly, bypassing InputManager bindings).
SetFonts() is never called on Android (no Qt/language layer) so s_font_info
stayed empty and AddTextFont() returned null -> blocky/blank OSD. Seed it from
the bundled Roboto-Regular.ttf, and fall back to the built-in font if the atlas
still fails so the GS device can initialise regardless.
- R5900 _cpuEventTest_Shared: bail out early on VMState::Stopping/Shutdown and
on IsExecutionInterrupted() so the EE leaves Execute() promptly on stop
(previously hit the ~5s shutdown timeout).
- native-lib Host::RequestVMShutdown: no-op if already Shutdown. The queued
task could re-set Stopping after the run loop already reached Shutdown,
sticking s_state at Stopping so the next Initialize failed 'already running'
-- kick back to library on the 2nd game boot.
The IOP dispatch loop lost its 'if (iopRecNeedsReset)' guard, leaving a bare
recResetRaw() that ran a full IOP recompiler reset on EVERY block (~800/s).
recClearLUT zeroing the LUT then dominated ~97% of EE-thread CPU in memset, so
every game crawled ~10-50x too slow (black screen / Speed 0%). Also drops a
duplicated recPtr/const_pool.Reset/recClearLUT block in the same function.
The unconditional pcsx2DEV9Sources list compiled the real pcap_io.cpp on
Android, which references pcap_findalldevs / pcap_open_live / ... with no
libpcap present -> undefined symbols at link. A debug build hid this via
--gc-sections dead-stripping the unreferenced calls; the LTO release build
surfaced all 12. Android already ships Android/AndroidPcapStubs.cpp (the stub
PCAPAdapter), so gate the real pcap_io.cpp to non-Android platforms.