Bake enemizer base patch and asar symbols into executable.

This commit is contained in:
Lyle Mantooth 2022-06-04 15:29:02 -04:00
parent 8d8faf105a
commit a0150caa56
Signed by: IslandUsurper
GPG key ID: 6DB52EAE123A5789
4 changed files with 41 additions and 53 deletions

View file

@ -36,7 +36,10 @@ fn main() -> Result<(), anyhow::Error> {
rom_bytes.resize(4 * 1024 * 1024, 0); rom_bytes.resize(4 * 1024 * 1024, 0);
let symbols = asar::load_symbols(Path::new(&symbols_path))?; 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 mut rom = RomData::new(symbols, rom_bytes); let mut rom = RomData::new(symbols, rom_bytes);

View file

@ -1,43 +1,34 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
pub type Symbols = HashMap<String, usize>; pub type Symbols = HashMap<String, usize>;
pub fn load_symbols(filename: &Path) -> anyhow::Result<Symbols> { pub fn load_symbols(contents: &str) -> anyhow::Result<Symbols> {
let file = File::open(filename)?; let symbols = contents
let reader = BufReader::new(file);
let symbols = reader
.lines() .lines()
.filter_map(|l| { .filter_map(|line| {
l.ok() let mut words = line.split_ascii_whitespace();
.and_then(|line| { match (words.next(), words.next(), words.next()) {
let mut words = line.split_ascii_whitespace(); // Get only two-word lines.
match (words.next(), words.next(), words.next()) { (Some(address), Some(symbol), None) => {
// Get only two-word lines. Some((symbol.to_owned(), address.to_owned()))
(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))
})
}) })
.collect(); .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();
Ok(symbols) Ok(symbols)
} }

View file

@ -1,15 +1,15 @@
use std::fs::File; use std::fs::File;
use std::io::prelude::*; use std::io::prelude::*;
use std::path::{Path, PathBuf}; use std::path::PathBuf;
use std::time::Instant; use std::time::Instant;
use anyhow::{bail, ensure}; use anyhow::ensure;
use clap::Parser; use clap::Parser;
use enemize::{asar, rom::RomData}; use enemize::{asar, rom::RomData};
const ASAR_SYMBOLS: &'static str = "asar_symbols.txt"; const ASAR_SYMBOLS: &'static str = include_str!("../../asar_symbols.txt");
const ENEMIZER_BASE_PATCH: &'static str = "enemizer_base_patch.json"; const ENEMIZER_BASE_PATCH: &'static str = include_str!("../../enemizer_base_patch.json");
/// Randomizes enemy placements in The Legend of Zelda: A Link to the Past for the Super Nintendo /// Randomizes enemy placements in The Legend of Zelda: A Link to the Past for the Super Nintendo
/// Entertainment System /// Entertainment System
@ -65,7 +65,7 @@ fn main() -> anyhow::Result<()> {
// (That is, 2 out of 2 billion instead of 1.) // (That is, 2 out of 2 billion instead of 1.)
let seed = args.seed.unwrap_or_else(|| rand::random()).saturating_abs(); let seed = args.seed.unwrap_or_else(|| rand::random()).saturating_abs();
rom.randomize(Path::new(ENEMIZER_BASE_PATCH), options, seed)?; rom.randomize(ENEMIZER_BASE_PATCH, options, seed)?;
let mut out_file = File::create(&args.output)?; let mut out_file = File::create(&args.output)?;
@ -84,12 +84,5 @@ fn main() -> anyhow::Result<()> {
} }
fn load_symbols() -> anyhow::Result<asar::Symbols> { fn load_symbols() -> anyhow::Result<asar::Symbols> {
if let Err(_) = std::fs::metadata(ASAR_SYMBOLS) { asar::load_symbols(ASAR_SYMBOLS)
bail!(
"Could not find symbols at {}. Did you run prepare.sh?",
ASAR_SYMBOLS
);
}
asar::load_symbols(Path::new(ASAR_SYMBOLS))
} }

View file

@ -1,15 +1,13 @@
use std::path::Path;
use anyhow::ensure; use anyhow::ensure;
use crate::option_flags::OptionFlags; use crate::option_flags::OptionFlags;
use crate::rom::RomData; use crate::rom::RomData;
use crate::PatchSet; use crate::{Patch, PatchSet};
impl RomData { impl RomData {
pub fn randomize( pub fn randomize(
&mut self, &mut self,
base_patch: &Path, base_patch: &str,
option_flags: OptionFlags, option_flags: OptionFlags,
seed: i32, seed: i32,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
@ -29,8 +27,11 @@ impl RomData {
self.expand_rom(); self.expand_rom();
self.set_info_flags(option_flags)?; self.set_info_flags(option_flags)?;
let patches = PatchSet::load(base_patch)?; let patches: Vec<Patch> = serde_json::from_str(base_patch)?;
patches.patch_rom(self);
let mut patch_set = PatchSet::default();
patch_set.add_patches(patches);
patch_set.patch_rom(self);
Ok(()) Ok(())
} }