diff --git a/src/marathon/wad.rs b/src/marathon/wad.rs index aba5113..2715863 100644 --- a/src/marathon/wad.rs +++ b/src/marathon/wad.rs @@ -13,18 +13,27 @@ type EntryMap<'a> = BTreeMap>; pub struct Entry<'a> { - map: ChunkMap<'a>, - ext: &'a[u8], + pub map: ChunkMap<'a>, + pub ext: &'a[u8], } #[derive(Debug)] pub struct Wad<'a> { - ver: u16, - dvr: u16, - ext: usize, - nam: String, - ent: EntryMap<'a>, + ver: Ver, + dvr: u16, + ext: usize, + nam: String, + pub ent: EntryMap<'a>, +} + +#[derive(Debug)] +pub enum Ver +{ + MI, + M2HasOvr, + M2HasDir, + M1 } impl<'a> fmt::Debug for Entry<'a> @@ -42,43 +51,50 @@ 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 ver = b_u16b(&b[ .. 2]); let dvr = b_u16b(&b[ 2.. 4]); let nam = &b[ 4..68]; - let crc = b_u32b(&b[68..72]); + // 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; + // hdr = b_u16b(&b[80..82]); + // bsz = b_u16b(&b[82..84]); + // pck = b_u32b(&b[84..88]); - println!("{:x}", crc); + let ver = match ver { + 4 => Ver::MI, + 2 => Ver::M2HasOvr, + 1 => Ver::M2HasDir, + 0 => panic!("old wad type unsupported"), //Ver::M1, + _ => panic!("invalid wad version"), + }; + + let mut map = EntryMap::new(); + let mut p = dir; + let n = match ver {Ver::M1 | Ver::M2HasDir => true, _ => false}; + let h = if n {8} else {10}; + + for i in 0..num + { + let ofs = b_u32b(&b[p ..p+ 4]) as usize; + let len = b_u32b(&b[p+4..p+ 8]) as usize; + let ind = if n {i as u16} + else {b_u16b(&b[p+8..p+10])}; + let ent = Entry{map: get_chunks(&b[ofs..ofs+len]), + ext: &b[p+h..p+h+ext]}; + + map.insert(ind, ent); + + p += h + ext; + } Wad{ver, dvr, ext, nam: mac_roman_conv(nam), - ent: get_entries(num, ext, dir, b)} + ent: map} } } -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; @@ -86,11 +102,11 @@ fn get_chunks(b: &[u8]) -> ChunkMap while p < b.len() { - let k = b_iden(&b[p+ 0..p+ 4]); + let k = b_iden(&b[p ..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]); + // o = b_u32b(&b[p+12..p+16]); + map.insert(k, &b[p+16..p+16+l]); p += l + 16; }