extern crate memmap; extern crate generic_array; pub mod durandal; pub mod marathon; use std::{io, fs, env}; use std::io::Write; use crate::durandal::pict::load_pict; use crate::durandal::image::Image; use crate::marathon::{wad, term}; use memmap::Mmap; use crate::durandal::bin::ResultS; #[derive(Debug)] struct Minf { env: u16, phy: u16, mus: u16, mfl: u16, efl: u16, epf: u32, bip: bool, nam: String, } impl Minf { fn chunk(b: &[u8]) -> ResultS { use crate::durandal::text::mac_roman_conv; use crate::durandal::bin::*; if b.len() < 88 {return Err("not enough data for Minf")} let env = b.c_u16b( 0)?; let phy = b.c_u16b( 2)?; let mus = b.c_u16b( 4)?; let mfl = b.c_u16b( 6)?; let efl = b.c_u16b( 8)?; let bip = b[10] != 0; let nam = mac_roman_conv(&b[18..84]); let epf = b.c_u32b(84)?; Ok(Minf{env, phy, mus, mfl, efl, epf, bip, nam}) } } fn write_ppm(fname: &str, im: &Image) -> io::Result<()> { let out = fs::File::create(fname)?; let mut out = io::BufWriter::new(out); write!(&mut out, "P3\n{} {}\n255\n", im.w(), im.h())?; for y in 0..im.h() { for x in 0..im.w() { let cr = &im[(x, y)]; write!(&mut out, "{} {} {} ", cr.r, cr.g, cr.b)?; } } Ok(()) } fn main() -> io::Result<()> { let arg = env::args().nth(1).expect("need at least 1 argument"); let fp = fs::File::open(arg)?; let mm = unsafe{Mmap::map(&fp)?}; let wad = wad::Wad::new(&mm).unwrap(); println!("{:#?}", wad); for (id, ent) in wad.ent { if let Some(b) = ent.map.get(b"PICT") { match load_pict(b) { Ok(im) => { println!("entry {} has PICT {}x{}", id, im.w(), im.h()); write_ppm(&format!("out_{}.ppm", id), &im)?; }, Err(e) => println!("entry {} has PICT (invalid: {:?})", id, e), } } if let Some(b) = ent.map.get(b"term") { match term::Terminal::chunk(b) { Ok(c) => println!("entry {} has term {:#?}", id, c), Err(e) => println!("entry {} has term (invalid: {:?})", id, e), } } if let Some(b) = ent.map.get(b"Minf") { match Minf::chunk(b) { Ok(c) => println!("entry {} has Minf {:#?}", id, c), Err(e) => println!("entry {} has Minf (invalid: {:?})", id, e), } } } Ok(()) } // EOF