diff --git a/src/doomlevel.rs b/src/doomlevel.rs index 0c59a08..32e1664 100644 --- a/src/doomlevel.rs +++ b/src/doomlevel.rs @@ -1,3 +1,4 @@ +mod linedef; mod vertex; use std::{ @@ -5,6 +6,8 @@ use std::{ io::{Read, Seek, SeekFrom}, }; +use self::linedef::Linedef; + use super::wadfile::WADFile; use vertex::Vertex; @@ -19,12 +22,12 @@ enum Lumps { SECTORS, REJECT, BLOCKMAP, - BEHAVIOR, } pub struct DoomLevel { pub name: String, pub vertexes: Vec, + pub linedefs: Vec, } impl DoomLevel { @@ -36,6 +39,11 @@ impl DoomLevel { wad_file.get_lump_offset(lvl_index + Lumps::VERTEXES as u32), wad_file.get_lump_size(lvl_index + Lumps::VERTEXES as u32), ), + linedefs: load_linedefs( + wad_file, + wad_file.get_lump_offset(lvl_index + Lumps::LINEDEFS as u32), + wad_file.get_lump_size(lvl_index + Lumps::LINEDEFS as u32), + ), } } } @@ -63,3 +71,42 @@ fn load_vertexes(wad_file: &WADFile, offset: u32, size: u32) -> Vec { vertex_list } + +fn load_linedefs(wad_file: &WADFile, offset: u32, size: u32) -> Vec { + let num_linedef: u32 = size / 14u32; + + let mut linedef_list: Vec = Vec::with_capacity(num_linedef as usize); + + let mut linedef_data = File::open(&wad_file.wad_path).unwrap(); + linedef_data.seek(SeekFrom::Start(offset as u64)).unwrap(); + + for _ in 0..num_linedef { + let mut start_vertex = [0; 2]; + let mut end_vertex = [0; 2]; + let mut flags = [0; 2]; + let mut special_type = [0; 2]; + let mut sector_tag = [0; 2]; + let mut front_sidedef = [0; 2]; + let mut back_sidedef = [0; 2]; + + linedef_data.read(&mut start_vertex).unwrap(); + linedef_data.read(&mut end_vertex).unwrap(); + linedef_data.read(&mut flags).unwrap(); + linedef_data.read(&mut special_type).unwrap(); + linedef_data.read(&mut sector_tag).unwrap(); + linedef_data.read(&mut front_sidedef).unwrap(); + linedef_data.read(&mut back_sidedef).unwrap(); + + linedef_list.push(Linedef { + start_vertex: i16::from_le_bytes(start_vertex), + end_vertex: i16::from_le_bytes(end_vertex), + flags: i16::from_le_bytes(flags), + special_type: i16::from_le_bytes(special_type), + sector_tag: i16::from_le_bytes(sector_tag), + front_sidedef: i16::from_le_bytes(front_sidedef), + back_sidedef: i16::from_le_bytes(back_sidedef), + }); + } + + linedef_list +} diff --git a/src/doomlevel/linedef.rs b/src/doomlevel/linedef.rs new file mode 100644 index 0000000..9804368 --- /dev/null +++ b/src/doomlevel/linedef.rs @@ -0,0 +1,47 @@ +pub struct Linedef { + pub start_vertex: i16, + pub end_vertex: i16, + pub flags: i16, + pub special_type: i16, + pub sector_tag: i16, + pub front_sidedef: i16, + pub back_sidedef: i16, +} + +impl Linedef { + pub fn blocks_players(&self) -> bool { + self.flags & (1 << 0) != 0 + } + + pub fn blocks_monsters(&self) -> bool { + self.flags & (1 << 1) != 0 + } + + pub fn is_two_sided(&self) -> bool { + self.flags & (1 << 2) != 0 + } + + pub fn is_upper_unpegged(&self) -> bool { + self.flags & (1 << 3) != 0 + } + + pub fn is_lower_unpegged(&self) -> bool { + self.flags & (1 << 4) != 0 + } + + pub fn is_secret(&self) -> bool { + self.flags & (1 << 5) != 0 + } + + pub fn blocks_sound(&self) -> bool { + self.flags & (1 << 6) != 0 + } + + pub fn never_automap(&self) -> bool { + self.flags & (1 << 7) != 0 + } + + pub fn always_automap(&self) -> bool { + self.flags & (1 << 8) != 0 + } +} diff --git a/src/main.rs b/src/main.rs index 17394f5..2f62304 100644 --- a/src/main.rs +++ b/src/main.rs @@ -35,12 +35,53 @@ Header: ); } - println!("\nFirst 20 Vertex Entries for E1M1:"); + println!("\nFirst 15 Vertex Entries for {}:", level.name); - for i in 0..20 { + for i in 0..15 { println!( "\t{} - ({}, {})", i, level.vertexes[i].x, level.vertexes[i].y ); } + + let test_linedef = 247; + + println!("\nLinedef Entry {} for {}:", test_linedef, level.name); + + println!( + "Start Vertex: {} +End Vertex: {} +Flags: {} +Special Type: {} +Sector Tag: {} +Front Sidedef: {} +Back Sidedef: {} + +Flags: +\tBlocks Players: {} +\tBlocks Monsters: {} +\tTwo Sided: {} +\tUpper Texture Unpegged: {} +\tLower Texture Unpegged: {} +\tSecret: {} +\tBlocks Sound: {} +\tNever Shows on Automap: {} +\tAlways Shows on Automap {}", + level.linedefs[test_linedef].start_vertex, + level.linedefs[test_linedef].end_vertex, + level.linedefs[test_linedef].flags, + level.linedefs[test_linedef].special_type, + level.linedefs[test_linedef].sector_tag, + level.linedefs[test_linedef].front_sidedef, + level.linedefs[test_linedef].back_sidedef, + level.linedefs[test_linedef].blocks_players(), + level.linedefs[test_linedef].blocks_monsters(), + level.linedefs[test_linedef].is_two_sided(), + level.linedefs[test_linedef].is_upper_unpegged(), + level.linedefs[test_linedef].is_lower_unpegged(), + level.linedefs[test_linedef].is_secret(), + level.linedefs[test_linedef].blocks_sound(), + level.linedefs[test_linedef].never_automap(), + level.linedefs[test_linedef].always_automap() + ); }