Compare commits
14 Commits
16f21694d9
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 728599e033 | |||
|
2e2c500155
|
|||
| 81fd194938 | |||
|
569265f414
|
|||
| 76358caaff | |||
|
fdb68ce0ff
|
|||
| a4fc4b89f8 | |||
|
fb802a8d2b
|
|||
| 8de9d56c2d | |||
|
c3b3081e74
|
|||
|
4b3822423f
|
|||
|
e6a0a54315
|
|||
|
bc4bf848c7
|
|||
|
ffb7b9d9c7
|
@@ -2,6 +2,7 @@
|
||||
mod tests;
|
||||
|
||||
mod lumps;
|
||||
mod types;
|
||||
mod utils;
|
||||
mod wad;
|
||||
|
||||
|
||||
19
src/lumps/linedef.rs
Normal file
19
src/lumps/linedef.rs
Normal 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
17
src/lumps/lump.rs
Normal 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,
|
||||
}
|
||||
@@ -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
19
src/lumps/seg.rs
Normal 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
19
src/lumps/sidedef.rs
Normal 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
19
src/lumps/thing.rs
Normal 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
19
src/lumps/vertex.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::utils::*;
|
||||
use crate::wad::wadfile::validate_wad;
|
||||
|
||||
#[test]
|
||||
pub fn valid_wad() {
|
||||
|
||||
260
src/tests/wad.rs
260
src/tests/wad.rs
@@ -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
10
src/types/linedef.rs
Normal 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
11
src/types/mod.rs
Normal 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
9
src/types/seg.rs
Normal 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
9
src/types/sidedef.rs
Normal 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
8
src/types/thing.rs
Normal 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
5
src/types/vertex.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Vertex {
|
||||
pub x: i16,
|
||||
pub y: i16,
|
||||
}
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
pub struct Directory {
|
||||
pub filepos: u32,
|
||||
pub size: u32,
|
||||
pub name: String,
|
||||
}
|
||||
@@ -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]);
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
mod directory;
|
||||
mod header;
|
||||
mod wadfile;
|
||||
pub mod wadfile;
|
||||
|
||||
pub use wadfile::WADFile;
|
||||
|
||||
@@ -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
143
src/wad/wadfile/readers.rs
Normal 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
26
src/wad/wadfile/utils.rs
Normal 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")
|
||||
}
|
||||
Reference in New Issue
Block a user