98 lines
2.3 KiB
Rust
98 lines
2.3 KiB
Rust
pub mod durandal;
|
|
pub mod marathon;
|
|
|
|
use crate::durandal::{err::*, image::Image, pict::load_pict};
|
|
use crate::marathon::{wad, term};
|
|
use memmap::Mmap;
|
|
use std::{io, io::Write, fs, env};
|
|
|
|
#[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<Minf>
|
|
{
|
|
use crate::durandal::text::mac_roman_conv;
|
|
use crate::durandal::bin::*;
|
|
|
|
if b.len() < 88 {return err_msg("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() -> ResultS<()>
|
|
{
|
|
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)?;
|
|
|
|
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
|