From ffb7b9d9c7c0471c8257cb65acc8fb2057a49a9e Mon Sep 17 00:00:00 2001 From: Wesley Irvin Date: Sun, 30 Mar 2025 13:55:46 -0400 Subject: [PATCH] Vertex Loading Added the ability to load vertex data from the WAD. Still needs some processing to make more robust, but for now is loading data. --- src/lib.rs | 1 + src/lumps/lump.rs | 13 ++++++++++++ src/lumps/mod.rs | 6 ++++++ src/lumps/vertex.rs | 19 +++++++++++++++++ src/tests/wad.rs | 50 +++++++++++++++++++++++++++++++++++++++----- src/types/mod.rs | 3 +++ src/types/vertex.rs | 5 +++++ src/utils/helpers.rs | 8 +++++++ src/utils/mod.rs | 1 + src/wad/directory.rs | 5 ----- src/wad/header.rs | 2 +- src/wad/mod.rs | 1 - src/wad/wadfile.rs | 45 ++++++++++++++++++++++++++++++--------- 13 files changed, 137 insertions(+), 22 deletions(-) create mode 100644 src/lumps/lump.rs create mode 100644 src/lumps/vertex.rs create mode 100644 src/types/mod.rs create mode 100644 src/types/vertex.rs delete mode 100644 src/wad/directory.rs diff --git a/src/lib.rs b/src/lib.rs index d0a7a14..6373e9c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ mod tests; mod lumps; +mod types; mod utils; mod wad; diff --git a/src/lumps/lump.rs b/src/lumps/lump.rs new file mode 100644 index 0000000..dfad4eb --- /dev/null +++ b/src/lumps/lump.rs @@ -0,0 +1,13 @@ +#[derive(Clone)] +pub struct Lump { + pub name: String, + pub lump_type: LumpType, + pub offset: u32, + pub size: u32, +} + +#[derive(Clone, Copy)] +pub enum LumpType { + Unknown, + Vertex, +} diff --git a/src/lumps/mod.rs b/src/lumps/mod.rs index e69de29..9b46b15 100644 --- a/src/lumps/mod.rs +++ b/src/lumps/mod.rs @@ -0,0 +1,6 @@ +mod lump; +mod vertex; + +pub use lump::Lump; +pub use lump::LumpType; +pub use vertex::VertexLump; diff --git a/src/lumps/vertex.rs b/src/lumps/vertex.rs new file mode 100644 index 0000000..c56b608 --- /dev/null +++ b/src/lumps/vertex.rs @@ -0,0 +1,19 @@ +use crate::types::Vertex; + +pub struct VertexLump { + pub vertexes: Vec, +} + +impl VertexLump { + pub fn num_vertexes(&self) -> usize { + self.vertexes.len() + } + + pub fn get_all_vertexes(&self) -> Vec { + self.vertexes.to_vec() + } + + pub fn get_vertex(&self, pos: usize) -> Vertex { + self.vertexes[pos].to_owned() + } +} diff --git a/src/tests/wad.rs b/src/tests/wad.rs index aa4eaeb..27a1f02 100644 --- a/src/tests/wad.rs +++ b/src/tests/wad.rs @@ -1,36 +1,76 @@ use crate::WADFile; +use std::sync::OnceLock; + +static WAD_INSTANCE: OnceLock = OnceLock::new(); + +/// Helper function to access the WAD file once +fn get_wad() -> &'static WADFile { + WAD_INSTANCE.get_or_init(|| WADFile::new(String::from("WADs/doom1.wad"))) +} + #[test] pub fn successful_wad_id() { - let wad_file = WADFile::new(String::from("WADs/doom1.wad")); + let wad_file = get_wad(); assert_eq!(wad_file.wad_id, "IWAD"); } #[test] pub fn correct_lumps() { - let wad_file = WADFile::new(String::from("WADs/doom1.wad")); + let wad_file = get_wad(); assert_eq!(wad_file.num_lumps, 1264); } #[test] pub fn correct_dir_size() { - let wad_file = WADFile::new(String::from("WADs/doom1.wad")); + let wad_file = get_wad(); assert_eq!(wad_file.directory.len(), 1264); } #[test] pub fn correct_lump_name() { - let wad_file = WADFile::new(String::from("WADs/doom1.wad")); + let wad_file = get_wad(); assert_eq!(wad_file.directory[0].name, "PLAYPAL"); } #[test] pub fn read_level_lump() { - let wad_file = WADFile::new(String::from("WADs/doom1.wad")); + let wad_file = get_wad(); assert_eq!(wad_file.directory[6].name, "E1M1"); } + +#[test] +pub fn read_vertex_lump() { + let wad_file = get_wad(); + + let vertex_lump = wad_file.get_vertex_lump(wad_file.directory[10].to_owned()); + + assert_ne!(vertex_lump.vertexes.len(), 0); +} + +#[test] +pub fn read_num_vertexes() { + let wad_file = get_wad(); + + let vertex_lump = wad_file.get_vertex_lump(wad_file.directory[10].to_owned()); + + assert_eq!(vertex_lump.vertexes.len(), 1868 / 4); +} + +#[test] +pub fn read_first_vertex() { + use crate::types::Vertex; + + let wad_file = get_wad(); + + let vertex_lump = wad_file.get_vertex_lump(wad_file.directory[10].to_owned()); + + let correct_vertex = Vertex { x: 1088, y: -3680 }; + + assert_eq!(vertex_lump.get_vertex(0), correct_vertex); +} diff --git a/src/types/mod.rs b/src/types/mod.rs new file mode 100644 index 0000000..3923dc6 --- /dev/null +++ b/src/types/mod.rs @@ -0,0 +1,3 @@ +mod vertex; + +pub use vertex::Vertex; diff --git a/src/types/vertex.rs b/src/types/vertex.rs new file mode 100644 index 0000000..409cfdb --- /dev/null +++ b/src/types/vertex.rs @@ -0,0 +1,5 @@ +#[derive(Clone, Debug, PartialEq)] +pub struct Vertex { + pub x: i16, + pub y: i16, +} diff --git a/src/utils/helpers.rs b/src/utils/helpers.rs index 99ae264..98c5066 100644 --- a/src/utils/helpers.rs +++ b/src/utils/helpers.rs @@ -41,3 +41,11 @@ pub fn read_u32_le(bytes: &[u8]) -> u32 { u32::from_le_bytes(bytes[..4].try_into().unwrap()) } } + +pub fn read_i16_le(bytes: &[u8]) -> i16 { + if bytes.len() < 2 { + 0 + } else { + i16::from_le_bytes(bytes[..2].try_into().unwrap()) + } +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 1873480..2784022 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -2,5 +2,6 @@ mod error; mod helpers; pub use helpers::read_ascii; +pub use helpers::read_i16_le; pub use helpers::read_u32_le; pub use helpers::validate_wad; diff --git a/src/wad/directory.rs b/src/wad/directory.rs deleted file mode 100644 index 14654da..0000000 --- a/src/wad/directory.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub struct Directory { - pub filepos: u32, - pub size: u32, - pub name: String, -} diff --git a/src/wad/header.rs b/src/wad/header.rs index 22ac646..6b671ca 100644 --- a/src/wad/header.rs +++ b/src/wad/header.rs @@ -8,7 +8,7 @@ use crate::utils::{read_ascii, read_u32_le}; impl Header { pub fn read_data(data: &[u8]) -> Self { - let id = read_ascii(&data[..4]); + let id = read_ascii(&data[..4]).to_string(); let lumps = read_u32_le(&data[4..8]); let offset = read_u32_le(&data[8..12]); diff --git a/src/wad/mod.rs b/src/wad/mod.rs index f9fd273..cd01cbc 100644 --- a/src/wad/mod.rs +++ b/src/wad/mod.rs @@ -1,4 +1,3 @@ -mod directory; mod header; mod wadfile; diff --git a/src/wad/wadfile.rs b/src/wad/wadfile.rs index 941e554..4491913 100644 --- a/src/wad/wadfile.rs +++ b/src/wad/wadfile.rs @@ -1,15 +1,17 @@ use std::{fs::File, io::Read, path::Path}; -use super::{directory::Directory, header::Header}; -use crate::utils::{read_ascii, read_u32_le, validate_wad}; +use super::header::Header; +use crate::lumps::{Lump, LumpType, VertexLump}; +use crate::types::Vertex; +use crate::utils::{read_ascii, read_i16_le, read_u32_le, validate_wad}; pub struct WADFile { pub path: String, pub wad_id: String, pub num_lumps: u32, pub dir_offset: u32, - pub directory: Vec, - pub wad_data: Vec, + pub directory: Vec, + pub data: Vec, } impl WADFile { @@ -27,17 +29,19 @@ impl WADFile { let wad_header = Header::read_data(&file_buffer[0..12]); - let mut wad_dir: Vec = Vec::with_capacity(wad_header.num_lumps as usize); + let mut lump_dir: Vec = Vec::with_capacity(wad_header.num_lumps as usize); let offset = wad_header.dir_offset; for entry in 0..wad_header.num_lumps { let startpos = (offset + 16 * entry) as usize; - let filepos = read_u32_le(&file_buffer[startpos..startpos + 4]); + let lump_offset = read_u32_le(&file_buffer[startpos..startpos + 4]); let size = read_u32_le(&file_buffer[startpos + 4..startpos + 8]); let name = read_ascii(&file_buffer[startpos + 8..startpos + 16]); - wad_dir.push(Directory { - filepos, + let lump_type = LumpType::Unknown; + lump_dir.push(Lump { name, + offset: lump_offset, + lump_type, size, }); } @@ -47,8 +51,29 @@ impl WADFile { wad_id: wad_header.wad_id, num_lumps: wad_header.num_lumps, dir_offset: wad_header.dir_offset, - directory: wad_dir, - wad_data: file_buffer, + directory: lump_dir, + data: file_buffer, } } + + pub fn get_vertex_lump(&self, lump: Lump) -> VertexLump { + let lump_offset = lump.offset as usize; + let lump_size = lump.size as usize; + let lump_data = &self.data[lump_offset..lump_offset + lump_size]; + let lump_entries: usize = lump_size / 4; + let mut vertexes: Vec = Vec::with_capacity(lump_size / 4); + + for entry in 0..lump_entries { + let startpos = entry * 4; + let vertex_x = read_i16_le(&lump_data[startpos..startpos + 2]); + let vertex_y = read_i16_le(&lump_data[startpos + 2..startpos + 4]); + + vertexes.push(Vertex { + x: vertex_x, + y: vertex_y, + }); + } + + VertexLump { vertexes } + } }