From 06bbc9caa8f65cf275857b71fac470ceba354300 Mon Sep 17 00:00:00 2001 From: popertots Date: Fri, 20 Mar 2026 17:16:54 +0000 Subject: [PATCH] feat: neofetch-style system info dump at startup Prints DORF SYSTEM box to stdout before game loop begins: OS, CPU (model + cores), GPU (WEBGPU_ADAPTER_NAME env var), RAM total + free (from /proc/meminfo), display vsync mode, initial chunk radius, world seed. --- src/main.rs | 3 ++ src/system_info.rs | 118 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 src/system_info.rs diff --git a/src/main.rs b/src/main.rs index ca5e339..d7c9c98 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,10 +13,12 @@ mod constants; mod cursor; mod entities; mod game; +mod system_info; mod world; fn main() { let game_config = config::GameConfig::load(); + system_info::print_system_info(&game_config); App::new() .insert_resource(game_config) @@ -29,6 +31,7 @@ fn main() { .set(WindowPlugin { primary_window: Some(Window { title: String::from("Dorf"), + present_mode: bevy::window::PresentMode::Mailbox, ..Default::default() }), ..Default::default() diff --git a/src/system_info.rs b/src/system_info.rs new file mode 100644 index 0000000..7b67563 --- /dev/null +++ b/src/system_info.rs @@ -0,0 +1,118 @@ +use std::env; +use std::fs; + +use crate::config::{GameConfig, VsyncMode}; +use crate::constants::SEED; + +pub fn print_system_info(config: &GameConfig) { + let os = format!("{} {}", env::consts::OS, env::consts::ARCH); + let cpu = cpu_info(); + let gpu = gpu_info(); + let (ram_total, ram_free) = mem_info(); + let display = vsync_label(&config.display.vsync); + let radius = config.initial_chunk_radius; + let seed = SEED; + + let line_width = 34; + let hline = format!("{:─ String { + #[cfg(target_os = "linux")] + { + let Ok(content) = fs::read_to_string("/proc/cpuinfo") else { + return String::from("Unknown CPU"); + }; + + let model_name = content + .lines() + .find(|l| l.starts_with("model name")) + .and_then(|l| l.split(':').nth(1)) + .map(|s| s.trim().to_string()) + .unwrap_or_else(|| String::from("Unknown CPU")); + + let core_count = content + .lines() + .filter(|l| l.starts_with("processor")) + .count() + .max(1); + + format!("{} ({} cores)", model_name, core_count) + } + + #[cfg(not(target_os = "linux"))] + { + let cores = env::var("NUMBER_OF_PROCESSORS") + .ok() + .and_then(|s| s.parse::().ok()) + .unwrap_or(1); + + format!("Unknown CPU ({} cores)", cores) + } +} + +fn gpu_info() -> String { + env::var("WEBGPU_ADAPTER_NAME").unwrap_or_else(|_| String::from("Unknown GPU")) +} + +fn mem_info() -> (u64, u64) { + #[cfg(target_os = "linux")] + { + let Ok(content) = fs::read_to_string("/proc/meminfo") else { + return (0, 0); + }; + + let parse_kb = |key: &str| -> u64 { + content + .lines() + .find(|l| l.starts_with(key)) + .and_then(|l| { + l.split_whitespace() + .nth(1) + .and_then(|s| s.parse::().ok()) + }) + .unwrap_or(0) + }; + + let total_kb = parse_kb("MemTotal:"); + let available_kb = parse_kb("MemAvailable:"); + let total_gb = total_kb / 1024 / 1024; + let available_gb = available_kb / 1024 / 1024; + (total_gb, available_gb) + } + + #[cfg(not(target_os = "linux"))] + { + (0, 0) + } +} + +fn vsync_label(mode: &VsyncMode) -> &'static str { + match mode { + VsyncMode::Vsync => "vsync", + VsyncMode::Mailbox => "mailbox vsync", + VsyncMode::Uncapped => "uncapped", + } +}