-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.rs
More file actions
98 lines (84 loc) · 3.56 KB
/
Copy pathbuild.rs
File metadata and controls
98 lines (84 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader, Write};
use std::path::Path;
use std::collections::HashMap;
fn main() {
// Link X11 library for window title detection on Linux
if cfg!(target_os = "linux") {
println!("cargo:rustc-link-lib=X11");
}
// Generate game database from GameIndex.yaml
println!("cargo:rerun-if-changed=../GameIndex.yaml");
generate_game_database();
}
fn generate_game_database() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("game_database_generated.rs");
// Read GameIndex.yaml
let gameindex_path = "../GameIndex.yaml";
let file = match File::open(gameindex_path) {
Ok(f) => f,
Err(_) => {
println!("cargo:warning=GameIndex.yaml not found, using built-in database");
return;
}
};
let reader = BufReader::new(file);
let mut games: HashMap<String, String> = HashMap::new();
let mut current_id = String::new();
let mut in_game_block = false;
for line in reader.lines() {
let line = line.unwrap();
let trimmed = line.trim();
// Check for game ID (e.g., "SLES-52056:")
if trimmed.len() >= 10 && trimmed.ends_with(':') {
if let Some(dash_pos) = trimmed.find('-') {
if dash_pos == 4 || dash_pos == 5 { // SLES-12345 or SCUS-12345
current_id = trimmed.trim_end_matches(':').to_string();
in_game_block = true;
}
}
} else if in_game_block && trimmed.starts_with("name:") {
// Extract game name
let name = trimmed[5..].trim();
// Remove quotes if present
let name = name.trim_matches('"');
if !games.contains_key(¤t_id) {
games.insert(current_id.clone(), name.to_string());
}
} else if in_game_block && trimmed.starts_with("name-en:") {
// Use English name if available (overwrites Japanese name)
let name = trimmed[8..].trim();
let name = name.trim_matches('"');
games.insert(current_id.clone(), name.to_string());
} else if trimmed.is_empty() || trimmed.starts_with('#') {
in_game_block = false;
}
}
// Generate Rust code
let mut output = File::create(&dest_path).unwrap();
writeln!(output, "// Auto-generated from GameIndex.yaml").unwrap();
writeln!(output, "// Total games: {}", games.len()).unwrap();
writeln!(output).unwrap();
writeln!(output, "use std::collections::HashMap;").unwrap();
writeln!(output, "use once_cell::sync::Lazy;").unwrap();
writeln!(output).unwrap();
writeln!(output, "pub static GAME_DATABASE_GENERATED: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| {{").unwrap();
writeln!(output, " let mut db = HashMap::new();").unwrap();
writeln!(output).unwrap();
// Sort games by ID for consistent output
let mut sorted_games: Vec<_> = games.iter().collect();
sorted_games.sort_by_key(|a| a.0);
for (id, name) in sorted_games {
// Escape the game name for Rust string literal
let escaped_name = name
.replace('\\', "\\\\")
.replace('"', "\\\"");
writeln!(output, " db.insert(\"{id}\", \"{escaped_name}\");").unwrap();
}
writeln!(output).unwrap();
writeln!(output, " db").unwrap();
writeln!(output, "}});").unwrap();
println!("cargo:warning=Generated game database with {} games", games.len());
}