143 lines
3.7 KiB
Rust
143 lines
3.7 KiB
Rust
use maraiah::{durandal::{bin::*, chunk::*, err::*, image::*, text::*},
|
|
marathon::{machdr, map, pict, shp, term, wad}};
|
|
use std::{fs,
|
|
io::{self, Write}};
|
|
|
|
fn write_chunk(cid: &Ident, cnk: &[u8], eid: u16) -> ResultS<()>
|
|
{
|
|
let fname = format!("out/{:04}{}.bin", eid, mac_roman_conv(cid));
|
|
let out = fs::File::create(&fname)?;
|
|
let mut out = io::BufWriter::new(out);
|
|
out.write(cnk)?;
|
|
Ok(())
|
|
}
|
|
|
|
fn read_chunk(cid: &Ident, cnk: &[u8], eid: u16) -> ResultS<()>
|
|
{
|
|
match cid {
|
|
b"PICT" => {
|
|
let im = pict::load_pict(cnk)?;
|
|
eprintln!("entry {} has PICT {}x{}", eid, im.w(), im.h());
|
|
let out = fs::File::create(&format!("out/{}.ppm", eid))?;
|
|
let mut out = io::BufWriter::new(out);
|
|
write_ppm(&mut out, &im)?;
|
|
}
|
|
b"Minf" => {
|
|
let minf = map::Minf::chunk(cnk)?;
|
|
eprintln!("entry {} has {:#?}", eid, minf);
|
|
}
|
|
b"EPNT" => {
|
|
let epnt = map::Endpoint::chunk(cnk)?;
|
|
eprintln!("entry {} has EPNT {:#?}", eid, epnt);
|
|
}
|
|
b"PNTS" => {
|
|
let epnt = map::Point::chunk(cnk)?;
|
|
eprintln!("entry {} has PNTS {:#?}", eid, epnt);
|
|
}
|
|
b"LINS" => {
|
|
let line = map::Line::chunk(cnk)?;
|
|
eprintln!("entry {} has LINS {:#?}", eid, line);
|
|
}
|
|
b"SIDS" => {
|
|
let line = map::Side::chunk(cnk)?;
|
|
eprintln!("entry {} has SIDS {:#?}", eid, line);
|
|
}
|
|
b"term" => {
|
|
let term = term::Terminal::chunk(cnk)?;
|
|
eprintln!("entry {} has term {:#?}", eid, term);
|
|
}
|
|
cid => {
|
|
write_chunk(cid, cnk, eid)?;
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn process_wad(b: &[u8]) -> ResultS<()>
|
|
{
|
|
let wad = wad::Wad::new(b)?;
|
|
|
|
eprintln!("{:#?}", wad);
|
|
|
|
for (eid, ent) in wad.entries {
|
|
for (cid, cnk) in ent.chunks {
|
|
read_chunk(&cid, cnk, eid)?;
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn dump_bitmaps(c: &shp::Collection, i: usize) -> ResultS<()>
|
|
{
|
|
for (j, bmp) in c.bmps.iter().enumerate() {
|
|
for (k, tab) in c.tabs.iter().enumerate() {
|
|
let fname = format!("out/shape{}_{}_{}.tga", i, j, k);
|
|
let out = fs::File::create(&fname)?;
|
|
let mut out = io::BufWriter::new(out);
|
|
write_tga(&mut out, &shp::ImageShp::new(bmp, &tab))?;
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn process_shp(b: &[u8]) -> ResultS<()>
|
|
{
|
|
for (i, cl) in shp::read_shapes(b)?.iter().enumerate() {
|
|
if let Some(cl) = &cl.0 {
|
|
dump_bitmaps(cl, i)?;
|
|
eprintln!("<{} lo> {:#?}\n{:#?}", i, cl.frms, cl.seqs);
|
|
}
|
|
if let Some(cl) = &cl.1 {
|
|
dump_bitmaps(cl, i + 100)?;
|
|
eprintln!("<{} hi> {:#?}\n{:#?}", i, cl.frms, cl.seqs);
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn main() -> ResultS<()>
|
|
{
|
|
use argparse::*;
|
|
use memmap::Mmap;
|
|
|
|
let mut args: Vec<String> = Vec::new();
|
|
{
|
|
let mut ap = ArgumentParser::new();
|
|
ap.set_description(env!("CARGO_PKG_DESCRIPTION"));
|
|
ap.add_option(&["-v", "--version"],
|
|
Print(format!("{} {}",
|
|
env!("CARGO_PKG_NAME"),
|
|
env!("CARGO_PKG_VERSION"))),
|
|
"Show the version");
|
|
ap.refer(&mut args)
|
|
.add_argument("inputs", List, "Input files");
|
|
ap.parse_args_or_exit();
|
|
}
|
|
|
|
for arg in &args {
|
|
let (typ, fna) = if let Some(st) = arg.find(':') {
|
|
arg.split_at(st + 1)
|
|
} else {
|
|
("wad:", arg.as_str())
|
|
};
|
|
|
|
let fp = fs::File::open(fna)?;
|
|
let mm = unsafe {Mmap::map(&fp)?};
|
|
let b = c_data(&mm, machdr::try_mac_header(&mm)..)?;
|
|
|
|
match typ {
|
|
"wad:" => process_wad(b),
|
|
"shp:" => process_shp(b),
|
|
_ => Err(err_msg("invalid file type specified on commandline")),
|
|
}?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
// EOF
|