The builds come from the DroidDeck-Components qualcomm-runtime release, built on ARM64 CI from this branch, so CI and fresh checkouts can stage the Qualcomm runtime without building it locally. The pins now match those Linux builds.
wallentx's libhybris runtime builder and patches, prebuilt bridge and WSI
releases, system-driver staging, android_wlegl buffer receiver and
Gamescope integration patches are what this backend is built on.
JeezDisReez identified turning off the image-bounds rewrite on Adreno as
the fix for the red graphics in DRAGON BALL: Sparking! ZERO.
Windows checkouts with core.autocrlf rewrote them with CRLF, which
changes their pinned hashes and can break git apply in the Linux build
roots.
(cherry picked from commit f6a2fbbe1b573b078cf9123638f32564c19b7a96)
Older Adreno drivers such as the 8 Gen 2's 0.676.1 lack
VK_EXT_external_memory_dma_buf, DRM modifiers and calibrated timestamps.
They failed device creation in the WSI layer, failed Proton games on the
zero-copy path, and corrupted the Steam UI under GPU compositing.
- WSI patch 0005 makes the Wayland platform optional per device, so a
device without its extensions stays usable for X11 swapchains instead
of failing vkCreateDevice.
- droiddeck-qualcomm-caps checks DMA-BUF export and import, the swapchain
extensions and Gamescope's linux-dmabuf once per session; Proton games
use the zero-copy WSI path only when it passes and stay on X11 SHM
otherwise. The session log records the verdict.
- The Steam browser uses software compositing when Zink offers less than
OpenGL 4.0, with BL_STEAM_CEF_SOFTWARE as the manual override.
Verified on the Adreno 740 (falls back to SHM and software compositing,
UI correct) and the Adreno 840 (zero-copy and GPU compositing unchanged).
(cherry picked from commit d8d0b10cced1f21a1e9bc7dca00efd89b389adb3)
VK_LAYER_HYBRIS_compat enables a Mali+DXVK workaround by default that
replaces the zero operand of the next OpSelect after any image sample or
fetch. On Adreno it collapses DXVK's comparison selects to constants,
which turned Sparking Zero's main-menu scene red.
(cherry picked from commit 8962b4f6f8c6d46178596dcfb02f98543135744d)
Games in Qualcomm sessions now hand Gamescope LINEAR DMA-BUFs exported by
the driver instead of copying frames through X11 SHM. The ARM WSI layer is
rebuilt with its Wayland backend and the private Gamescope gains a
linux-dmabuf global without a DRM device. BL_QUALCOMM_SHM=1 keeps the
shared-memory path; Turnip sessions are unchanged.
(cherry picked from commit 1bd4c04f193f48bdaf4d4aad374010abaf48765d)
## What this does
The itch.io Store tab used to show only four fixed shelves. This is the
first of a series of PRs that rework it. It adds real browsing: pick an
order and a price filter, and the tab loads itch's own listing for that
choice and keeps loading as you scroll. Login, the library, downloads
and installs are unchanged.
Platform and tag filters, the game page with the install picker, updates
and collections are not in this PR. They come in the following ones.
## How it works
itch serves every listing page as an RSS feed if you add `.xml` to the
address. The app already reads those feeds for the shelves, so browsing
reuses the same parser (`ItchShelves.parse`). Nothing here needs the API
key.
The address is built the way itch builds its own links: sort, then
price, then `platform-<name>`, then `tag-<slug>`.
| Choice | Address |
|---|---|
| Popular (default) | `https://itch.io/games` |
| New & popular | `/games/new-and-popular` |
| Top sellers | `/games/top-sellers` |
| Top rated | `/games/top-rated` |
| Most recent | `/games/newest` |
| Free | `/games/free` |
| On sale | `/games/on-sale` |
| Paid | `/games/store` |
| $5 or less | `/games/5-dollars-or-less` |
| $15 or less | `/games/15-dollars-or-less` |
Choices combine, for example `/games/top-rated/free`, then `.xml` for
the feed. Page 2 and later add `?page=N`.
## Changes
**`stores/itch/ItchBrowse.kt` (new)**
- `BrowseQuery` holds sort, price, platforms and tags. The default query
is the front page, which keeps the existing shelves.
- `ItchBrowse.path` and `url` build the addresses above. Only the
spellings listed above are used. Platforms and tags are already accepted
by the builder, ready for the next PR.
- `ItchBrowse.page` loads one page of results:
- Disk cache under `cacheDir/itch-browse`, keyed by the SHA-1 of the
address, fresh for 3 hours.
- Requests are made one at a time, at least 1.2 s apart.
- A 429 answer waits 8 s and tries once more.
- Each request is written to the store log (address, status, number of
games).
- `ItchBrowseState` is the Compose state for the tab: the query, the
games loaded so far, and the loading, ended and failed flags. A
generation counter discards answers that arrive after the user has
changed the query. Paging skips games it has already shown.
**`ui/ItchBrowseBar.kt` (new)**
- A sort chip row and a price chip row, plus a load-more trigger at the
end of the grid.
- Chips are selectable, work with the controller (`controllerConfirm`)
and use the same glide border as the rest of the app.
**`ui/StoresPage.kt`**
- The storefront shows the chip bar for itch.io and, when a non-default
choice is active, the browse results in the existing grid instead of the
shelves.
- Games you already own are marked as owned in the results.
- Empty and failed states have their own messages.
**`stores/itch/ItchShelves.kt`**
- `open(url)` is now `internal` so browsing can reuse it.
**`stores/StoresState.kt`**
- `detailItem` also looks in the browse results for itch.io, so tapping
a result opens its detail page.
**Strings**
- 13 new strings (sort names, price names, "Load more", "Couldn't load
games"), translated in all 33 locales.
**Docs and tests**
- `docs/development/itch-browse.md` explains the address scheme, the
cache and the paging.
- `ItchBrowseTest` checks the addresses the code builds against the ones
listed above.
## Testing
I checked every address with `.xml` added, and all of them load without
errors:
- Every sort, every price filter and every platform on its own.
- Combinations: `top-rated/free`, `top-rated/on-sale`,
`top-rated/store`, `top-rated/5-dollars-or-less`,
`top-rated/free/platform-windows` and
`top-rated/free/platform-windows/tag-pixel-art`.
- Paging: `?page=2` and `top-rated.xml?page=2`.
The unit test locks those addresses in.
## Not in this PR
- Platform and tag filters in the UI, and search.
- The game page, the version picker and install for free games.
- Updates for installed games and itch collections.
- Android builds will link out to the itch.io page. Butler patching
comes last, as an add-on pack.
The sort and price chips now cover everything itch's browse page offers, with the
paths copied from its links: new-and-popular, top-sellers, top-rated and newest
for sorts; free, on-sale, store, 5-dollars-or-less and 15-dollars-or-less for
prices; platform-windows, -osx, -linux, -android, -ios, -web and -mobile-web.
The guessed alternative spelling of the free filter is gone, so a query is one
address. The tests assert the addresses itch itself uses.
New and reworded strings in all 33 locales.
droiddeck-steam-shortcuts and AddedGames.accountConfig took the account
marked "MostRecent" in loginusers.vdf, else the only userdata folder.
The arm64 client here writes no MostRecent, so with two accounts in one
install nothing was picked: no added or store game reached
shortcuts.vdf ("no signed-in account yet; nothing written") and Steam
answered their launch with "App configuration unavailable".
Without MostRecent, take the account marked AutoLogin, then the one with
the latest timestamp. Both sides use the same order so the app reads the
config the guest script writes.
The Store tab only had four fixed shelves and a title search. A row of sort
(Popular, New, Top rated, Top sellers) and price (Any, Free, On sale) chips now
sets a BrowseQuery; anything but the defaults swaps the shelves for that query's
games, loaded page by page as the grid scrolls.
ItchBrowse builds itch's listing-feed URL (platform and tag segments are in the
builder for the next change), tries each spelling of a price filter until one
answers, spaces requests 1.2 s apart, backs off once on a 429, and keeps pages
in the app cache for three hours. Every request is logged with its status and
game count so a wrong URL guess can be fixed from a device. Owned games replace
their browse copy so Install and the owned markers are right, and the detail
page finds browse results.
Strings for all 33 locales; URL-builder tests; docs/development/itch-browse.md.
Steam installs Proton EasyAntiCheat Runtime (1826330) and Proton BattlEye Runtime (1161040) as tool depots. The launcher's Games tab and the desktop's game entries now skip them like the other runtimes.
The content log was read with RandomAccessFile.readLine, one byte per read, on the main thread. A 4 MB log took about 2 s on the first poll, enough for an ANR on slower devices while a download runs. It is now read through a buffered reader with the same Latin-1 lines and offset, and the per-line regexes only run on lines that can match.
Games the Epic client installed now carry their LaunchCommand arguments too, split by a new launch.split op. A doubled quote inside a quoted argument is one literal quote, and an install with a version ignores a manifest without the same build.
The manifest's arguments apply only when its build matches the installed version, only arguments the merge inserted are tracked as its own, escaped quotes split like a Windows command line, and the REDprelauncher rule needs Cyberpunk2077.exe beside it.
Feature level 12_2 makes vkd3d-proton report mesh shaders and ray tracing that Turnip doesn't provide. Caravan SandWitch (Unreal Engine 5) then builds mesh shader pipelines without a pipeline layout and the driver crashes; Cyberpunk 2077 stops at ray tracing initialization. Only these two games get 12_1, and a value set in a game's own settings still wins.
Epic manifests carry a launch command next to the launch executable, which the Epic launcher passes to the game. It was read and dropped, so Caravan SandWitch never got -PCStore=EGS and quit with "started outside of any known PC store". The manifest's launch command now joins the game's arguments, including for games already installed.
The redistributable seeder marked every process in a game's install scripts as already run, so the Ubisoft Connect installer that Ubisoft games list was skipped and they stopped with "Unable to locate Uplay PC". It is now left to run like the Vulkan runtime installer, and a marker an earlier seeding wrote is taken back out.