Bannerlator 2.9-pre3
Pre-releaseBannerlator 2.9-pre3 — test build
⚠️ This is a pre-release, not a stable buildIt exists so the work below can get real testing on real devices. Expect rough edges. The headline feature — the rebuilt virtual controls editor — is still in-progress work from an open pull request that hasn't been merged or fully reviewed yet.
- Stable users are not affected.
2.8remains the Latest release; nobody is offered this unless they ask for it.- Already on 2.9-pre1 or pre2? This build carries the same versionCode (49) so it installs straight over them — but for that reason the in-app updater will not offer it to you automatically. Grab the APK below.
- Coming from 2.8? Settings → enable "Include pre-releases" in the updater, or just sideload.
- If it misbehaves, install 2.8 back over the top. It's app-side only, so nothing about your containers is at risk either way.
- Please report what you find — that's the entire point of this build. Open an issue with logs where you can.
Like the last several releases this is entirely app-side — no ImageFS reinstall. Containers, themes, custom accent and per-game settings all carry over. Install straight over 2.8, pre1 or pre2.
🔁 What changed since 2.9-pre2
pre2 was cut two days ago. main has moved a long way since, and the controls editor has had another eleven commits of its own.
🎮 Controls editor — controller handling and custom icons (by @arro000)
- Custom icon rendering options — more control over how imported glyphs are drawn, plus a fix for paint state leaking between elements.
- Opt-in Button Grid multitouch — press more than one cell of a grid at once, off by default.
- Controller input correctness — momentary button edges are now tracked per device, pulses per source, and mappings dispatch on state edges rather than levels. If you had a controller that double-fired, dropped inputs when a second pad was connected, or left a button stuck, this is the area that changed.
- Bounded combos and a resized event buffer, and deferred range-input callbacks are now cancelled properly.
- Pulse state maps are reused rather than reallocated each frame.
🆕 Smart Game Import (new on main since pre2)
Adding a game now tries to work out what it actually is instead of handing you the executable's filename.
- Automatic naming from folder signals, PE version info, Steam and GOG id files — with names normalised (colons, ™/®, version tags and
-Win64-Shippingsuffixes stripped). - Search Steam confirmation dialog when the guess is uncertain, so you can pick the right title.
- Dependency detection — the importer scans the game folder for bundled redistributables and recommends the components it needs as chips you can install in one tap, with bundled and optional split out.
- Installer-based components now run visibly on the container desktop rather than silently, and return you to where you were afterwards.
- Game Details editor, with the details shown on the loading screen.
🖥️ In-game refresh rates above 60 Hz (new on main since pre2)
Games that expose a refresh-rate setting were locked to 60 Hz on any panel, and no client-side setting could change it — the cause was on our side. Our X server implemented BigReq, DRI3, MIT-SHM, Present and Sync but no RandR at all, which is how Wine enumerates display modes; finding none, it fell back to a single synthetic 60 Hz mode.
- The X server now implements RandR, and advertises the rates your panel actually supports.
- Max in-game refresh rate — a ceiling, as a container default and a per-game override, for when you'd rather a game didn't reach for 144.
- This is a different axis from the existing match/manual refresh settings: those drive the host Android panel, this bounds what the guest game may request.
✅ Tested and verified — but you need a current Wine layer
This only works on a Proton layer whose
winex11was compiled with xrandr — the refreshed Proton 11.0-1 and Proton 10.0-4 builds, both downloadable in-app. On an older layer the app detects the missing capability and deliberately leaves the unlock off, so nothing regresses; you simply won't get the extra rates until you download one of those two.Restart the game after changing a cap — engines read the mode list only at startup.
🎞️ Frame generation
- A fifth model, "FSR3+" — model 3's optical flow reworked with a per-block search (instead of per-pixel), a 5×5 window, sub-pixel refinement and true bidirectional flow with occlusion gating, for roughly 2.7× less cost than model 3. Model 3 is kept bit-identical so the two can be compared directly.
- The per-frame present stall is gone. The layer was calling
vkQueueWaitIdleon the compute queue once per presented frame — which, on any GPU exposing a single universal queue family (the normal Adreno layout), was draining the game's own in-flight work, not just the interpolation dispatch. It now waits on the dispatch's own fence.
The present-path fix is from @clintOnSky's #96 — the Xiaomi half of that PR shipped in pre2, this is the other half. Thank you.
✅ Tested and verified working — but still experimental
Frame generation runs, the models switch live, and the present-path fix is in. That is not the same as it being finished. bionic-fg remains experimental, work-in-progress and quirky — expect odd behaviour in places, particularly around interactions with the FPS limiter and in fast motion.
FSR3 and FSR3+ are still unproven for image quality specifically. The published FSR3 numbers were measured while parked, which is a fair cost measurement and a worthless quality one. Fast lateral motion and occlusion edges are exactly where they might fall apart — that's the test that's still wanted, and the most useful thing you can report back.
📦 Also
- GameNative wrapper 20260723 bundled.
- Fixed a crash opening the new-container editor introduced by the refresh work.
🕹️ Virtual controls editor — rebuilt in Compose (in progress)
Unchanged in scope from pre1 and pre2, with the fixes above folded in. The whole on-screen controls editor has been rewritten, replacing the old Fragment/XML settings interface with a Compose one — and a large set of new capabilities along with it.
- New control types — Dynamic Stick, Mouse Area, Button Grid, Expandable Button, and an Android Keyboard control.
- A real editing UI — Compose toolbar, visual control-type picker, and a sliding settings panel that opens automatically when you add an element.
- Per-element tuning — dead zones for Stick / Dynamic Stick / D-Pad, sensitivity, hold bindings, detection-area styling and grid cell shapes.
- Better bindings — category-filtered binding selector, multi-key combos, binding presets, and custom icons.
- Control groups — name a group, toggle its visibility, and move its members together.
- Reference background images with adjustable opacity, so you can lay controls out against a screenshot of the actual game.
- Live in-game profile editing — adjust a profile without leaving the Wine session.
- Versioned ICPx import/export — embedded icons, legacy
.icpcompatibility, validation and atomic writes. - Input hardening — fixes for stuck and conflicting buttons, sticks, and duplicate bindings.
⚠️ This is still the part that most needs testing. It is a very large change to the input system, it is not yet merged, and it has not had a full review. Please exercise your existing control profiles and report anything that regressed — especially profiles created in an older version.
This work is entirely by @arro000 in PR #156, published here as a test build so it can get device coverage before merge. Thank you.
🐞 Known issues
- Occasional ANR ("Bannerlator isn't responding") during input. The UI thread can block on a socket write and stall touch delivery for 5+ seconds. This is pre-existing — it reproduces on 2.8 and earlier — but you may well meet it while testing, so it's listed rather than left as a surprise. Reports with a timestamp are still useful.
- The FPS limiter and frame generation interact badly at low caps. With a cap around 30 and generation on, generated frames get dropped and you end up with fewer frames than you asked for. Understood and being worked on; a cap of 60 behaves correctly. Not a regression from pre2.
- Frame generation is verified working, but bionic-fg as a whole is still experimental / work-in-progress and quirky. Models 1–4 in particular are not quality-proven. Default (model 0) is unchanged from 2.8.
- The refresh-rate unlock needs a current Wine layer. It's verified working, but only on the refreshed Proton 11.0-1 or Proton 10.0-4 layers (both in the in-app downloads). On anything older it stays off by design.
- The virtual controls editor is unmerged, in-progress work. Treat anything it does as provisional.
📥 Downloads
| Variant | File |
|---|---|
| Standard | Bannerlator-2.9-pre3-standard.apk |
| PUBG | Bannerlator-2.9-pre3-pubg.apk |
| Ludashi | Bannerlator-2.9-pre3-ludashi.apk |
ℹ️ On pre1 or pre2 already? Same versionCode, so the in-app updater won't prompt you — download directly from here and install over the top. On 2.8? Turn on "Include pre-releases" in the updater, or sideload. Either way this build is entirely app-side: there's no ImageFS reinstall, and your containers, themes, accent, per-game settings and control colours all carry over.
🙏 Credits
- @arro000 — the entire virtual controls editor rebuild (#156): the Compose editor, the new control types, per-element tuning, control groups, background images, live in-game profile editing and the ICPx format — and, in this build, the custom-icon rendering work, Button Grid multitouch and the per-device controller input fixes.
- @clintOnSky — the frame-gen present-path fix (#96) that removes a per-frame stall on the game's own render queue, following the Xiaomi/HyperOS fix from the same PR that shipped in pre2.
- @Devaspe — continued testing of the pre-release line, and confirming the Xiaomi/HyperOS frame-gen fix on real hardware.
