From efc51288904c71d6e9ea0c29d331bcc91ff48130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20=E2=80=9Cpep=E2=80=9D=20Buquet?= Date: Wed, 24 Nov 2021 22:18:34 +0100 Subject: [PATCH] rom: extract pokemon list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maxime “pep” Buquet --- rom/Cargo.toml | 1 + rom/build.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/rom/Cargo.toml b/rom/Cargo.toml index ea4ec26..7d83684 100644 --- a/rom/Cargo.toml +++ b/rom/Cargo.toml @@ -7,3 +7,4 @@ license = "AGPL-3.0-or-later" [build-dependencies] quote = "1.0" +pkstrings = "0.1.0" diff --git a/rom/build.rs b/rom/build.rs index 807ecf5..bec76c6 100644 --- a/rom/build.rs +++ b/rom/build.rs @@ -21,10 +21,12 @@ use std::error::Error as StdError; use std::path::Path; use quote::{format_ident, quote}; +use pkstrings::{self, PKString}; #[derive(Debug, Eq, PartialEq)] pub enum Error { EnvVariableError(env::VarError), + PKStringError(pkstrings::Error), ROMDoesntExist, UnableToOpenROM, } @@ -35,6 +37,7 @@ impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { match self { Error::EnvVariableError(e) => write!(f, "POKEMON_ROM env var error: {}", e), + Error::PKStringError(e) => write!(f, "PKString error: {}", e), Error::ROMDoesntExist => write!(f, "ROM doesn't exist"), Error::UnableToOpenROM => write!(f, "Unable to open ROM"), } @@ -47,6 +50,12 @@ impl From for Error { } } +impl From for Error { + fn from(err: pkstrings::Error) -> Error { + Error::PKStringError(err) + } +} + fn get_rom() -> Result, Error> { let env_romp = env::var("POKEMON_ROM")?; let romp = Path::new(&env_romp); @@ -61,10 +70,45 @@ fn get_rom() -> Result, Error> { }) } +/// Get pokemon names from ROM slice. +/// The data that gets in is a list of encoded strings of 10 chars each, over 255 pokemons. +fn get_pokemon_list(data: &[u8]) -> Result, Error> { + let mut buffer: String = String::with_capacity(10); + let mut res: Vec = Vec::with_capacity(255); + + // TODO: Ensure we have the right length? a multiple of 10 + + for (offset, ord) in data.iter().enumerate() { + let pkstr = match PKString::try_from(&[*ord][..]) { + Ok(pkstr) => pkstr, + Err(e) => { + println!("BUFFER: {:?}", buffer); + return Err(Error::PKStringError(e)); + }, + }; + + if offset != 0 && (offset % 10) == 0 { + res.push(buffer.clone()); + buffer.clear() + } + + buffer.push_str(String::from(&pkstr).as_str()); + } + + res.push(buffer.clone()); + Ok(res) +} + fn main() -> Result<(), Error> { let output = Path::new(&env::var("OUT_DIR").unwrap()).join("output.rs"); let mut output = BufWriter::new(File::create(&output).unwrap()); - let _rom: Vec = get_rom()?; + let rom: Vec = get_rom()?; + + let pkmn: Vec<_> = { + let start = 0x1c21e; + let end = start + 10 * 190; // Only the first 190 are valid + get_pokemon_list(&rom[start..end])? + }; let pkmn_names: Vec<_> = [ "Rhydon", @@ -80,6 +124,8 @@ fn main() -> Result<(), Error> { pub enum PokemonNames { #(#pkmn_names),* } + + let foo = vec![#(#pkmn),*]; }; write!(output, "{}", tokens).unwrap();