1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-06-30 03:37:45 +00:00
kawari/build.rs
Joshua Goins 6ecdae840c Continue parsing when encountering unknown packets
This reads the unknown packet data, just throwing it in a byte
buffer. This allows us to read the rest of the segmenets in
the packet, and fixes parsing.

Note that this still log spams with "wrong size" as we can't
determine the size of the unknown packet ahead of time. This is
easy to fix, but it's not a high priority yet.

Fixes #73
2025-06-28 08:48:59 -04:00

88 lines
3.3 KiB
Rust

use std::path::PathBuf;
use serde_json::Value;
fn main() {
// Add link search directory for Oodle
println!("cargo:rustc-link-search=./oodle");
// Generate IPC opcodes
{
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
d.push("resources/opcodes.json");
println!("cargo::rerun-if-changed={}", d.to_str().unwrap());
let mut output_str = "use binrw::binrw;\n".to_string();
let opcodes_buffer = std::fs::read_to_string(d).unwrap();
let json: Value = serde_json::from_str(&opcodes_buffer).unwrap();
for element in json.as_object().unwrap() {
let key = element.0;
let opcodes = element.1.as_array().unwrap();
if !opcodes.is_empty() {
// beginning
output_str.push_str("#[binrw]\n");
output_str.push_str("#[derive(Clone, PartialEq, Debug)]\n");
output_str.push_str(&format!("pub enum {key} {{\n"));
for opcode in opcodes {
let opcode = opcode.as_object().unwrap();
let name = opcode.get("name").unwrap().as_str().unwrap();
let opcode = opcode.get("opcode").unwrap().as_number().unwrap();
output_str.push_str(&format!("#[brw(magic = {opcode}u16)]\n"));
output_str.push_str(&format!("{name},\n"));
}
output_str.push_str(&format!("Unknown(u16),\n"));
// end
output_str.push_str("}\n\n");
output_str.push_str(&format!("impl {key} {{\n"));
// sizes
output_str.push_str("/// Returns the expected size of the data segment of this IPC opcode, _without_ any headers.\n");
output_str.push_str("pub fn calc_size(&self) -> u32 {\n");
output_str.push_str("match self {\n");
for opcode in opcodes {
let opcode = opcode.as_object().unwrap();
let name = opcode.get("name").unwrap().as_str().unwrap();
let size = opcode.get("size").unwrap().as_number().unwrap();
output_str.push_str(&format!("{key}::{name} => {size},\n"));
}
output_str.push_str(&format!("{key}::Unknown(_) => 0,\n"));
output_str.push_str("}\n\n");
output_str.push_str("}\n\n");
// names
output_str.push_str("/// Returns a human-readable name of the opcode.\n");
output_str.push_str("pub fn get_name(&self) -> &'static str {\n");
output_str.push_str("match self {\n");
for opcode in opcodes {
let opcode = opcode.as_object().unwrap();
let name = opcode.get("name").unwrap().as_str().unwrap();
output_str.push_str(&format!("{key}::{name} => \"{name}\",\n"));
}
output_str.push_str(&format!("{key}::Unknown(_) => \"Unknown\",\n"));
output_str.push_str("}\n\n");
output_str.push_str("}\n\n");
// end impl
output_str.push_str("}\n\n");
}
}
std::fs::write("src/opcodes.rs", output_str).expect("Failed to write opcodes file!");
}
}