Compare commits

...

14 Commits

Author SHA1 Message Date
728599e033 Merge pull request 'Seg Reader' (#8) from segs-reader into main
Reviewed-on: #8
2025-04-08 19:49:24 -04:00
2e2c500155 Seg Reader
Added the ability to read Seg lumps from the WAD file.
2025-04-08 19:47:15 -04:00
81fd194938 Merge pull request 'Thing Reader' (#7) from thing-reader into main
Reviewed-on: #7
2025-04-07 19:14:11 -04:00
569265f414 Thing Reader
Reads things from the WAD file.
2025-04-07 19:09:33 -04:00
76358caaff Merge pull request 'Sidedef Reader' (#6) from sidedef-reader into main
Reviewed-on: #6
2025-03-31 20:24:19 -04:00
fdb68ce0ff Sidedef Reader
Added the ability to read sidedef lumps from the wadfile.
2025-03-31 20:20:52 -04:00
a4fc4b89f8 Merge pull request 'WAD Refactor' (#5) from wad-refactor into main
Reviewed-on: #5
2025-03-31 19:33:15 -04:00
fb802a8d2b WAD Refactor
Refactored some of the code for the wadfile reading. Moved out the
readers into their own separate file, and moved some utilities around to
create wad utilities for more modularity.
2025-03-31 19:30:26 -04:00
8de9d56c2d Merge pull request 'Linedef Reader' (#4) from linedef-reader into main
Reviewed-on: #4
2025-03-30 19:23:53 -04:00
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
4b3822423f Merge branch 'lump-types' 2025-03-30 15:58:00 -04:00
e6a0a54315 Lump Type Handling
Added in the ability for us to detect Vertex lump types. Every lump is
no longer being flagged as a LumpType::Unknown. Also added in the
testing framework to make sure that we are loading up the correct number
of vertex lumps from the wad file.
2025-03-30 15:55:42 -04:00
bc4bf848c7 Merge branch 'vertex-loader' 2025-03-30 13:59:37 -04:00
ffb7b9d9c7 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.
2025-03-30 13:55:46 -04:00
24 changed files with 639 additions and 54 deletions

View File

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

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

@@ -0,0 +1,19 @@
use crate::types::Linedef;
pub struct LinedefLump {
pub linedefs: Vec<Linedef>,
}
impl LinedefLump {
pub fn get_linedef(&self, pos: usize) -> Linedef {
self.linedefs[pos].to_owned()
}
pub fn get_all_linedefs(&self) -> Vec<Linedef> {
self.linedefs.to_vec()
}
pub fn get_num_linedefs(&self) -> usize {
self.linedefs.len()
}
}

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

@@ -0,0 +1,17 @@
#[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,
Linedef,
Sidedef,
Thing,
Seg,
}

View File

@@ -0,0 +1,13 @@
mod linedef;
mod lump;
mod seg;
mod sidedef;
mod thing;
mod vertex;
pub use linedef::LinedefLump;
pub use lump::{Lump, LumpType};
pub use seg::SegLump;
pub use sidedef::SidedefLump;
pub use thing::ThingLump;
pub use vertex::VertexLump;

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

@@ -0,0 +1,19 @@
use crate::types::Seg;
pub struct SegLump {
pub segs: Vec<Seg>,
}
impl SegLump {
pub fn get_num_segs(&self) -> usize {
self.segs.len()
}
pub fn get_all_segs(&self) -> Vec<Seg> {
self.segs.to_vec()
}
pub fn get_seg(&self, pos: usize) -> Seg {
self.segs[pos].to_owned()
}
}

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

@@ -0,0 +1,19 @@
use crate::types::Sidedef;
pub struct SidedefLump {
pub sidedefs: Vec<Sidedef>,
}
impl SidedefLump {
pub fn get_num_sidedefs(&self) -> usize {
self.sidedefs.len()
}
pub fn get_all_sidedefs(&self) -> Vec<Sidedef> {
self.sidedefs.to_vec()
}
pub fn get_sidedef(&self, pos: usize) -> Sidedef {
self.sidedefs[pos].to_owned()
}
}

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

@@ -0,0 +1,19 @@
use crate::types::Thing;
pub struct ThingLump {
pub things: Vec<Thing>,
}
impl ThingLump {
pub fn get_num_things(&self) -> usize {
self.things.len()
}
pub fn get_all_things(&self) -> Vec<Thing> {
self.things.to_vec()
}
pub fn get_thing(&self, pos: usize) -> Thing {
self.things[pos].to_owned()
}
}

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 get_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,4 +1,4 @@
use crate::utils::*;
use crate::wad::wadfile::validate_wad;
#[test]
pub fn valid_wad() {

View File

@@ -1,36 +1,286 @@
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]
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]);
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]);
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]);
let correct_vertex = Vertex { x: 1088, y: -3680 };
assert_eq!(vertex_lump.get_vertex(0), correct_vertex);
}
#[test]
pub fn get_num_vertex_lumps() {
use crate::lumps::{Lump, LumpType};
let mut vetex_lumps: Vec<Lump> = Vec::new();
let wad_file = get_wad();
for entry in 0..wad_file.num_lumps as usize {
if let LumpType::Vertex = wad_file.directory[entry].lump_type {
vetex_lumps.push(wad_file.directory[entry].to_owned());
}
}
assert_eq!(vetex_lumps.len(), 9);
}
#[test]
pub fn get_num_vertexes() {
let wad_file = get_wad();
let vertex_lump = wad_file.get_vertex_lump(&wad_file.directory[10]);
assert_eq!(vertex_lump.get_num_vertexes(), 467);
}
#[test]
pub fn read_first_linedef() {
use crate::types::Linedef;
let wad_file = get_wad();
let linedef_lump = wad_file.get_linedef_lump(&wad_file.directory[8]);
let correct_linedef = Linedef {
vertex1: 0,
vertex2: 1,
flags: 1,
special: 0,
tag: 0,
front_sidedef: 0,
back_sidedef: -1,
};
assert_eq!(linedef_lump.get_linedef(0), correct_linedef);
}
#[test]
pub fn get_num_linedef_lumps() {
use crate::lumps::{Lump, LumpType};
let mut linedef_lumps: Vec<Lump> = Vec::new();
let wad_file = get_wad();
for entry in 0..wad_file.num_lumps as usize {
if let LumpType::Linedef = wad_file.directory[entry].lump_type {
linedef_lumps.push(wad_file.directory[entry].to_owned());
}
}
assert_eq!(linedef_lumps.len(), 9);
}
#[test]
pub fn get_num_linedefs() {
let wad_file = get_wad();
let linedef_lump = wad_file.get_linedef_lump(&wad_file.directory[8]);
assert_eq!(linedef_lump.get_num_linedefs(), 475);
}
#[test]
pub fn read_first_sidedef() {
use crate::types::Sidedef;
let wad_file = get_wad();
let sidedef_lump = wad_file.get_sidedef_lump(&wad_file.directory[9]);
let correct_sidedef = Sidedef {
x_offset: 0,
y_offset: 0,
upper_texture: String::from("-"),
lower_texture: String::from("-"),
middle_texture: String::from("DOOR3"),
sector: 40,
};
assert_eq!(sidedef_lump.get_sidedef(0), correct_sidedef);
}
#[test]
pub fn get_num_sidedef_lumps() {
use crate::lumps::{Lump, LumpType};
let mut sidedef_lumps: Vec<Lump> = Vec::new();
let wad_file = get_wad();
for entry in 0..wad_file.num_lumps as usize {
if let LumpType::Sidedef = wad_file.directory[entry].lump_type {
sidedef_lumps.push(wad_file.directory[entry].to_owned());
}
}
assert_eq!(sidedef_lumps.len(), 9);
}
#[test]
pub fn get_num_sidedefs() {
let wad_file = get_wad();
let sidedef_lump = wad_file.get_sidedef_lump(&wad_file.directory[9]);
assert_eq!(sidedef_lump.get_num_sidedefs(), 648);
}
#[test]
pub fn read_first_thing() {
use crate::types::Thing;
let wad_file = get_wad();
let thing_lump = wad_file.get_thing_lump(&wad_file.directory[7]);
let correct_thing = Thing {
x_position: 1056,
y_position: -3616,
angle: 90,
thing_type: 1,
flags: 7,
};
assert_eq!(thing_lump.get_thing(0), correct_thing);
}
#[test]
pub fn get_num_thing_lumps() {
use crate::lumps::{Lump, LumpType};
let mut thing_lumps: Vec<Lump> = Vec::new();
let wad_file = get_wad();
for entry in 0..wad_file.num_lumps as usize {
if let LumpType::Thing = wad_file.directory[entry].lump_type {
thing_lumps.push(wad_file.directory[entry].to_owned());
}
}
assert_eq!(thing_lumps.len(), 9);
}
#[test]
pub fn get_num_things() {
let wad_file = get_wad();
let thing_lump = wad_file.get_thing_lump(&wad_file.directory[7]);
assert_eq!(thing_lump.get_num_things(), 138);
}
#[test]
pub fn read_first_seg() {
use crate::types::Seg;
let wad_file = get_wad();
let seg_lump = wad_file.get_seg_lump(&wad_file.directory[11]);
let correct_seg = Seg {
start_vertex: 123,
end_vertex: 124,
angle: 16384,
linedef: 152,
direction: 0,
offset: 0,
};
assert_eq!(seg_lump.get_seg(0), correct_seg);
}
#[test]
pub fn get_num_seg_lumps() {
use crate::lumps::{Lump, LumpType};
let mut seg_lumps: Vec<Lump> = Vec::new();
let wad_file = get_wad();
for entry in 0..wad_file.num_lumps as usize {
if let LumpType::Seg = wad_file.directory[entry].lump_type {
seg_lumps.push(wad_file.directory[entry].to_owned());
}
}
assert_eq!(seg_lumps.len(), 9);
}
#[test]
pub fn get_num_segs() {
let wad_file = get_wad();
let thing_lump = wad_file.get_seg_lump(&wad_file.directory[11]);
assert_eq!(thing_lump.get_num_segs(), 732);
}

10
src/types/linedef.rs Normal file
View File

@@ -0,0 +1,10 @@
#[derive(Clone, Debug, PartialEq)]
pub struct Linedef {
pub vertex1: i16,
pub vertex2: i16,
pub flags: i16,
pub special: i16,
pub tag: i16,
pub front_sidedef: i16,
pub back_sidedef: i16,
}

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

@@ -0,0 +1,11 @@
mod linedef;
mod seg;
mod sidedef;
mod thing;
mod vertex;
pub use linedef::Linedef;
pub use seg::Seg;
pub use sidedef::Sidedef;
pub use thing::Thing;
pub use vertex::Vertex;

9
src/types/seg.rs Normal file
View File

@@ -0,0 +1,9 @@
#[derive(Clone, Debug, PartialEq)]
pub struct Seg {
pub start_vertex: i16,
pub end_vertex: i16,
pub angle: i16,
pub linedef: i16,
pub direction: i16,
pub offset: i16,
}

9
src/types/sidedef.rs Normal file
View File

@@ -0,0 +1,9 @@
#[derive(Clone, Debug, PartialEq)]
pub struct Sidedef {
pub x_offset: i16,
pub y_offset: i16,
pub upper_texture: String,
pub lower_texture: String,
pub middle_texture: String,
pub sector: i16,
}

8
src/types/thing.rs Normal file
View File

@@ -0,0 +1,8 @@
#[derive(Clone, Debug, PartialEq)]
pub struct Thing {
pub x_position: i16,
pub y_position: i16,
pub angle: i16,
pub thing_type: i16,
pub flags: i16,
}

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

@@ -1,32 +1,3 @@
use std::{
fs::File,
io::{self, Read},
path::Path,
};
/// Validates a WAD file to make sure that it is a legitimate file
///
/// Parameters:
/// - path: &str - Path to the WAD to validate
pub fn validate_wad(path: &str) -> io::Result<bool> {
let wad_file = Path::new(path);
// Check to see if the WAD exists
if !(wad_file.exists()) {
// Return back false because we didn't pass a valid file
return Ok(false);
}
// If the file exists open it and read the first 4 bytes
// of the file and see if we get "IWAD" or "PWAD"
let mut file = File::open(wad_file)?;
let mut magic = [0u8; 4];
file.read_exact(&mut magic)?;
// Now we return based on what we found
Ok(magic == *b"IWAD" || magic == *b"PWAD")
}
pub fn read_ascii(bytes: &[u8]) -> String {
std::str::from_utf8(&bytes[..bytes.len()])
.unwrap_or("")
@@ -41,3 +12,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())
}
}

View File

@@ -2,5 +2,5 @@ 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;

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 {
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]);

View File

@@ -1,5 +1,4 @@
mod directory;
mod header;
mod wadfile;
pub mod wadfile;
pub use wadfile::WADFile;

View File

@@ -1,15 +1,21 @@
mod readers;
mod utils;
pub use utils::validate_wad;
use crate::lumps::{Lump, LumpType};
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::utils::{read_ascii, read_i16_le, read_u32_le};
pub struct WADFile {
pub path: String,
pub wad_id: String,
pub num_lumps: u32,
pub dir_offset: u32,
pub directory: Vec<Directory>,
pub wad_data: Vec<u8>,
pub directory: Vec<Lump>,
pub data: Vec<u8>,
}
impl WADFile {
@@ -27,17 +33,26 @@ impl WADFile {
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;
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 = match name.as_str() {
"VERTEXES" => LumpType::Vertex,
"LINEDEFS" => LumpType::Linedef,
"SIDEDEFS" => LumpType::Sidedef,
"THINGS" => LumpType::Thing,
"SEGS" => LumpType::Seg,
_ => LumpType::Unknown,
};
lump_dir.push(Lump {
name,
offset: lump_offset,
lump_type,
size,
});
}
@@ -47,8 +62,8 @@ 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,
}
}
}

143
src/wad/wadfile/readers.rs Normal file
View File

@@ -0,0 +1,143 @@
use crate::lumps::{LinedefLump, Lump, SegLump, SidedefLump, ThingLump, VertexLump};
use crate::types::{Linedef, Seg, Sidedef, Thing, Vertex};
use crate::utils::read_ascii;
use crate::wad::WADFile;
use crate::wad::wadfile::read_i16_le;
impl WADFile {
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 }
}
pub fn get_sidedef_lump(&self, lump: &Lump) -> SidedefLump {
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_entires = lump_size / 30;
let mut sidedefs: Vec<Sidedef> = Vec::with_capacity(lump_entires);
for entry in 0..lump_entires {
let startpos = entry * 30;
let x_offset = read_i16_le(&lump_data[startpos..startpos + 2]);
let y_offset = read_i16_le(&lump_data[startpos + 2..startpos + 4]);
let upper_texture = read_ascii(&lump_data[startpos + 4..startpos + 12]);
let lower_texture = read_ascii(&lump_data[startpos + 12..startpos + 20]);
let middle_texture = read_ascii(&lump_data[startpos + 20..startpos + 28]);
let sector = read_i16_le(&lump_data[startpos + 28..startpos + 30]);
sidedefs.push(Sidedef {
x_offset,
y_offset,
upper_texture,
lower_texture,
middle_texture,
sector,
});
}
SidedefLump { sidedefs }
}
pub fn get_thing_lump(&self, lump: &Lump) -> ThingLump {
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 / 10;
let mut things: Vec<Thing> = Vec::with_capacity(lump_entries);
for entry in 0..lump_entries {
let startpos = entry * 10;
let x_position = read_i16_le(&lump_data[startpos..startpos + 2]);
let y_position = read_i16_le(&lump_data[startpos + 2..startpos + 4]);
let angle = read_i16_le(&lump_data[startpos + 4..startpos + 6]);
let thing_type = read_i16_le(&lump_data[startpos + 6..startpos + 8]);
let flags = read_i16_le(&lump_data[startpos + 8..startpos + 10]);
things.push(Thing {
x_position,
y_position,
angle,
thing_type,
flags,
});
}
ThingLump { things }
}
pub fn get_seg_lump(&self, lump: &Lump) -> SegLump {
let lump_offset = lump.offset as usize;
let lump_size = lump.size as usize;
let lump_entries = lump_size / 12;
let mut segs: Vec<Seg> = Vec::with_capacity(lump_entries);
for entry in 0..lump_entries {
let startpos = (entry * 12) + lump_offset;
let start_vertex = read_i16_le(&self.data[startpos..startpos + 2]);
let end_vertex = read_i16_le(&self.data[startpos + 2..startpos + 4]);
let angle = read_i16_le(&self.data[startpos + 4..startpos + 6]);
let linedef = read_i16_le(&self.data[startpos + 6..startpos + 8]);
let direction = read_i16_le(&self.data[startpos + 8..startpos + 10]);
let offset = read_i16_le(&self.data[startpos + 10..startpos + 12]);
segs.push(Seg {
start_vertex,
end_vertex,
angle,
linedef,
direction,
offset,
});
}
SegLump { segs }
}
}

26
src/wad/wadfile/utils.rs Normal file
View File

@@ -0,0 +1,26 @@
use std::fs::File;
use std::io::{self, Read};
use std::path::Path;
/// Validates a WAD file to make sure that it is a legitimate file
///
/// Parameters:
/// - path: &str - Path to the WAD to validate
pub fn validate_wad(path: &str) -> io::Result<bool> {
let wad_file = Path::new(path);
// Check to see if the WAD exists
if !(wad_file.exists()) {
// Return back false because we didn't pass a valid file
return Ok(false);
}
// If the file exists open it and read the first 4 bytes
// of the file and see if we get "IWAD" or "PWAD"
let mut file = File::open(wad_file)?;
let mut magic = [0u8; 4];
file.read_exact(&mut magic)?;
// Now we return based on what we found
Ok(magic == *b"IWAD" || magic == *b"PWAD")
}