diff --git a/Cargo.lock b/Cargo.lock index 6ad2c11..c449041 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,6 +102,7 @@ version = "0.1.0" dependencies = [ "anyhow", "clap", + "rand", "serde", "serde_json", "thiserror", @@ -116,6 +117,17 @@ dependencies = [ "instant", ] +[[package]] +name = "getrandom" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "hashbrown" version = "0.11.2" @@ -186,6 +198,12 @@ version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -228,6 +246,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + [[package]] name = "redox_syscall" version = "0.2.13" @@ -361,6 +409,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 636360e..aee92b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [workspace] members = [ - "enemize", - "bin_comp", "base_patch_generator", + "bin_comp", + "enemize", ] diff --git a/enemize/Cargo.toml b/enemize/Cargo.toml index 8becd9b..a763a91 100644 --- a/enemize/Cargo.toml +++ b/enemize/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] anyhow = "1" clap = { version = "3.1.18", features = ["derive"] } +rand = "0.8" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1" diff --git a/enemize/src/main.rs b/enemize/src/main.rs index f032483..ea0f310 100644 --- a/enemize/src/main.rs +++ b/enemize/src/main.rs @@ -1,7 +1,13 @@ -use std::path::PathBuf; +use std::fs::File; +use std::io::prelude::*; +use std::path::{Path, PathBuf}; +use std::time::Instant; +use anyhow::ensure; use clap::Parser; +use enemize::{asar, rom::RomData}; + /// Randomizes enemy placements in The Legend of Zelda: A Link to the Past for the Super Nintendo /// Entertainment System #[derive(Debug, Parser)] @@ -12,12 +18,6 @@ struct Args { /// seed number #[clap(short, long)] seed: Option, - /// path to the base2patched.json (not used in binary mode) - #[clap(short, long, required_unless_present = "binary")] - base: Option, - /// path to the randomizerPatch.json (not used in binary mode) - #[clap(short, long, required_unless_present = "binary")] - randomizer: Option, /// path to the enemizerOptions.json #[clap(short, long)] enemizer: PathBuf, @@ -28,6 +28,53 @@ struct Args { binary: bool, } -fn main() { +fn main() -> anyhow::Result<()> { let args = Args::parse(); + + let stopwatch = Instant::now(); + + let options = serde_json::from_reader(File::open(args.enemizer)?)?; + let symbols = load_symbols(&args.rom)?; + + let mut raw_data = vec![]; + let mut rom_file = File::open(args.rom)?; + rom_file.read_to_end(&mut raw_data)?; + + raw_data.resize(2 * 1024 * 1024, 0); + + let mut rom_data = RomData::new(symbols, raw_data); + ensure!(!rom_data.is_enemizer(), "It appears that the provided base ROM is already enemized. Please ensure you are using an original game ROM."); + + let seed = args.seed.unwrap_or_else(|| rand::random()); + + //let randomized_rom = randomize_rom(seed, raw_data, options); + + if args.binary { + + } else { + + } + + println!("Seed generated in: {}ms", stopwatch.elapsed().as_millis()); + + Ok(()) +} + +fn load_symbols(rom: &Path) -> anyhow::Result { + let sym_path = rom.with_extension("sym"); + + if let Err(_) = std::fs::metadata(&sym_path) { + let status = std::process::Command::new("asar") + .arg("--no-title-check") + .arg("--fix-checksum=off") + .arg("--symbols=wla") + .arg("-Iassembly/src") + .arg("assembly/src/main.asm") + .arg(rom) + .status()?; + + ensure!(status.success(), "could not generate symbols"); + } + + asar::load_symbols(sym_path.as_path()) }