Merge remote-tracking branch 'origin/main' into audio/latency-overhaul
ci / bun-nix (pull_request) Successful in 33s
ci / web (pull_request) Successful in 1m9s
ci / docs-site (pull_request) Successful in 1m21s
apple / swift (pull_request) Successful in 1m33s
apple / screenshots (pull_request) Skipped
ci / rust-arm64 (pull_request) Successful in 2m13s
windows / build (x86_64-pc-windows-msvc) (pull_request) Successful in 2m36s
windows / build (aarch64-pc-windows-msvc) (pull_request) Successful in 1m9s
android / android (pull_request) Successful in 7m53s
ci / rust (pull_request) Successful in 12m23s

This commit is contained in:
2026-08-08 00:16:02 +02:00
93 changed files with 4799 additions and 527 deletions
@@ -361,6 +361,40 @@ pub extern "system" fn Java_io_unom_punktfunk_kit_NativeBridge_nativeSendGamepad
);
}
/// `NativeBridge.nativePadMotionReaches(handle, declaredPref)` — whether motion sent for a pad that
/// declared `declaredPref` (the `GamepadPref` wire byte it passed to `nativeSendGamepadArrival`) can
/// actually reach the game, or would be decoded and dropped by a host backend with no motion plane.
///
/// The whole question is answered here rather than in Kotlin so the reasoning lives in exactly one
/// place — [`punktfunk_core::config::pad_motion_reaches`], which carries the argument and the tests.
/// A third transcription of it would be a third thing to get subtly wrong, and every way of getting
/// it wrong is silent: too strict kills a working gyro, too lax keeps ~250 Hz of samples flowing
/// into a host that drops every one.
///
/// A `0` handle answers `true` — "don't suppress" is the safe answer when we cannot tell, matching
/// the `Auto` rule inside the predicate itself.
#[no_mangle]
pub extern "system" fn Java_io_unom_punktfunk_kit_NativeBridge_nativePadMotionReaches(
_env: JNIEnv,
_this: JObject,
handle: jlong,
declared_pref: jint,
) -> jboolean {
if handle == 0 {
return 1;
}
// SAFETY: live handle per the nativeConnect/nativeClose contract; both fields are plain Copy
// values read behind `&self`.
let h = unsafe { &*(handle as *const SessionHandle) };
let declared =
punktfunk_core::config::GamepadPref::from_u8(declared_pref.clamp(0, u8::MAX as jint) as u8);
u8::from(punktfunk_core::config::pad_motion_reaches(
declared,
h.client.requested_gamepad,
h.client.resolved_gamepad,
))
}
/// `NativeBridge.nativeSendGamepadRemove(handle, pad)` — signal that wire pad index `pad` was
/// unplugged so the host tears its virtual device down. `pad` (rides `flags`) is the only field; the
/// core stamps the per-pad seq (in the snapshot seq space, so a reordered snapshot can't resurrect the