diff --git a/src/wad.rs b/src/wad.rs index cab704c..2809427 100644 --- a/src/wad.rs +++ b/src/wad.rs @@ -1,21 +1,67 @@ -use std::path::PathBuf; -use std::fs::File; -use std::io::{BufReader, Seek, SeekFrom}; use bincode; use serde::Deserialize; +use std::fs::File; +use std::io::{BufReader, Seek, SeekFrom}; +use std::path::PathBuf; +/* +A great document I've used as a reference is The Unofficial Doom Specs v1.666 +https://www.gamers.org/dhs/helpdocs/dmsp1666.html + +References in comments are probably to this document +*/ + +// See Chapter 2 #[derive(Deserialize, Debug)] pub struct WadHeader { pub identifier: [u8; 4], pub num_lumps: i32, pub file_offset_to_start: i32, } +// See Chapter 2 +#[derive(Deserialize, Debug)] +pub struct WadLumpDirectoryEntry { + pub offset: i32, + pub size: i32, + pub name: [u8; 8], +} + +pub struct NiceWadLumpEntry { + pub offset: i32, + pub size: i32, + pub name: String, +} pub fn open_wad(path: &PathBuf) -> WadHeader { - let mut file = BufReader::new(File::open(path).unwrap()); + let mut file = BufReader::new(File::open(path).unwrap()); let header: WadHeader = bincode::deserialize_from(&mut file).unwrap(); - file.seek(SeekFrom::Start(header.file_offset_to_start as u64)).unwrap(); - + file.seek(SeekFrom::Start(header.file_offset_to_start as u64)) + .unwrap(); + let mut lumps: Vec = Vec::new(); + let mut nice_lumps: Vec = Vec::new(); + let mut levels = Vec::new(); + for lump_num in 0..header.num_lumps { + let lump: WadLumpDirectoryEntry = bincode::deserialize_from(&mut file).unwrap(); + let nice_lump = NiceWadLumpEntry { + offset: lump.offset, + size: lump.size, + name: std::str::from_utf8(&lump.name).unwrap().to_string(), + }; + // I stole this from rust-doom. I looked up idSoftware Linux Doom, but they searched + // for the strings "map%d" or ExMy - I'm not 100% sure, but I bet many PWADs don't + // neccesarily use this... I do think that probably PWADs provide different THINGS + // for their maps - I don't know how you wouldn't - what I'm not 100% sure about is + // whether the map reference is _always_ before the THINGS. Might have to try + // with some WADs to check + if &lump.name == b"THINGS\0\0" { + levels.push((lump_num - 1) as usize); + } + lumps.push(lump); + nice_lumps.push(nice_lump); + } + for lump in nice_lumps { + println!("{}", lump.name); + } header } @@ -26,9 +72,31 @@ mod tests { #[test] fn test_open_wad() { let freedoom_iwad = PathBuf::from("freedoom1.wad"); - assert!(freedoom_iwad.exists(), "Needs freedoom1.wad - get it from here https://freedoom.github.io"); + assert!( + freedoom_iwad.exists(), + "WAD test need freedoom1.wad - get it from here https://freedoom.github.io" + ); let ow = open_wad(&freedoom_iwad); assert_eq!(&ow.identifier, b"IWAD"); assert_eq!(std::str::from_utf8(&ow.identifier).unwrap(), "IWAD"); } + + #[test] + fn test_failed() { + let freedoom_iwad = PathBuf::from("freedoom1.wad"); + assert!( + freedoom_iwad.exists(), + "WAD test need freedoom1.wad - get it from here https://freedoom.github.io" + ); + let ow = open_wad(&freedoom_iwad); + panic!(); + } + + #[test] + fn test_struct_size() { + // This probably isn't really neccesary... but it might catch a mistake, maybe? + // These shouldn't compile if the size is incorrect (I think) + const _HS: [u8; 12] = [0; std::mem::size_of::()]; + const _LDS: [u8; 16] = [0; std::mem::size_of::()]; + } }