Files
wad-reader/src/wad/wadfile.rs
Wesley Irvin c3b3081e74 Linedef Reader
Added ability to read linedef lumps. Also added all the test
functionality to make sure we are reading the linedefs correctly.
2025-03-30 19:21:52 -04:00

115 lines
3.9 KiB
Rust

use std::{fs::File, io::Read, path::Path};
use super::header::Header;
use crate::lumps::{LinedefLump, Lump, LumpType, VertexLump};
use crate::types::{Linedef, 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<Lump>,
pub data: Vec<u8>,
}
impl WADFile {
pub fn new(path: String) -> Self {
if !(validate_wad(path.as_str()).unwrap()) {
panic!();
}
let file_path = Path::new(path.as_str());
let mut wad_file = File::open(file_path).unwrap();
let file_size = wad_file.metadata().unwrap().len() as usize;
let mut file_buffer: Vec<u8> = Vec::with_capacity(file_size);
wad_file.read_to_end(&mut file_buffer).unwrap();
let wad_header = Header::read_data(&file_buffer[0..12]);
let mut lump_dir: Vec<Lump> = 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 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]);
let lump_type = match name.as_str() {
"VERTEXES" => LumpType::Vertex,
"LINEDEFS" => LumpType::Linedef,
_ => LumpType::Unknown,
};
lump_dir.push(Lump {
name,
offset: lump_offset,
lump_type,
size,
});
}
Self {
path,
wad_id: wad_header.wad_id,
num_lumps: wad_header.num_lumps,
dir_offset: wad_header.dir_offset,
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<Vertex> = Vec::with_capacity(lump_entries);
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 }
}
pub fn get_linedef_lump(&self, lump: &Lump) -> LinedefLump {
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 = lump_size / 14;
let mut linedefs: Vec<Linedef> = Vec::with_capacity(lump_entries);
for entry in 0..lump_entries {
let startpos = entry * 14;
let vertex1 = read_i16_le(&lump_data[startpos..startpos + 2]);
let vertex2 = read_i16_le(&lump_data[startpos + 2..startpos + 4]);
let flags = read_i16_le(&lump_data[startpos + 4..startpos + 6]);
let special = read_i16_le(&lump_data[startpos + 6..startpos + 8]);
let tag = read_i16_le(&lump_data[startpos + 8..startpos + 10]);
let front_sidedef = read_i16_le(&lump_data[startpos + 10..startpos + 12]);
let back_sidedef = read_i16_le(&lump_data[startpos + 12..startpos + 14]);
linedefs.push(Linedef {
vertex1,
vertex2,
flags,
special,
tag,
front_sidedef,
back_sidedef,
});
}
LinedefLump { linedefs }
}
}