Files
NX2navi/runtime/sysinfo.c
epicmeme546 c84c035939 Remove the co-op of 0.8.0: its runtime layer, relay, menu tab, settings, tests and docs.
The hidden beta shared story progress through a relay a player had to run and never showed the other players. A new co-op replaces it. Gone are runtime/coop*.c and their headers, the menu's Co-op tab and its texts in four languages, tools/coop_relay.py, the co-op tests, docs/coop.md, the [coop] section of nx2navi.ini.example, the --probe-coop mode, the coop trace item, and Monocypher, which only this layer used.

The old settings stay known as retired keys, so an nx2navi.ini that still sets them logs no unknown key, and they stay on the list of private settings, so a bug report keeps a room's secret, a relay's address and a name out. The platform layer's UDP sockets and fs_save_snapshot stay for the new co-op; cfg_ini_now and fs_profile_path, which nothing else called, are removed.

Checked: the game builds and starts, the menu shows its four tabs, --probe-cfg and --probe-fs pass, and the launcher's private-settings test passes. tests/save_share_check.py builds without its co-op stub; it cannot run from this worktree because the folder's path is longer than Windows allows, on main too.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-13 03:37:26 -05:00

99 lines
3.9 KiB
C

// What a bug report needs about the machine (sysinfo.h). The OS calls sit behind platform.h; the GPU and driver come
// from the Vulkan device the game renders on.
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#if defined(__x86_64__) || defined(__i386__)
#include <cpuid.h>
#endif
#include "cfg.h"
#include "cfg_private.h"
#include "host.h"
#include "platform/platform.h"
#include "sysinfo.h"
#include "vk.h"
void sysinfo_cpu_name(char *out, size_t n) {
out[0] = 0;
#if defined(__x86_64__) || defined(__i386__)
unsigned r[12];
if (__get_cpuid_max(0x80000000, NULL) < 0x80000004) return;
for (unsigned i = 0; i < 3; i++) __get_cpuid(0x80000002 + i, &r[i * 4], &r[i * 4 + 1], &r[i * 4 + 2], &r[i * 4 + 3]);
char b[49];
memcpy(b, r, 48);
b[48] = 0;
const char *p = b;
while (*p == ' ') p++;
snprintf(out, n, "%s", p);
for (char *e = out + strlen(out); e > out && e[-1] == ' '; e--) e[-1] = 0;
#endif
}
int sysinfo_log_folder(char *out, size_t n) {
const char *log = rt_log_path();
if (log) snprintf(out, n, "%s", log);
else if (!plat_stderr_path(out, n) && !plat_exe_path(out, n)) return 0;
char *s = strrchr(out, '\\'), *f = strrchr(out, '/');
if (f > s) s = f;
if (!s) return 0;
*s = 0;
return 1;
}
typedef struct { char *buf; size_t n, at; } Out;
static void put(Out *o, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
static void put(Out *o, const char *fmt, ...) {
if (o->at + 1 >= o->n) return;
va_list ap;
va_start(ap, fmt);
int k = vsnprintf(o->buf + o->at, o->n - o->at, fmt, ap);
va_end(ap);
if (k > 0) o->at = o->at + (size_t)k < o->n ? o->at + (size_t)k : o->n - 1;
}
// The private settings (cfg_private.h) stay out of a text that ends up in bug reports: only whether they are set.
static int private_setting(const char *key) { return cfg_private_key(key); } // cfg_private.h: one list for all
static void put_setting(const char *key, const char *value, int from_env, void *ctx) {
if (private_setting(key)) value = CFG_PRIVATE_SHOWN;
put(ctx, from_env ? " NX2NAVI_%s=%s (environment)\n" : " %s = %s\n", key, value);
}
int sysinfo_text(char *buf, size_t n) {
if (!n) return 0;
Out o = {buf, n, 0};
buf[0] = 0;
char s[256];
put(&o, "NX2navi system info\n");
put(&o, "OS: %s\n", plat_os_version(s, sizeof s) ? s : "unknown");
sysinfo_cpu_name(s, sizeof s);
put(&o, "CPU: %s, %u logical processors\n", s[0] ? s : "unknown", plat_cpu_count());
float used, total, proc;
plat_mem_info(&used, &total, &proc);
if (total > 0) put(&o, "RAM: %.1f GB, %.1f GB in use, the game %.1f GB\n", total / 1024, used / 1024, proc / 1024);
VkCtx *c = vk_ctx();
if (c) {
VkPhysicalDeviceDriverProperties dp = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES};
VkPhysicalDeviceProperties2 p2 = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = &dp};
vkGetPhysicalDeviceProperties2(c->phys, &p2);
const VkPhysicalDeviceProperties *p = &p2.properties;
uint64_t vram = 0;
for (uint32_t h = 0; h < c->mem_props.memoryHeapCount; h++)
if (c->mem_props.memoryHeaps[h].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) vram += c->mem_props.memoryHeaps[h].size;
put(&o, "GPU: %s (vendor 0x%04x, device 0x%04x), %.1f GB device-local memory\n", p->deviceName, p->vendorID,
p->deviceID, vram / 1073741824.0);
put(&o, "Driver: %s %s, driver version 0x%08x, Vulkan %u.%u.%u\n", dp.driverName, dp.driverInfo,
p->driverVersion, VK_API_VERSION_MAJOR(p->apiVersion), VK_API_VERSION_MINOR(p->apiVersion),
VK_API_VERSION_PATCH(p->apiVersion));
} else {
put(&o, "GPU: no Vulkan device yet\n");
}
put(&o, "Settings with a value:\n");
size_t before = o.at;
cfg_each_active(put_setting, &o);
if (o.at == before) put(&o, " none\n");
return (int)o.at;
}