diff --git a/base_patch_generator/src/main.rs b/base_patch_generator/src/main.rs index 9d47946..f3412d3 100644 --- a/base_patch_generator/src/main.rs +++ b/base_patch_generator/src/main.rs @@ -36,10 +36,7 @@ fn main() -> Result<(), anyhow::Error> { rom_bytes.resize(4 * 1024 * 1024, 0); - let mut symbols_file = File::open(&symbols_path)?; - let mut symbols_text = String::new(); - symbols_file.read_to_string(&mut symbols_text)?; - let symbols = asar::load_symbols(&symbols_text)?; + let symbols = asar::load_symbols(Path::new(&symbols_path))?; let mut rom = RomData::new(symbols, rom_bytes); diff --git a/enemize/src/asar.rs b/enemize/src/asar.rs index 6a34cd0..b4afba8 100644 --- a/enemize/src/asar.rs +++ b/enemize/src/asar.rs @@ -1,34 +1,43 @@ use std::collections::HashMap; +use std::fs::File; +use std::io::{BufRead, BufReader}; +use std::path::Path; pub type Symbols = HashMap; -pub fn load_symbols(contents: &str) -> anyhow::Result { - let symbols = contents +pub fn load_symbols(filename: &Path) -> anyhow::Result { + let file = File::open(filename)?; + let reader = BufReader::new(file); + + let symbols = reader .lines() - .filter_map(|line| { - let mut words = line.split_ascii_whitespace(); - match (words.next(), words.next(), words.next()) { - // Get only two-word lines. - (Some(address), Some(symbol), None) => { - Some((symbol.to_owned(), address.to_owned())) - } + .filter_map(|l| { + l.ok() + .and_then(|line| { + let mut words = line.split_ascii_whitespace(); + match (words.next(), words.next(), words.next()) { + // Get only two-word lines. + (Some(address), Some(symbol), None) => { + Some((symbol.to_owned(), address.to_owned())) + } - _ => None, - } + _ => None, + } + }) + .and_then(|(symbol, mut address)| { + if let Some(colon_at) = address.find(':') { + address.remove(colon_at); + } + + // Filter out the ones that don't have a hexadecimal number as the first word. + let snes_address = u32::from_str_radix(&address, 16).ok()?; + + let pc_address = snes_to_pc_address(snes_address); + + Some((symbol, pc_address)) + }) }) - .filter_map(|(symbol, mut address)| { - if let Some(colon_at) = address.find(':') { - address.remove(colon_at); - } - - // Filter out the ones that don't have a hexadecimal number as the first word. - let snes_address = u32::from_str_radix(&address, 16).ok()?; - - let pc_address = snes_to_pc_address(snes_address); - - Some((symbol, pc_address)) - }) - .collect(); + .collect(); Ok(symbols) } diff --git a/enemize/src/lib.rs b/enemize/src/lib.rs index a499767..63e07af 100644 --- a/enemize/src/lib.rs +++ b/enemize/src/lib.rs @@ -19,13 +19,11 @@ pub mod rom; pub struct InvalidEnumError(PhantomData); #[derive(Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] pub struct Patch { pub address: usize, pub patch_data: Vec, } -#[derive(Default)] pub struct PatchSet { filename: PathBuf, patches: Vec, diff --git a/enemize/src/main.rs b/enemize/src/main.rs index fcb4f5e..17da211 100644 --- a/enemize/src/main.rs +++ b/enemize/src/main.rs @@ -1,15 +1,15 @@ use std::fs::File; use std::io::prelude::*; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::time::Instant; -use anyhow::ensure; +use anyhow::{bail, ensure}; use clap::Parser; use enemize::{asar, rom::RomData}; -const ASAR_SYMBOLS: &'static str = include_str!("../../asar_symbols.txt"); -const ENEMIZER_BASE_PATCH: &'static str = include_str!("../../enemizer_base_patch.json"); +const ASAR_SYMBOLS: &'static str = "asar_symbols.txt"; +const ENEMIZER_BASE_PATCH: &'static str = "enemizer_base_patch.json"; /// Randomizes enemy placements in The Legend of Zelda: A Link to the Past for the Super Nintendo /// Entertainment System @@ -65,7 +65,7 @@ fn main() -> anyhow::Result<()> { // (That is, 2 out of 2 billion instead of 1.) let seed = args.seed.unwrap_or_else(|| rand::random()).saturating_abs(); - rom.randomize(ENEMIZER_BASE_PATCH, options, seed)?; + rom.randomize(Path::new(ENEMIZER_BASE_PATCH), options, seed)?; let mut out_file = File::create(&args.output)?; @@ -84,5 +84,12 @@ fn main() -> anyhow::Result<()> { } fn load_symbols() -> anyhow::Result { - asar::load_symbols(ASAR_SYMBOLS) + if let Err(_) = std::fs::metadata(ASAR_SYMBOLS) { + bail!( + "Could not find symbols at {}. Did you run prepare.sh?", + ASAR_SYMBOLS + ); + } + + asar::load_symbols(Path::new(ASAR_SYMBOLS)) } diff --git a/enemize/src/randomize.rs b/enemize/src/randomize.rs index a42438e..4fe78ae 100644 --- a/enemize/src/randomize.rs +++ b/enemize/src/randomize.rs @@ -1,13 +1,15 @@ +use std::path::Path; + use anyhow::ensure; use crate::option_flags::OptionFlags; use crate::rom::RomData; -use crate::{Patch, PatchSet}; +use crate::PatchSet; impl RomData { pub fn randomize( &mut self, - base_patch: &str, + base_patch: &Path, option_flags: OptionFlags, seed: i32, ) -> anyhow::Result<()> { @@ -27,11 +29,8 @@ impl RomData { self.expand_rom(); self.set_info_flags(option_flags)?; - let patches: Vec = serde_json::from_str(base_patch)?; - - let mut patch_set = PatchSet::default(); - patch_set.add_patches(patches); - patch_set.patch_rom(self); + let patches = PatchSet::load(base_patch)?; + patches.patch_rom(self); Ok(()) } diff --git a/prepare.sh b/prepare.sh index d532d49..ecb6269 100644 --- a/prepare.sh +++ b/prepare.sh @@ -6,4 +6,3 @@ fi if [[ ! -s enemizer_base_patch.json ]]; then cargo run -p base_patch_generator -- "$1" base_patch.json asar_symbols.txt enemizer_base_patch.json fi -cp enemizer_base_patch.json target/debug/enemizerBasePatch.json