101 lines
2.1 KiB
Rust
101 lines
2.1 KiB
Rust
//! Marathon Wad format handling.
|
|
|
|
use std::collections::BTreeMap;
|
|
use std::fmt;
|
|
|
|
use durandal::bin::*;
|
|
use durandal::machead::try_mac_header;
|
|
use durandal::text::mac_roman_conv;
|
|
|
|
type Chunk <'a> = &'a[u8];
|
|
type ChunkMap<'a> = BTreeMap<Ident, Chunk<'a>>;
|
|
type EntryMap<'a> = BTreeMap<u16 , Entry<'a>>;
|
|
|
|
pub struct Entry<'a>
|
|
{
|
|
map: ChunkMap<'a>,
|
|
ext: &'a[u8],
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct Wad<'a>
|
|
{
|
|
ver: u16,
|
|
dvr: u16,
|
|
ext: usize,
|
|
nam: String,
|
|
ent: EntryMap<'a>,
|
|
}
|
|
|
|
impl<'a> fmt::Debug for Entry<'a>
|
|
{
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
|
|
{
|
|
write!(f, "Entry {{ ")?;
|
|
for (k, _) in &self.map {write!(f, "{} ", mac_roman_conv(&k[..]))?}
|
|
write!(f, "}}")
|
|
}
|
|
}
|
|
|
|
impl<'a> Wad<'a>
|
|
{
|
|
pub fn new(b: &[u8]) -> Wad
|
|
{
|
|
let b = &b[try_mac_header(b)..];
|
|
let ver = b_u16b(&b[ 0.. 2]);
|
|
let dvr = b_u16b(&b[ 2.. 4]);
|
|
let nam = &b[ 4..68];
|
|
let crc = b_u32b(&b[68..72]);
|
|
let dir = b_u32b(&b[72..76]) as usize;
|
|
let num = b_u16b(&b[76..78]) as usize;
|
|
let ext = b_u16b(&b[78..80]) as usize;
|
|
|
|
println!("{:x}", crc);
|
|
|
|
Wad{ver, dvr, ext,
|
|
nam: mac_roman_conv(nam),
|
|
ent: get_entries(num, ext, dir, b)}
|
|
}
|
|
}
|
|
|
|
fn get_entries(num: usize, ext: usize, dir: usize, b: &[u8]) -> EntryMap
|
|
{
|
|
let mut p = dir;
|
|
let mut map = EntryMap::new();
|
|
|
|
for _ in 0..num
|
|
{
|
|
let ofs = b_u32b(&b[p+0..p+ 4]) as usize;
|
|
let len = b_u32b(&b[p+4..p+ 8]) as usize;
|
|
let ind = b_u16b(&b[p+8..p+10]);
|
|
let ent = Entry{map: get_chunks(&b[ ofs.. ofs+len]),
|
|
ext: &b[p+10..p+10+ext]};
|
|
|
|
map.insert(ind, ent);
|
|
|
|
p += 10 + ext;
|
|
}
|
|
|
|
map
|
|
}
|
|
|
|
fn get_chunks(b: &[u8]) -> ChunkMap
|
|
{
|
|
let mut p = 0;
|
|
let mut map = ChunkMap::new();
|
|
|
|
while p < b.len()
|
|
{
|
|
let k = b_iden(&b[p+ 0..p+ 4]);
|
|
// nx = b_u32b(&b[p+ 4..p+ 8]);
|
|
let l = b_u32b(&b[p+ 8..p+12]) as usize;
|
|
// ?? = b_u32b(&b[p+12..p+16]);
|
|
map.insert(k, &b[p+16..p+ l]);
|
|
p += l + 16;
|
|
}
|
|
|
|
map
|
|
}
|
|
|
|
// EOF
|