From ab161c5a640a9ed38d3e7fac6ee1e84b86b41449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thea=20Sch=C3=B6bl?= Date: Wed, 17 Apr 2024 21:13:09 +0200 Subject: [PATCH] feat: bank stuff --- .gitignore | 1 + enmacompat/src/area.rs | 13 +++++++++-- enmacompat/src/main.rs | 10 +++++--- enmacompat/src/section.rs | 45 ++++++++++++++++++++++++++++++++---- enmacompat/src/windows_pe.rs | 6 +++++ 5 files changed, 66 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 6abfe1b..4269bec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target +/out /.direnv diff --git a/enmacompat/src/area.rs b/enmacompat/src/area.rs index 46cea27..bfb3d71 100644 --- a/enmacompat/src/area.rs +++ b/enmacompat/src/area.rs @@ -1,4 +1,7 @@ -use crate::{section::EnmaSection, windows_pe::WindowsPEFile}; +use crate::{ + section::{read_bank_cell, EnmaBankCell, EnmaSection}, + windows_pe::WindowsPEFile, +}; use binrw::{BinRead, NullString}; use serde::Serialize; @@ -53,19 +56,25 @@ pub fn read_area(file: &WindowsPEFile, address: u64) -> Result(area.sections_addr + i as u64 * 0x24)) + .map(|i| file.read_addr::(area.sections_addr + i as u64 * 0x28)) .collect::>()?, + bank_left: read_bank_cell(file, area.bank_left_addr, area.section_count)?, + bank_right: read_bank_cell(file, area.bank_right_addr, area.section_count)?, }) } #[derive(Debug, Serialize)] pub struct EnmaArea { + /// A unique identifier for the area pub id: u64, + /// The name of the area pub name: String, pub stage_id: u64, pub related_area_addr: [u64; 4], pub unknown: [f32; 4], pub sections: Vec, + pub bank_left: Vec, + pub bank_right: Vec, } #[derive(BinRead, Debug)] diff --git a/enmacompat/src/main.rs b/enmacompat/src/main.rs index 569c722..2497ba2 100644 --- a/enmacompat/src/main.rs +++ b/enmacompat/src/main.rs @@ -26,13 +26,17 @@ fn main() { windows_pe_file.get_file_address(location).unwrap() ); - for i in 1..2 { + let mut i = 1; + loop { let address = windows_pe_file.read_addr::(location + i * 8).unwrap(); + if address == 0 { + break; + } let area = read_area(&windows_pe_file, address).unwrap(); - - let file = File::create(format!("{}.json", area.name)).unwrap(); + let file = File::create(format!("out/{}.json", area.name)).unwrap(); let mut writer = std::io::BufWriter::new(file); serde_json::to_writer_pretty(&mut writer, &area).unwrap(); + i += 1; } } else { println!("\x1b[31mArea array location could not found\x1b[0m"); diff --git a/enmacompat/src/section.rs b/enmacompat/src/section.rs index 8fa5d82..e62c797 100644 --- a/enmacompat/src/section.rs +++ b/enmacompat/src/section.rs @@ -1,16 +1,53 @@ use binrw::BinRead; use serde::Serialize; +use crate::windows_pe::WindowsPEFile; + #[derive(Debug, BinRead, Serialize)] pub struct EnmaSection { + /// The distance along the path pub distance: f32, - pub x: f32, - pub y: f32, - pub angle1: f32, - pub angle2: f32, + /// The position of the node in world space + pub position: [f32; 2], + /// The normal of the node + pub normal: [f32; 2], + /// The left wall, where the wall point is `position + normal * left` pub left: f32, + /// The right wall, where the wall point is `position + normal * right` pub right: f32, + /// The z component of the position pub height: f32, pub unk1: f32, pub unk2: f32, } + +#[derive(Debug, BinRead, Serialize)] +pub struct EnmaBankCell { + /// The index of the section this bank belongs to + pub section: i32, + /// The width of the bank (it's unclear wether this is horizontal or diagonal) + pub width: f32, + /// The bank (it's unclear if this is a rotation in radians or a factor) + pub bank: f32, + /// If false then this bank cell is not connected to the previous one + #[br(map = |x: u32| x == 1)] + pub connect: bool, +} + +pub fn read_bank_cell( + file: &WindowsPEFile, + mut address: u64, + section_count: i32, +) -> Result, std::io::Error> { + let mut result = vec![]; + loop { + let bank = file.read_addr::(address)?; + if bank.section >= section_count { + break; + } + result.push(bank); + address += 0x10; + } + + Ok(result) +} diff --git a/enmacompat/src/windows_pe.rs b/enmacompat/src/windows_pe.rs index 07a6c24..e023c87 100644 --- a/enmacompat/src/windows_pe.rs +++ b/enmacompat/src/windows_pe.rs @@ -140,6 +140,12 @@ impl WindowsPEFile { T: BinRead, T::Args<'a>: Default, { + if address == 0 { + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + "Address null pointer dereference", + )); + } let mut reader = BufReader::new(&self.file); if let Some(file_addr) = self.get_file_address(address) { reader.seek(std::io::SeekFrom::Start(file_addr as u64))?;