Wad stuff is coming along slowly
This commit is contained in:
80
src/wad.rs
80
src/wad.rs
@@ -1,21 +1,67 @@
|
|||||||
use std::path::PathBuf;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::{BufReader, Seek, SeekFrom};
|
|
||||||
use bincode;
|
use bincode;
|
||||||
use serde::Deserialize;
|
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)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct WadHeader {
|
pub struct WadHeader {
|
||||||
pub identifier: [u8; 4],
|
pub identifier: [u8; 4],
|
||||||
pub num_lumps: i32,
|
pub num_lumps: i32,
|
||||||
pub file_offset_to_start: 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 {
|
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();
|
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<WadLumpDirectoryEntry> = Vec::new();
|
||||||
|
let mut nice_lumps: Vec<NiceWadLumpEntry> = 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
|
header
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,9 +72,31 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_open_wad() {
|
fn test_open_wad() {
|
||||||
let freedoom_iwad = PathBuf::from("freedoom1.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);
|
let ow = open_wad(&freedoom_iwad);
|
||||||
assert_eq!(&ow.identifier, b"IWAD");
|
assert_eq!(&ow.identifier, b"IWAD");
|
||||||
assert_eq!(std::str::from_utf8(&ow.identifier).unwrap(), "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::<WadHeader>()];
|
||||||
|
const _LDS: [u8; 16] = [0; std::mem::size_of::<WadLumpDirectoryEntry>()];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user