mirror of
https://github.com/spoopyghosty0/frameport.git
synced 2026-10-29 04:02:45 +01:00
Scared By Squares (Unreal 4.27, OpenXR) creates two actions named "turn"
(an action mapping and an axis mapping called Turn). The Frame's runtime
accepts the duplicate, then vrserver fails to load the input manifest it
builds ("SetXrInputConfig failed. Failed to load manifest"), drops the
app's connection and treats it as exited: black, then the home environment
while the game keeps running with sound. Headless the app reconnected as a
plain OpenXR instance, got throttled to 10 fps and the compositor received
no presents.
- action_dedup (adapter setting, default on): a later duplicate action name
or localized name in a set is created as "<name>_N" / "<Localized> N"
(native/adapter/action_names.h, host-tested). Headless on the dev Frame:
manifest loads, 72 fps, 2808 presents in 45 s (before: 10 fps, none).
- input_diag logs every action set and action (escaped names).
- force_render (hidden diagnostic): xrWaitFrame reports shouldRender=TRUE so
headless runs exercise engines that skip layers when not visible; FrameBridge
logs shouldRender changes.
- Triage: space-warp-used only on the motion-vector swapchain (format 97);
D24S8 (129) eye depth falsely matched. New info finding duplicate-action-renamed.
- Catalog entry (status unknown, min_app 1.2.1), PLAYBOOK row.
36 lines
1.9 KiB
C
36 lines
1.9 KiB
C
// SPDX-License-Identifier: GPL-3.0-only
|
|
// action_dedup (session_fixes.c, GitHub #323): a free name for a controller action whose name or localized name is
|
|
// already used in its action set. No OpenXR types, so the host tests can compile it.
|
|
#pragma once
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
static size_t action_name_len(const char *s, size_t max) { // strnlen (not in plain C11)
|
|
size_t n = 0;
|
|
while (n < max && s[n]) ++n;
|
|
return n;
|
|
}
|
|
|
|
// taken(ctx, name, localized): 1 when `name` or `localized` is already used in the set.
|
|
typedef int (*action_name_taken_fn)(void *ctx, const char *name, const char *localized);
|
|
|
|
// Writes "<name>_N" / "<localized> N" (N = 2..99, the first pair not taken; cut to fit name_size/localized_size
|
|
// including the terminator) and returns 1; 0 when the original names are free or no free pair exists.
|
|
static int action_unique_names(const char *name, const char *localized, action_name_taken_fn taken, void *ctx,
|
|
char *out_name, size_t name_size, char *out_localized, size_t localized_size) {
|
|
if (!taken(ctx, name, localized) || name_size < 8 || localized_size < 8) return 0;
|
|
for (int n = 2; n < 100; ++n) {
|
|
char suffix[8], lsuffix[8];
|
|
snprintf(suffix, sizeof(suffix), "_%d", n);
|
|
snprintf(lsuffix, sizeof(lsuffix), " %d", n);
|
|
size_t keep = action_name_len(name, name_size - 1);
|
|
if (keep + strlen(suffix) > name_size - 1) keep = name_size - 1 - strlen(suffix);
|
|
snprintf(out_name, name_size, "%.*s%s", (int)keep, name, suffix);
|
|
size_t lkeep = action_name_len(localized, localized_size - 1);
|
|
if (lkeep + strlen(lsuffix) > localized_size - 1) lkeep = localized_size - 1 - strlen(lsuffix);
|
|
snprintf(out_localized, localized_size, "%.*s%s", (int)lkeep, localized, lsuffix);
|
|
if (!taken(ctx, out_name, out_localized)) return 1;
|
|
}
|
|
return 0;
|
|
}
|