Improve Wad loader
parent
11141c2e00
commit
445eb15729
|
@ -13,18 +13,27 @@ type EntryMap<'a> = BTreeMap<u16 , Entry<'a>>;
|
||||||
|
|
||||||
pub struct Entry<'a>
|
pub struct Entry<'a>
|
||||||
{
|
{
|
||||||
map: ChunkMap<'a>,
|
pub map: ChunkMap<'a>,
|
||||||
ext: &'a[u8],
|
pub ext: &'a[u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Wad<'a>
|
pub struct Wad<'a>
|
||||||
{
|
{
|
||||||
ver: u16,
|
ver: Ver,
|
||||||
dvr: u16,
|
dvr: u16,
|
||||||
ext: usize,
|
ext: usize,
|
||||||
nam: String,
|
nam: String,
|
||||||
ent: EntryMap<'a>,
|
pub ent: EntryMap<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Ver
|
||||||
|
{
|
||||||
|
MI,
|
||||||
|
M2HasOvr,
|
||||||
|
M2HasDir,
|
||||||
|
M1
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> fmt::Debug for Entry<'a>
|
impl<'a> fmt::Debug for Entry<'a>
|
||||||
|
@ -42,43 +51,50 @@ impl<'a> Wad<'a>
|
||||||
pub fn new(b: &[u8]) -> Wad
|
pub fn new(b: &[u8]) -> Wad
|
||||||
{
|
{
|
||||||
let b = &b[try_mac_header(b)..];
|
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 dvr = b_u16b(&b[ 2.. 4]);
|
||||||
let nam = &b[ 4..68];
|
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 dir = b_u32b(&b[72..76]) as usize;
|
||||||
let num = b_u16b(&b[76..78]) as usize;
|
let num = b_u16b(&b[76..78]) as usize;
|
||||||
let ext = b_u16b(&b[78..80]) 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,
|
Wad{ver, dvr, ext,
|
||||||
nam: mac_roman_conv(nam),
|
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
|
fn get_chunks(b: &[u8]) -> ChunkMap
|
||||||
{
|
{
|
||||||
let mut p = 0;
|
let mut p = 0;
|
||||||
|
@ -86,11 +102,11 @@ fn get_chunks(b: &[u8]) -> ChunkMap
|
||||||
|
|
||||||
while p < b.len()
|
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]);
|
// nx = b_u32b(&b[p+ 4..p+ 8]);
|
||||||
let l = b_u32b(&b[p+ 8..p+12]) as usize;
|
let l = b_u32b(&b[p+ 8..p+12]) as usize;
|
||||||
// ?? = b_u32b(&b[p+12..p+16]);
|
// o = b_u32b(&b[p+12..p+16]);
|
||||||
map.insert(k, &b[p+16..p+ l]);
|
map.insert(k, &b[p+16..p+16+l]);
|
||||||
p += l + 16;
|
p += l + 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue