Compare commits
3 commits
4972986fee
...
a0150caa56
Author | SHA1 | Date | |
---|---|---|---|
Lyle Mantooth | a0150caa56 | ||
Lyle Mantooth | 8d8faf105a | ||
Lyle Mantooth | ec37b1d583 |
|
@ -36,7 +36,10 @@ fn main() -> Result<(), anyhow::Error> {
|
|||
|
||||
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);
|
||||
|
||||
|
|
|
@ -1,43 +1,34 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::path::Path;
|
||||
|
||||
pub type Symbols = HashMap<String, usize>;
|
||||
|
||||
pub fn load_symbols(filename: &Path) -> anyhow::Result<Symbols> {
|
||||
let file = File::open(filename)?;
|
||||
let reader = BufReader::new(file);
|
||||
|
||||
let symbols = reader
|
||||
pub fn load_symbols(contents: &str) -> anyhow::Result<Symbols> {
|
||||
let symbols = contents
|
||||
.lines()
|
||||
.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()))
|
||||
}
|
||||
.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()))
|
||||
}
|
||||
|
||||
_ => 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))
|
||||
})
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.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)
|
||||
}
|
||||
|
|
|
@ -19,11 +19,13 @@ pub mod rom;
|
|||
pub struct InvalidEnumError<T>(PhantomData<T>);
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Patch {
|
||||
pub address: usize,
|
||||
pub patch_data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PatchSet {
|
||||
filename: PathBuf,
|
||||
patches: Vec<Patch>,
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
use std::time::Instant;
|
||||
|
||||
use anyhow::{bail, ensure};
|
||||
use anyhow::ensure;
|
||||
use clap::Parser;
|
||||
|
||||
use enemize::{asar, rom::RomData};
|
||||
|
||||
const ASAR_SYMBOLS: &'static str = "asar_symbols.txt";
|
||||
const ENEMIZER_BASE_PATCH: &'static str = "enemizer_base_patch.json";
|
||||
const ASAR_SYMBOLS: &'static str = include_str!("../../asar_symbols.txt");
|
||||
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
|
||||
/// 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(Path::new(ENEMIZER_BASE_PATCH), options, seed)?;
|
||||
rom.randomize(ENEMIZER_BASE_PATCH, options, seed)?;
|
||||
|
||||
let mut out_file = File::create(&args.output)?;
|
||||
|
||||
|
@ -84,12 +84,5 @@ fn main() -> anyhow::Result<()> {
|
|||
}
|
||||
|
||||
fn load_symbols() -> anyhow::Result<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))
|
||||
asar::load_symbols(ASAR_SYMBOLS)
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
use std::path::Path;
|
||||
|
||||
use anyhow::ensure;
|
||||
|
||||
use crate::option_flags::OptionFlags;
|
||||
use crate::rom::RomData;
|
||||
use crate::PatchSet;
|
||||
use crate::{Patch, PatchSet};
|
||||
|
||||
impl RomData {
|
||||
pub fn randomize(
|
||||
&mut self,
|
||||
base_patch: &Path,
|
||||
base_patch: &str,
|
||||
option_flags: OptionFlags,
|
||||
seed: i32,
|
||||
) -> anyhow::Result<()> {
|
||||
|
@ -29,8 +27,11 @@ impl RomData {
|
|||
self.expand_rom();
|
||||
self.set_info_flags(option_flags)?;
|
||||
|
||||
let patches = PatchSet::load(base_patch)?;
|
||||
patches.patch_rom(self);
|
||||
let patches: Vec<Patch> = serde_json::from_str(base_patch)?;
|
||||
|
||||
let mut patch_set = PatchSet::default();
|
||||
patch_set.add_patches(patches);
|
||||
patch_set.patch_rom(self);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -6,3 +6,4 @@ 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
|
||||
|
|
Loading…
Reference in a new issue