WinNative is a community project built on other people’s work. This page is the full attribution for everything WinNative is built from, including the parts we did not write. Per-component license tables for the retro-console and emulator side live in EMULATOR_CREDITS.md.
WinNative is distributed under the GNU General Public License v3.0 (LICENSE). Copyright and license notices are preserved in every file that carries upstream work, and the corresponding source for every copyleft component is available from the projects linked here.
app/src/main/cpp/waylandcomp),
its Wayland runtime design, clipboard and IME bridges, and the winewayland launch path by
Banner (The412Banner) from
Bannerlator, ported to WinNative; ships the
vendored libwayland-server 1.26 and libffi from the same project. See
docs/WAYLAND-DISPLAY.md.libemucore. PS2 online play uses PCSX2’s DEV9 network adapterDISOpticalFlow,
LICENSE), which adopted Till Kroeger’s
original OF_DIScalcOpticalFlowFarneback (optflowgf.cpp,
LICENSE)dxbc shader translator, vendored at app/src/main/cpp/thirdparty/dxbc to convert the
frame generation shaders to SPIR-VWinNative’s frame generation exists because Camille LaVey, working in the Eden Emulator Project, had already solved the hard part: getting the Lossless Scaling compute chain running correctly on Vulkan, on mobile GPUs. The port here started from that work and still carries it. The Eden Emulator Project copyright notices are preserved in every file that derives from it, under GPL-3.0-or-later.
Derived from Camille LaVey’s Eden port (jointly with lsfg-vk, which that port was in turn ported from):
| Source file | What it provides |
|---|---|
lsfg_chain.* |
The shape of the whole chain — which of the 25 shaders run, in what order, and what each stage feeds the next |
lsfg_mipmaps.* |
The flow pyramid the rest of the chain is built on |
lsfg_alpha.* |
Per-level feature extraction, including the batched-barrier dispatch pattern the rest of the chain follows |
lsfg_beta.* |
The coarse flow estimate the refinement stages start from |
lsfg_gamma.* |
Coarse-to-fine flow refinement, one instance per pyramid level |
lsfg_delta.* |
The extra refinement and detail passes on the finest levels |
lsfg_generate.* |
The final warp that produces the interpolated frame |
lsfg_common.* |
The Vulkan plumbing all of the above sit on — image, sampler and buffer wrappers, the barrier builder, the descriptor writer, and the pass/pipeline helper |
Derived from the Eden port specifically:
| Source file | What it provides |
|---|---|
lsfg_pacer.* |
Deciding how many frames to generate per real frame |
lsfg_shaders.* |
Turning the extracted shader blobs into Vulkan shader modules |
Getting the descriptor layouts, barrier placement and dispatch geometry of a 25-shader chain right is not something you arrive at by reading the shaders; it is the part that takes the debugging. Camille LaVey did that work, and this port would not have been possible without it.
What WinNative added on top is the Windows and Android side of it: reading the shader blobs out
of a user’s own Lossless Scaling install (lsfg_dll.*), translating them when only DXBC is
available (lsfg_dxbc.*), the JNI surface (lsfg_jni.*), driver probing (lsfg_probe.*), and
wiring the chain into WinNative’s compositor and swapchain (vkr_lsfg.*).
WinNative’s second frame generator is a complete open-source implementation of Dense Inverse
Search optical flow, contributed by qwertypower (DEVAR Entertainment LLC) under the MIT
license (app/src/main/cpp/wfg/LICENSE); the rest of WinNative, including the compositor code that
calls it, stays GPL-3.0.
Unlike the Lossless Scaling path it depends on nothing the user has to own or install. The whole
chain ships with the APK as twenty-two compute shaders and runs in the same Vulkan compositor, so
frame generation is available on a fresh install with no Steam account and no Lossless.dll.
The flow estimator is a hybrid of two published methods. The fine levels are DIS, whose reference
implementation is OpenCV’s DISOpticalFlow
(OpenCV LICENSE). OpenCV in turn adopted
Till Kroeger’s original OF_DIS. The coarse levels are
Gunnar Farnebäck’s polynomial-expansion flow, ported from OpenCV’s calcOpticalFlowFarneback.
What is original here, by qwertypower, is the Vulkan compute realisation of both and the hybrid
itself — the pyramid, the descriptor and barrier layout, the sparse-to-dense step, the
interpolation (occlusion handling, forward splatting, acceleration) and the pacing — built to run
inside a mobile compositor at frame rate.
| Stage | Shaders |
|---|---|
| Luminance pyramid and gradients | dis_luma_r16, dis_luma_r32, dis_gradient |
| Farneback on the coarse levels | dis_fb_poly, dis_fb_hsum, dis_fb_vsolve |
| Patch inverse search on the fine levels | dis_inverse_search, dis_propagate |
| Sparse grid to dense flow | dis_densify |
| Variational refinement | dis_vr_prep, dis_vr_d1, dis_vr_d2, dis_vr_w, dis_vr_coef, dis_vr_sor, dis_vr_add |
| Packed field, occlusion fill, acceleration | dis_flow_pack, dis_fill |
| Overlay history, occlusion side, splat | dis_hist, dis_side, dis_splat |
| Warp to the in-between frame | dis_interpolate |
The engine sits behind its own settings — a Fast / Balance flow resolution and an optional target frame rate — kept separate from the Lossless Scaling ones, and the two engines are mutually exclusive because the compositor drives one interpolator per frame.
WinNative’s microphone support exists because The412Banner wrote DirectAudio, a native Wine → Android AAudio mmdevapi driver, and then completed its capture half. Nothing in that driver is WinNative’s work. We ship his release binaries unmodified and add only the host-side plumbing that selects and configures them.
Wine has no AAudio backend upstream. DirectAudio is an original driver whose structure is
modelled on Wine’s winecoreaudio.drv, with the CoreAudio device layer replaced by Android
AAudio — no PulseAudio daemon and no ALSA server anywhere in the path. That is also the reason
it is the only one of WinNative’s three audio stacks that can carry a microphone at all: the
ALSA aserver protocol has no capture verb (its guest plugin refuses a non-playback PCM
outright), and the bundled PulseAudio ships no source module, so any capture endpoint winepulse
advertises would record silence.
| Component | What it provides |
|---|---|
winedirectaudio.drv (arm64ec + i386 PE) |
The mmdevapi driver the guest game loads |
winedirectaudio.so (bionic unixlib) |
The AAudio backend both PE halves share |
| Render mixer | One shared AAudio output stream, per-voice mixing, adaptive buffering with decay, and a dead-callback watchdog |
| Capture path (v1.3.2) | One shared AAudio INPUT stream (48 kHz / float / stereo, VOICE_COMMUNICATION preset for platform echo-cancel, noise-suppress and auto-gain), opened lazily on the first capture stream and started only on the first Start |
What WinNative added is only the host half: picking the driver build that matches the
container’s Wine ABI and the device’s kernel page size, overlaying the three files onto the
Proton layer, writing the Wine registry key that selects the driver, requesting RECORD_AUDIO,
and exposing the microphone opt-in per container and per shortcut.
The microphone is off by default and per-container, which is the driver’s own design rather
than caution on our part: a capture endpoint a game can enumerate but not open makes titles that
probe the microphone while loading abandon audio init and boot to a black screen (God of War and
DiRT 3, device-proven upstream). With the gate off the driver is byte-identical to its
render-only build. WinNative additionally withholds the gate when RECORD_AUDIO has not been
granted, so a denied permission degrades to render-only rather than to an unopenable endpoint.
DirectAudio is licensed LGPL-2.1-or-later and remains so. The bundled binaries, their
checksums, the upstream source offer and the verbatim COPYING, NOTICE and AUTHORS files
live in app/src/main/assets/directaudio/. Integration
notes are in docs/direct-audio-integration.md.
DirectAudio by The412Banner (https://github.com/The412Banner/directaudio)
WinNative’s Steam Controller support, the animated controller test panel and the tap-the-pad
visual binder are The412Banner’s work, written for
Bannerlator and ported here. The design, the
SDL3 bridge, the input model, the pad artwork and the hotspot manifest are all his; WinNative’s
own part is the adaptation to this fork’s input plumbing (WinHandler’s slot machinery, the
InputControlsView binding lane and the Compose settings screen) plus full localization.
Out of the box a Steam Controller is not a gamepad: it presents as a keyboard and mouse
(“lizard mode”), so Android never reports a controller and WinNative’s normal InputDevice path
cannot see it. SDL3’s HIDAPI Steam drivers speak Valve’s protocol instead — over Bluetooth LE or
USB — keep lizard mode off and parse the reports. Only those drivers are enabled
(SDL_HINT_JOYSTICK_HIDAPI=0, SDL_HINT_JOYSTICK_HIDAPI_STEAM=1), so SDL never opens, claims or
requests USB permission for any other controller, and every non-Valve pad keeps the untouched
Android input path.
| Piece | What it does |
|---|---|
steamctrl/steam_controller_bridge.cpp |
JNI bridge over SDL3’s gamepad API: flat int/float arrays for up to four Valve HIDAPI pads, plus rumble |
SteamControllerBackend |
~250 Hz poll thread, ordered frame delivery onto the main thread, the 22-bit button model, trackpad-as-mouse and the back-paddle / “…” bindings |
WinHandler SDL pads |
Seats each pad in the ordinary player-slot machinery under a synthetic device id, shadows the Valve device Android also exposes, and routes rumble back through SDL |
ControllerTestPanel |
The animated pad picture: live button glow, movable stick nubs that glow with deflection, trigger and battery readouts, and the per-device inputs-verified tally, including paddles and touchpads |
VisualControllerBinder |
Tap a button on the pad art to rebind it, written into the same profile store the list editor uses |
pad_*.png |
The per-family controller artwork (Xbox 360 / Xbox / DualSense / DualShock 4 / DualShock 3 / Switch Pro / 8BitDo / GameCube / SNES / Steam / Generic) |
Support is off by default and lives in Settings → Input Controls → Steam Controller. While it is off, SDL is never loaded and the normal controller path is byte-for-byte unchanged.
Credit history — every commit below is The412Banner’s, in The412Banner/Bannerlator:
| Commit | Date | Subject |
|---|---|---|
9ca9bcf |
2026-08-31 | Controller Test: reuse the visualizer in Settings > Input Controls |
d32a03f |
2026-08-31 | Controller Test: accurate per-family pad art + smaller in-game popup |
1678f23 |
2026-08-31 | Controller Test: bound the pad picture to a compact size |
4344ef4 |
2026-08-31 | Visual controller binder: tap the pad to remap, in Settings + in-game |
475721e |
2026-08-31 | Controller pads: pre-rendered PNG art + overlay; Settings test-first; fix live-input arm |
8d2e1e3 |
2026-08-31 | Controller test: movable stick nubs + pinned footer (Identify never clips) |
90a8286 |
2026-08-31 | Controller test: stick nubs glow on deflection + landscape pad-left / metrics-right |
1e0d46f |
2026-08-31 | Controller test: landscape metrics as a 2x2 grid so all four tiles fit |
9722956 |
2026-08-31 | feat(controller-test): independent OSC/physical profile lanes + live profile lists |
095269d |
2026-08-31 | Bind screen: add Delete profile + outline/dividers on menus and popup |
b02d981 |
2026-08-31 | Controller test: unify popup-menu styling on outlinedMenuCard; rename Settings card |
b9e6552 |
2026-09-10 | Steam Controller support via SDL3 (opt-in, Input Controls > Device) |
e5b1272 |
2026-09-10 | Steam Controller: fetch pad name/path on the poll thread |
6d3b2a7 |
2026-09-10 | Steam Controller: back buttons, profile bindings, settings test dialog |
d03f6b1 |
2026-09-10 | Steam Controller: make the “…” (Quick Access) button mappable |
3d243e4 |
2026-09-10 | Controller test: count the Steam Controller’s “…” button (18 inputs) |
b597711 |
2026-09-10 | Steam Controller: pick which trackpad moves the mouse (right / left / both / off) |
c2acbbd |
2026-09-10 | Merge branch ‘feat/steam-controller-sdl’: opt-in Steam Controller support via SDL3 |
Bannerlator is GPL-3.0, the same license as WinNative, and remains so. SDL3 is Zlib-licensed and
uses a separate Java/JNI namespace and native library for this integration, with a Bluetooth transport patch; see vendor/maven/README.md and
EMULATOR_CREDITS.md.
Steam Controller support, controller test and visual binder by The412Banner (https://github.com/The412Banner/Bannerlator)