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.
This commit is contained in:
@@ -13,10 +13,12 @@ mod constants;
|
|||||||
mod cursor;
|
mod cursor;
|
||||||
mod entities;
|
mod entities;
|
||||||
mod game;
|
mod game;
|
||||||
|
mod system_info;
|
||||||
mod world;
|
mod world;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let game_config = config::GameConfig::load();
|
let game_config = config::GameConfig::load();
|
||||||
|
system_info::print_system_info(&game_config);
|
||||||
|
|
||||||
App::new()
|
App::new()
|
||||||
.insert_resource(game_config)
|
.insert_resource(game_config)
|
||||||
@@ -29,6 +31,7 @@ fn main() {
|
|||||||
.set(WindowPlugin {
|
.set(WindowPlugin {
|
||||||
primary_window: Some(Window {
|
primary_window: Some(Window {
|
||||||
title: String::from("Dorf"),
|
title: String::from("Dorf"),
|
||||||
|
present_mode: bevy::window::PresentMode::Mailbox,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|||||||
@@ -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!("{:─<width$}", "", width = line_width);
|
||||||
|
|
||||||
|
println!();
|
||||||
|
println!("╔═{hline}═╗");
|
||||||
|
println!("║{:^width$}║", "DORF SYSTEM", width = line_width + 2);
|
||||||
|
println!("╠═{hline}═╣");
|
||||||
|
println!("║ OS: {:<width$}║", os, width = line_width);
|
||||||
|
println!("║ CPU: {:<width$}║", cpu, width = line_width);
|
||||||
|
println!("║ GPU: {:<width$}║", gpu, width = line_width);
|
||||||
|
println!(
|
||||||
|
"║ RAM: {:<width$}║",
|
||||||
|
format!("{} GB ({} GB free)", ram_total, ram_free),
|
||||||
|
width = line_width
|
||||||
|
);
|
||||||
|
println!("║ Display: {:<width$}║", display, width = line_width);
|
||||||
|
println!(
|
||||||
|
"║ Radius: {:<width$}║",
|
||||||
|
format!("{} chunks", radius),
|
||||||
|
width = line_width
|
||||||
|
);
|
||||||
|
println!("║ Seed: {:<width$}║", seed, width = line_width);
|
||||||
|
println!("╚═{hline}═╝");
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cpu_info() -> 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::<usize>().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::<u64>().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",
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user