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_code: u16, physi_id: u16, music_id: u16, msn_flag: u16, env_flag: u16, ent_flag: u32, levelnam: 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_code = b.c_u16b( 0)?; let physi_id = b.c_u16b( 2)?; let music_id = b.c_u16b( 4)?; let msn_flag = b.c_u16b( 6)?; let env_flag = b.c_u16b( 8)?; let levelnam = mac_roman_conv(&b[18..84]); let ent_flag = b.c_u32b(84)?; Ok(Minf{env_code, physi_id, music_id, msn_flag, env_flag, ent_flag, levelnam}) } } 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.entries { if let Some(b) = ent.chunks.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.chunks.get(b"Minf") { match Minf::chunk(b) { Ok (c) => println!("entry {} has Minf {:#?}", id, c), Err(e) => println!("entry {} has Minf (invalid: {:?})", id, e), } } if let Some(b) = ent.chunks.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), } } } Ok(()) } // EOF