neurodoom 0.6.7

Deterministic no_std Doom engine with semantic and depth perception buffers for AI
Documentation
use neurodoom::wad::{Wad, WadKind};

fn load_wad() -> Vec<u8> {
    // Use DOOM_WAD env var, or fall back to vendored shareware WAD
    let path = std::env::var("DOOM_WAD")
        .unwrap_or_else(|_| "doom1.wad".to_string());
    std::fs::read(&path).unwrap_or_else(|e| panic!("failed to read WAD at {path}: {e}"))
}

#[test]
fn parse_doom1_wad() {
    let data = load_wad();
    let wad = Wad::parse(&data).expect("failed to parse WAD");

    assert_eq!(wad.kind(), WadKind::Iwad);
    assert!(wad.num_lumps() > 100, "expected many lumps, got {}", wad.num_lumps());
}

#[test]
fn find_playpal() {
    let data = load_wad();
    let wad = Wad::parse(&data).unwrap();

    let playpal = wad.lump_by_name("PLAYPAL").expect("PLAYPAL lump not found");
    // 14 palettes × 256 colors × 3 bytes (RGB)
    assert_eq!(playpal.len(), 14 * 256 * 3);
}

#[test]
fn find_e1m1_map_lumps() {
    let data = load_wad();
    let wad = Wad::parse(&data).unwrap();

    let e1m1 = wad.find_lump("E1M1").expect("E1M1 marker not found");

    // All required map sub-lumps should follow the marker
    let expected = [
        "THINGS", "LINEDEFS", "SIDEDEFS", "VERTEXES", "SEGS",
        "SSECTORS", "NODES", "SECTORS", "REJECT", "BLOCKMAP",
    ];
    for name in &expected {
        assert!(
            wad.find_lump_after(name, e1m1).is_some(),
            "map sub-lump {name} not found after E1M1"
        );
    }
}

#[test]
fn e1m1_vertexes_size() {
    let data = load_wad();
    let wad = Wad::parse(&data).unwrap();

    let e1m1 = wad.find_lump("E1M1").unwrap();
    let verts_idx = wad.find_lump_after("VERTEXES", e1m1).unwrap();
    let verts = wad.lump_data(verts_idx);

    // Each vertex is 4 bytes (2× i16)
    assert_eq!(verts.len() % 4, 0);
    let num_vertexes = verts.len() / 4;
    assert_eq!(num_vertexes, 467, "E1M1 should have 467 vertexes");
}