use std::env; use std::fs; use std::process::Command; 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 distro = distro_info(); let kernel = kernel_info(); let cpu = cpu_info(); let gpu = gpu_info(); let (ram_total, ram_free) = mem_info(); let (res, hz) = display_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", VsyncMode::Uncapped => "uncapped", } } fn distro_info() -> String { #[cfg(target_os = "linux")] { if let Ok(content) = fs::read_to_string("/etc/os-release") { let pretty_name = content .lines() .find(|l| l.starts_with("PRETTY_NAME=")) .and_then(|l| l.split('=').nth(1)) .map(|s| s.trim_matches('"').to_string()); if let Some(name) = pretty_name { return name; } } String::from("Unknown distro") } #[cfg(not(target_os = "linux"))] { String::from("N/A") } } fn kernel_info() -> String { #[cfg(target_os = "linux")] { if let Ok(output) = Command::new("uname").arg("-r").output() { if let Ok(kernel) = String::from_utf8(output.stdout) { return kernel.trim().to_string(); } } String::from("Unknown kernel") } #[cfg(not(target_os = "linux"))] { String::from("N/A") } } fn display_info() -> (String, String) { #[cfg(target_os = "linux")] { if let Ok(output) = Command::new("xrandr").output() { if let Ok(xr) = String::from_utf8(output.stdout) { let lines: Vec<&str> = xr.lines().collect(); if let Some(current) = lines.iter().find(|l| l.contains("+*")) { let parts: Vec<&str> = current.split_whitespace().collect(); let res = parts.get(0).unwrap_or(&"unknown"); let mut hz = String::from("60"); for part in &parts[1..] { if part.ends_with("Hz") || part.parse::().is_ok() { hz = part .trim_end_matches("Hz*") .trim_end_matches("Hz") .to_string(); break; } } return (res.to_string(), hz); } } } } #[cfg(not(target_os = "linux"))] return (String::from("N/A"), String::from("N/A")); (String::from("unknown"), String::from("?")) }