Merge branch 'vertex-loader'

This commit is contained in:
2025-03-30 13:59:37 -04:00
13 changed files with 137 additions and 22 deletions

View File

@@ -2,6 +2,7 @@
mod tests; mod tests;
mod lumps; mod lumps;
mod types;
mod utils; mod utils;
mod wad; mod wad;

13
src/lumps/lump.rs Normal file
View File

@@ -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,
}

View File

@@ -0,0 +1,6 @@
mod lump;
mod vertex;
pub use lump::Lump;
pub use lump::LumpType;
pub use vertex::VertexLump;

19
src/lumps/vertex.rs Normal file
View File

@@ -0,0 +1,19 @@
use crate::types::Vertex;
pub struct VertexLump {
pub vertexes: Vec<Vertex>,
}
impl VertexLump {
pub fn num_vertexes(&self) -> usize {
self.vertexes.len()
}
pub fn get_all_vertexes(&self) -> Vec<Vertex> {
self.vertexes.to_vec()
}
pub fn get_vertex(&self, pos: usize) -> Vertex {
self.vertexes[pos].to_owned()
}
}

View File

@@ -1,36 +1,76 @@
use crate::WADFile; use crate::WADFile;
use std::sync::OnceLock;
static WAD_INSTANCE: OnceLock<WADFile> = 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] #[test]
pub fn successful_wad_id() { 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"); assert_eq!(wad_file.wad_id, "IWAD");
} }
#[test] #[test]
pub fn correct_lumps() { 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); assert_eq!(wad_file.num_lumps, 1264);
} }
#[test] #[test]
pub fn correct_dir_size() { 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); assert_eq!(wad_file.directory.len(), 1264);
} }
#[test] #[test]
pub fn correct_lump_name() { 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"); assert_eq!(wad_file.directory[0].name, "PLAYPAL");
} }
#[test] #[test]
pub fn read_level_lump() { 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"); 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);
}

3
src/types/mod.rs Normal file
View File

@@ -0,0 +1,3 @@
mod vertex;
pub use vertex::Vertex;

5
src/types/vertex.rs Normal file
View File

@@ -0,0 +1,5 @@
#[derive(Clone, Debug, PartialEq)]
pub struct Vertex {
pub x: i16,
pub y: i16,
}

View File

@@ -41,3 +41,11 @@ pub fn read_u32_le(bytes: &[u8]) -> u32 {
u32::from_le_bytes(bytes[..4].try_into().unwrap()) 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())
}
}

View File

@@ -2,5 +2,6 @@ mod error;
mod helpers; mod helpers;
pub use helpers::read_ascii; pub use helpers::read_ascii;
pub use helpers::read_i16_le;
pub use helpers::read_u32_le; pub use helpers::read_u32_le;
pub use helpers::validate_wad; pub use helpers::validate_wad;

View File

@@ -1,5 +0,0 @@
pub struct Directory {
pub filepos: u32,
pub size: u32,
pub name: String,
}

View File

@@ -8,7 +8,7 @@ use crate::utils::{read_ascii, read_u32_le};
impl Header { impl Header {
pub fn read_data(data: &[u8]) -> Self { 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 lumps = read_u32_le(&data[4..8]);
let offset = read_u32_le(&data[8..12]); let offset = read_u32_le(&data[8..12]);

View File

@@ -1,4 +1,3 @@
mod directory;
mod header; mod header;
mod wadfile; mod wadfile;

View File

@@ -1,15 +1,17 @@
use std::{fs::File, io::Read, path::Path}; use std::{fs::File, io::Read, path::Path};
use super::{directory::Directory, header::Header}; use super::header::Header;
use crate::utils::{read_ascii, read_u32_le, validate_wad}; 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 struct WADFile {
pub path: String, pub path: String,
pub wad_id: String, pub wad_id: String,
pub num_lumps: u32, pub num_lumps: u32,
pub dir_offset: u32, pub dir_offset: u32,
pub directory: Vec<Directory>, pub directory: Vec<Lump>,
pub wad_data: Vec<u8>, pub data: Vec<u8>,
} }
impl WADFile { impl WADFile {
@@ -27,17 +29,19 @@ impl WADFile {
let wad_header = Header::read_data(&file_buffer[0..12]); let wad_header = Header::read_data(&file_buffer[0..12]);
let mut wad_dir: Vec<Directory> = Vec::with_capacity(wad_header.num_lumps as usize); let mut lump_dir: Vec<Lump> = Vec::with_capacity(wad_header.num_lumps as usize);
let offset = wad_header.dir_offset; let offset = wad_header.dir_offset;
for entry in 0..wad_header.num_lumps { for entry in 0..wad_header.num_lumps {
let startpos = (offset + 16 * entry) as usize; 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 size = read_u32_le(&file_buffer[startpos + 4..startpos + 8]);
let name = read_ascii(&file_buffer[startpos + 8..startpos + 16]); let name = read_ascii(&file_buffer[startpos + 8..startpos + 16]);
wad_dir.push(Directory { let lump_type = LumpType::Unknown;
filepos, lump_dir.push(Lump {
name, name,
offset: lump_offset,
lump_type,
size, size,
}); });
} }
@@ -47,8 +51,29 @@ impl WADFile {
wad_id: wad_header.wad_id, wad_id: wad_header.wad_id,
num_lumps: wad_header.num_lumps, num_lumps: wad_header.num_lumps,
dir_offset: wad_header.dir_offset, dir_offset: wad_header.dir_offset,
directory: wad_dir, directory: lump_dir,
wad_data: file_buffer, 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<Vertex> = 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 }
}
} }