clean up code
parent
ee3c2cb8c1
commit
2a3dd59570
|
@ -16,8 +16,8 @@ pub struct Color
|
|||
/// Image with width and height.
|
||||
pub struct Image
|
||||
{
|
||||
w: usize,
|
||||
h: usize,
|
||||
w: usize,
|
||||
h: usize,
|
||||
pub cr: Vec<Color>,
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,7 @@ pub fn check_apple_single(b: &[u8]) -> Option<usize>
|
|||
|
||||
let num = b.o_u16b(24)? as usize;
|
||||
|
||||
for i in 0..num
|
||||
{
|
||||
for i in 0..num {
|
||||
let p = 26 + (12 * i);
|
||||
let fid = b.o_u32b(p )?;
|
||||
let ofs = b.o_u32b(p+4)? as usize;
|
||||
|
@ -30,8 +29,7 @@ pub fn check_mac_bin(b: &[u8]) -> Option<usize>
|
|||
let mut crc = 0;
|
||||
|
||||
for i in 0..124 {
|
||||
for j in 8..16
|
||||
{
|
||||
for j in 8..16 {
|
||||
let d = b[i] as (u16) << j;
|
||||
if (d ^ crc) & 0x8000 != 0 {crc = crc << 1 ^ 0x1021}
|
||||
else {crc <<= 1}
|
||||
|
|
|
@ -21,16 +21,15 @@ fn get_clut(b: &[u8]) -> ResultS<Vec<Color>>
|
|||
|
||||
map.resize(num, Color{r: 0, g: 0, b: 0, a: 0});
|
||||
|
||||
for i in 0..num
|
||||
{
|
||||
for i in 0..num {
|
||||
let p = 8 + i * 8;
|
||||
let n = (b.c_u16b(p )? & 0xff) as usize;
|
||||
let r = (b.c_u16b(p+2)? >> 8 ) as u8;
|
||||
let g = (b.c_u16b(p+4)? >> 8 ) as u8;
|
||||
let b = (b.c_u16b(p+6)? >> 8 ) as u8;
|
||||
let n = if !dev {(b.c_u16b(p )? & 0xff) as usize} else {i};
|
||||
let r = (b.c_u16b(p+2)? >> 8) as u8;
|
||||
let g = (b.c_u16b(p+4)? >> 8) as u8;
|
||||
let b = (b.c_u16b(p+6)? >> 8) as u8;
|
||||
|
||||
// with device mapping, we ignore the index entirely
|
||||
map[if dev {i} else {n}] = Color{r, g, b, a: 255};
|
||||
map[n] = Color{r, g, b, a: 255};
|
||||
}
|
||||
|
||||
Ok(map)
|
||||
|
@ -41,13 +40,12 @@ fn read_rle_data<F, N>(cmp: bool, len: usize, o: &mut Vec<u8>, mut rd: F)
|
|||
where F: FnMut() -> GenericArray<u8, N>,
|
||||
N: ArrayLength<u8>
|
||||
{
|
||||
if cmp
|
||||
{
|
||||
if cmp {
|
||||
let d = rd();
|
||||
for _ in 0..len {for v in d.iter() {o.push(*v)}}
|
||||
for _ in 0..len {for v in d.iter() {o.push(*v)}}
|
||||
} else {
|
||||
for _ in 0..len {let d = rd(); for v in d.iter() {o.push(*v)}}
|
||||
}
|
||||
else
|
||||
{for _ in 0..len {let d = rd(); for v in d.iter() {o.push(*v)}}}
|
||||
}
|
||||
|
||||
/// Read run-length encoded data.
|
||||
|
@ -58,8 +56,7 @@ fn read_rle(b: &[u8], pt: usize, ln: bool) -> ResultS<(Vec<u8>, usize)>
|
|||
let sz = if pt > 250 {(b.c_u16b(0)? as usize + 2, p += 2).0}
|
||||
else {(b[0] as usize + 1, p += 1).0};
|
||||
|
||||
while p < sz
|
||||
{
|
||||
while p < sz {
|
||||
let szf = b[(p, p += 1).0];
|
||||
let cmp = szf & 0x80 != 0;
|
||||
let len = if cmp {!szf + 2} else {szf + 1} as usize;
|
||||
|
@ -84,8 +81,7 @@ fn expand_data(b: Vec<u8>, depth: u16) -> ResultS<Vec<u8>>
|
|||
_ => return Err("invalid bit depth")
|
||||
});
|
||||
|
||||
for ch in b
|
||||
{
|
||||
for ch in b {
|
||||
match depth {
|
||||
4 => for i in 1..=0 {o.push(ch >> i * 4 & 0xfu8)}, // 2 nibbles
|
||||
2 => for i in 3..=0 {o.push(ch >> i * 2 & 0x3u8)}, // 4 dibits
|
||||
|
@ -100,8 +96,6 @@ fn expand_data(b: Vec<u8>, depth: u16) -> ResultS<Vec<u8>>
|
|||
/// Process a CopyBits operation.
|
||||
fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> ResultS<Image>
|
||||
{
|
||||
const SIZE_HEAD: usize = 46;
|
||||
|
||||
let mut p = if !packed {4} else {0}; // baseAddr
|
||||
|
||||
let (w, h) = (im.w(), im.h());
|
||||
|
@ -124,7 +118,7 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result
|
|||
// = b.c_u32b(p+38)?; pmTable
|
||||
// = b.c_u32b(p+42)?; pmReserved
|
||||
|
||||
p += SIZE_HEAD;
|
||||
p += 46; // size of header
|
||||
|
||||
if pf & 0x8000 == 0 {return Err("PICT1 not supported")}
|
||||
if xe - xb != w || ye - yb != h {return Err("image bounds are incorrect")}
|
||||
|
@ -143,22 +137,17 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result
|
|||
|
||||
match dept {
|
||||
1 | 2 | 4 | 8 =>
|
||||
// uncompressed 8-bit colormap indices
|
||||
if pt < 8 && dept == 8
|
||||
{
|
||||
if pt < 8 && dept == 8 {
|
||||
// uncompressed 8-bit colormap indices
|
||||
for _ in 0..h {
|
||||
for _ in 0..w
|
||||
{im.cr.push(map[b[(p, p += 1).0] as usize].clone())}
|
||||
}
|
||||
|
||||
Ok(im)
|
||||
}
|
||||
|
||||
// RLE compressed 1, 2, 4 or 8 bit colormap indices
|
||||
else if rle
|
||||
{
|
||||
for _ in 0..h
|
||||
{
|
||||
} else if rle {
|
||||
// RLE compressed 1, 2, 4 or 8 bit colormap indices
|
||||
for _ in 0..h {
|
||||
let (d, pp) = read_rle(&b[p..], pt, false)?;
|
||||
let d = if dept < 8 {expand_data(d, dept)?} else {d};
|
||||
|
||||
|
@ -169,26 +158,19 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result
|
|||
|
||||
Ok(im)
|
||||
}
|
||||
|
||||
// invalid
|
||||
else {Err("invalid configuration")},
|
||||
16 =>
|
||||
// uncompressed R5G5B5
|
||||
if pt < 8 || pack == PACK_NONE
|
||||
{
|
||||
if pt < 8 || pack == PACK_NONE {
|
||||
// uncompressed R5G5B5
|
||||
for _ in 0..h {
|
||||
for _ in 0..w
|
||||
{im.cr.push(Color::from_r5g5b5(b.c_u16b((p, p += 2).0)?))}
|
||||
}
|
||||
|
||||
Ok(im)
|
||||
}
|
||||
|
||||
// RLE compressed R5G5B5
|
||||
else if rle
|
||||
{
|
||||
for _ in 0..h
|
||||
{
|
||||
} else if rle {
|
||||
// RLE compressed R5G5B5
|
||||
for _ in 0..h {
|
||||
let (d, pp) = read_rle(&b[p..], pt, true)?;
|
||||
|
||||
p += pp;
|
||||
|
@ -199,16 +181,12 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result
|
|||
|
||||
Ok(im)
|
||||
}
|
||||
|
||||
// invalid
|
||||
else {Err("invalid configuration")},
|
||||
32 =>
|
||||
// uncompressed RGB8 or XRGB8
|
||||
if pt < 8 || pack == PACK_NONE || pack == PACK_NOPAD
|
||||
{
|
||||
if pt < 8 || pack == PACK_NONE || pack == PACK_NOPAD {
|
||||
// uncompressed RGB8 or XRGB8
|
||||
for _ in 0..h {
|
||||
for _ in 0..w
|
||||
{
|
||||
for _ in 0..w {
|
||||
if pack != PACK_NOPAD {p += 1};
|
||||
let (r, g, b) = (b[p], b[p+1], b[p+2]);
|
||||
p += 3;
|
||||
|
@ -217,20 +195,15 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result
|
|||
}
|
||||
|
||||
Ok(im)
|
||||
}
|
||||
|
||||
// RLE compressed RGB8
|
||||
else if rle
|
||||
{
|
||||
} else if rle {
|
||||
// RLE compressed RGB8
|
||||
let pt = pt - w; // remove padding byte from pitch
|
||||
for _ in 0..h
|
||||
{
|
||||
for _ in 0..h {
|
||||
let (d, pp) = read_rle(&b[p..], pt, false)?;
|
||||
|
||||
p += pp;
|
||||
|
||||
for x in 0..w
|
||||
{
|
||||
for x in 0..w {
|
||||
let (r, g, b) = (d[x+w*0], d[x+w*1], d[x+w*2]);
|
||||
im.cr.push(Color{r, g, b, a: 255});
|
||||
}
|
||||
|
@ -238,8 +211,6 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result
|
|||
|
||||
Ok(im)
|
||||
}
|
||||
|
||||
// invalid
|
||||
else {Err("invalid configuration")},
|
||||
_ => Err("invalid bit depth")
|
||||
}
|
||||
|
@ -252,18 +223,16 @@ fn read_quicktime_c(_im: Image, _b: &[u8]) -> ResultS<Image>
|
|||
/// Load a PICT image.
|
||||
pub fn load_pict(b: &[u8]) -> ResultS<Image>
|
||||
{
|
||||
const SIZE_HEAD: usize = 10;
|
||||
// size = b.c_u16b(0)?;
|
||||
// top = b.c_u16b(2)?;
|
||||
// left = b.c_u16b(4)?;
|
||||
let h = b.c_u16b(6)? as usize;
|
||||
let w = b.c_u16b(8)? as usize;
|
||||
let im = Image::new(w, h);
|
||||
|
||||
// size = b.c_u16b(0)?;
|
||||
// top = b.c_u16b(2)?;
|
||||
// left = b.c_u16b(4)?;
|
||||
let h = b.c_u16b(6)? as usize;
|
||||
let w = b.c_u16b(8)? as usize;
|
||||
let im = Image::new(w, h);
|
||||
let mut p = SIZE_HEAD;
|
||||
let mut p = 10; // size of header
|
||||
|
||||
while p < b.len()
|
||||
{
|
||||
while p < b.len() {
|
||||
let op = b.c_u16b((p, p += 2).0)?;
|
||||
|
||||
match op {
|
||||
|
@ -274,47 +243,47 @@ pub fn load_pict(b: &[u8]) -> ResultS<Image>
|
|||
0x8200 => return read_quicktime_c(im, &b[p..]), // CompressedQuickTime
|
||||
0x00ff => break, // OpEndPic
|
||||
// help i'm trapped in an awful metafile format from the 80s
|
||||
0x0000 => (), // NoOp
|
||||
0x001c => (), // HiliteMode
|
||||
0x001e => (), // DefHilite
|
||||
0x0038 => (), // FrameSameRect
|
||||
0x0039 => (), // PaintSameRect
|
||||
0x003a => (), // EraseSameRect
|
||||
0x003b => (), // InvertSameRect
|
||||
0x003c => (), // FillSameRect
|
||||
0x8000 => (), // Reserved
|
||||
0x0000 | // NoOp
|
||||
0x001c | // HiliteMode
|
||||
0x001e | // DefHilite
|
||||
0x0038 | // FrameSameRect
|
||||
0x0039 | // PaintSameRect
|
||||
0x003a | // EraseSameRect
|
||||
0x003b | // InvertSameRect
|
||||
0x003c | // FillSameRect
|
||||
0x8000 | // Reserved
|
||||
0x8100 => (), // Reserved
|
||||
0x0003 => p += 2, // TxFont
|
||||
0x0004 => p += 2, // TxFace
|
||||
0x0005 => p += 2, // TxMode
|
||||
0x0008 => p += 2, // PnMode
|
||||
0x000d => p += 2, // TxSize
|
||||
0x0011 => p += 2, // VersionOp
|
||||
0x0015 => p += 2, // PnLocHFrac
|
||||
0x0016 => p += 2, // ChExtra
|
||||
0x0023 => p += 2, // ShortLineFrom
|
||||
0x00a0 => p += 2, // ShortComment
|
||||
0x0003 | // TxFont
|
||||
0x0004 | // TxFace
|
||||
0x0005 | // TxMode
|
||||
0x0008 | // PnMode
|
||||
0x000d | // TxSize
|
||||
0x0011 | // VersionOp
|
||||
0x0015 | // PnLocHFrac
|
||||
0x0016 | // ChExtra
|
||||
0x0023 | // ShortLineFrom
|
||||
0x00a0 | // ShortComment
|
||||
0x02ff => p += 2, // Version
|
||||
0x0006 => p += 4, // SpExtra
|
||||
0x0007 => p += 4, // PnSize
|
||||
0x000b => p += 4, // OvSize
|
||||
0x000c => p += 4, // Origin
|
||||
0x000e => p += 4, // FgCol
|
||||
0x000f => p += 4, // BkCol
|
||||
0x0006 | // SpExtra
|
||||
0x0007 | // PnSize
|
||||
0x000b | // OvSize
|
||||
0x000c | // Origin
|
||||
0x000e | // FgCol
|
||||
0x000f | // BkCol
|
||||
0x0021 => p += 4, // LineFrom
|
||||
0x001a => p += 6, // RGBFgCol
|
||||
0x001b => p += 6, // RGBBkCol
|
||||
0x001d => p += 6, // TxRatio
|
||||
0x001a | // RGBFgCol
|
||||
0x001b | // RGBBkCol
|
||||
0x001d | // TxRatio
|
||||
0x0022 => p += 6, // ShortLine
|
||||
0x0002 => p += 8, // BkPat
|
||||
0x0009 => p += 8, // PnPat
|
||||
0x0010 => p += 8, // TxRatio
|
||||
0x0020 => p += 8, // Line
|
||||
0x002e => p += 8, // GlyphState
|
||||
0x0030 => p += 8, // FrameRect
|
||||
0x0031 => p += 8, // PaintRect
|
||||
0x0032 => p += 8, // EraseRect
|
||||
0x0033 => p += 8, // InvertRect
|
||||
0x0002 | // BkPat
|
||||
0x0009 | // PnPat
|
||||
0x0010 | // TxRatio
|
||||
0x0020 | // Line
|
||||
0x002e | // GlyphState
|
||||
0x0030 | // FrameRect
|
||||
0x0031 | // PaintRect
|
||||
0x0032 | // EraseRect
|
||||
0x0033 | // InvertRect
|
||||
0x0034 => p += 8, // FillRect
|
||||
0x002d => p += 10, // LineJustify
|
||||
0x0c00 => p += 24, // HeaderOp
|
||||
|
|
|
@ -3,18 +3,16 @@
|
|||
/// Formats a binary size string for any given number.
|
||||
pub fn to_binsize(n: u64) -> String
|
||||
{
|
||||
let names = ["kB", "MB", "GB", "TB"];
|
||||
const NAMES: [&str; 4] = ["kB", "MB", "GB", "TB"];
|
||||
|
||||
// empty size
|
||||
if n == 0 {return String::from("empty")}
|
||||
|
||||
// terabytes, gigabytes, megabytes, kilobytes
|
||||
for i in 4..=1
|
||||
{
|
||||
if n >= 1000u64.pow(i)
|
||||
{
|
||||
for i in 4..=1 {
|
||||
if n >= 1000u64.pow(i) {
|
||||
let x = n as f64 / 1000f64.powi(i as i32);
|
||||
return format!("{:1}{}", x, names[i as usize - 1])
|
||||
return format!("{:1}{}", x, NAMES[i as usize - 1])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,14 +36,11 @@ pub fn fuck_string(s: &[u8]) -> Vec<u8>
|
|||
/// Converts input from Mac Roman to a Unicode string.
|
||||
pub fn mac_roman_conv(s: &[u8]) -> String
|
||||
{
|
||||
let l = s.len();
|
||||
let mut v = String::with_capacity(l);
|
||||
let mut v = String::with_capacity(s.len());
|
||||
|
||||
for i in 0..l
|
||||
{
|
||||
if s[i] == 0 {break}
|
||||
|
||||
if s[i] & 0x80 != 0 {v.push(TR[s[i] as usize & 0x7f])}
|
||||
for i in 0..s.len() {
|
||||
if s[i] == 0 {break}
|
||||
else if s[i] & 0x80 != 0 {v.push(TR[s[i] as usize & 0x7f])}
|
||||
else if s[i] == b'\r' {v.push('\n')}
|
||||
else {v.push(s[i] as char)}
|
||||
}
|
||||
|
|
59
src/main.rs
59
src/main.rs
|
@ -19,14 +19,13 @@ use crate::durandal::bin::ResultS;
|
|||
#[derive(Debug)]
|
||||
struct Minf
|
||||
{
|
||||
env: u16,
|
||||
phy: u16,
|
||||
mus: u16,
|
||||
mfl: u16,
|
||||
efl: u16,
|
||||
epf: u32,
|
||||
bip: bool,
|
||||
nam: String,
|
||||
env_code: u16,
|
||||
physi_id: u16,
|
||||
music_id: u16,
|
||||
msn_flag: u16,
|
||||
env_flag: u16,
|
||||
ent_flag: u32,
|
||||
levelnam: String,
|
||||
}
|
||||
|
||||
impl Minf
|
||||
|
@ -38,16 +37,15 @@ impl Minf
|
|||
|
||||
if b.len() < 88 {return Err("not enough data for Minf")}
|
||||
|
||||
let env = b.c_u16b( 0)?;
|
||||
let phy = b.c_u16b( 2)?;
|
||||
let mus = b.c_u16b( 4)?;
|
||||
let mfl = b.c_u16b( 6)?;
|
||||
let efl = b.c_u16b( 8)?;
|
||||
let bip = b[10] != 0;
|
||||
let nam = mac_roman_conv(&b[18..84]);
|
||||
let epf = b.c_u32b(84)?;
|
||||
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, phy, mus, mfl, efl, epf, bip, nam})
|
||||
Ok(Minf{env_code, physi_id, music_id, msn_flag, env_flag, ent_flag, levelnam})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,8 +57,7 @@ fn write_ppm(fname: &str, im: &Image) -> io::Result<()>
|
|||
write!(&mut out, "P3\n{} {}\n255\n", im.w(), im.h())?;
|
||||
|
||||
for y in 0..im.h() {
|
||||
for x in 0..im.w()
|
||||
{
|
||||
for x in 0..im.w() {
|
||||
let cr = &im[(x, y)];
|
||||
write!(&mut out, "{} {} {} ", cr.r, cr.g, cr.b)?;
|
||||
}
|
||||
|
@ -78,10 +75,8 @@ fn main() -> io::Result<()>
|
|||
|
||||
println!("{:#?}", wad);
|
||||
|
||||
for (id, ent) in wad.ent
|
||||
{
|
||||
if let Some(b) = ent.map.get(b"PICT")
|
||||
{
|
||||
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());
|
||||
|
@ -91,19 +86,17 @@ fn main() -> io::Result<()>
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(b) = ent.map.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),
|
||||
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.map.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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,7 @@ impl Terminal
|
|||
|
||||
let mut p = SIZE_HEAD;
|
||||
|
||||
for _ in 0..gnu
|
||||
{
|
||||
for _ in 0..gnu {
|
||||
// flg = b.c_u16b(p )?;
|
||||
let typ = b.c_u16b(p+ 2)?.into();
|
||||
let per = b.c_i16b(p+ 4)?;
|
||||
|
@ -43,8 +42,7 @@ impl Terminal
|
|||
p += SIZE_GROUP;
|
||||
}
|
||||
|
||||
for _ in 0..fnu
|
||||
{
|
||||
for _ in 0..fnu {
|
||||
let ind = b.c_u16b(p )?;
|
||||
let fce = b.c_u16b(p+2)?;
|
||||
let col = b.c_u16b(p+4)?;
|
||||
|
@ -62,8 +60,7 @@ impl Terminal
|
|||
let mut v = Vec::new();
|
||||
let mut p = 0;
|
||||
|
||||
while p < b.len()
|
||||
{
|
||||
while p < b.len() {
|
||||
let sta = p;
|
||||
|
||||
let (len, trm) = Terminal::read(&b[p..])?;
|
||||
|
|
|
@ -13,27 +13,27 @@ type EntryMap<'a> = BTreeMap<u16 , Entry<'a>>;
|
|||
|
||||
pub struct Entry<'a>
|
||||
{
|
||||
pub map: ChunkMap<'a>,
|
||||
pub ext: &'a[u8],
|
||||
pub chunks: ChunkMap<'a>,
|
||||
pub appdata: &'a[u8],
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Wad<'a>
|
||||
{
|
||||
ver: Ver,
|
||||
dvr: u16,
|
||||
ext: usize,
|
||||
nam: String,
|
||||
pub ent: EntryMap<'a>,
|
||||
wadver: Ver,
|
||||
dataver: u16,
|
||||
origname: String,
|
||||
appsize: usize,
|
||||
pub entries: EntryMap<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Ver
|
||||
{
|
||||
MI,
|
||||
M2,
|
||||
M1Dir,
|
||||
M1
|
||||
Base,
|
||||
Dir,
|
||||
Over,
|
||||
MI
|
||||
}
|
||||
|
||||
impl<'a> fmt::Debug for Entry<'a>
|
||||
|
@ -41,7 +41,7 @@ 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[..]))?}
|
||||
for (ident, _) in &self.chunks {write!(f, "{} ", mac_roman_conv(ident))?}
|
||||
write!(f, "}}")
|
||||
}
|
||||
}
|
||||
|
@ -50,79 +50,74 @@ impl<'a> Wad<'a>
|
|||
{
|
||||
pub fn new(b: &[u8]) -> ResultS<Wad>
|
||||
{
|
||||
const SIZE_ENTRY_NEW: usize = 10;
|
||||
const SIZE_ENTRY_OLD: usize = 8;
|
||||
|
||||
let b = &b[try_mac_header(b)..];
|
||||
if b.len() < 128 {return Err("not enough data for header")}
|
||||
if b.len() < 128 {return Err("not enough data for Wad header")}
|
||||
|
||||
let ver = b.c_u16b( 0)?;
|
||||
let dvr = b.c_u16b( 2)?;
|
||||
let nam = &b[4..68];
|
||||
// crc = b.c_u32b(68)?;
|
||||
let dir = b.c_u32b(72)? as usize;
|
||||
let num = b.c_u16b(76)? as usize;
|
||||
let ext = b.c_u16b(78)? as usize;
|
||||
// hdr = b.c_u16b(80)?;
|
||||
// bsz = b.c_u16b(82)?;
|
||||
// pck = b.c_u32b(84)?;
|
||||
let wadver = b.c_u16b( 0)?;
|
||||
let dataver = b.c_u16b( 2)?;
|
||||
let origname = mac_roman_conv(&b[4..68]);
|
||||
// crc = b.c_u32b(68)?;
|
||||
let dirofs = b.c_u32b(72)? as usize;
|
||||
let numents = b.c_u16b(76)? as usize;
|
||||
let appsize = b.c_u16b(78)? as usize;
|
||||
// chnksize = b.c_u16b(80)?;
|
||||
// entsize = b.c_u16b(82)?;
|
||||
// parent = b.c_u32b(84)?;
|
||||
|
||||
let ver = match ver {
|
||||
let wadver = match wadver {
|
||||
4 => Ver::MI,
|
||||
2 => Ver::M2,
|
||||
1 => Ver::M1Dir,
|
||||
0 => Ver::M1,
|
||||
_ => return Err("invalid wad version"),
|
||||
2 => Ver::Over,
|
||||
1 => Ver::Dir,
|
||||
0 => Ver::Base,
|
||||
_ => return Err("invalid Wad version"),
|
||||
};
|
||||
|
||||
let mut map = EntryMap::new();
|
||||
let mut p = dir;
|
||||
let o = match ver {Ver::M1 | Ver::M1Dir => true, _ => false};
|
||||
let h = if o {SIZE_ENTRY_OLD} else {SIZE_ENTRY_NEW};
|
||||
let is_old = match wadver {Ver::Base => true, _ => false};
|
||||
let entsize = if is_old {8} else {10};
|
||||
|
||||
for i in 0..num
|
||||
let mut entries = EntryMap::new();
|
||||
let mut p = dirofs;
|
||||
|
||||
for i in 0..numents
|
||||
{
|
||||
let ofs = b.c_u32b(p )? as usize;
|
||||
let len = b.c_u32b(p+4)? as usize;
|
||||
let ind = if o {i as u16}
|
||||
else {b.c_u16b(p+8)?};
|
||||
let offset = b.c_u32b(p )? as usize;
|
||||
let size = b.c_u32b(p+4)? as usize;
|
||||
let index = if !is_old {b.c_u16b(p+8)?} else {i as u16};
|
||||
|
||||
if ofs + len > b.len() {return Err("not enough data for entry")}
|
||||
if offset + size > b.len() {return Err("not enough data for entry")}
|
||||
|
||||
let ent = Entry{map: get_chunks(&b[ofs..ofs+len], o)?,
|
||||
ext: &b[p+h..p+h+ext]};
|
||||
let chunks = get_chunks(&b[offset..offset+size], is_old)?;
|
||||
let appdata = &b[p+entsize..p+entsize+appsize];
|
||||
|
||||
map.insert(ind, ent);
|
||||
entries.insert(index, Entry{chunks, appdata});
|
||||
|
||||
p += h + ext;
|
||||
p += entsize + appsize;
|
||||
}
|
||||
|
||||
Ok(Wad{ver, dvr, ext,
|
||||
nam: mac_roman_conv(nam),
|
||||
ent: map})
|
||||
Ok(Wad{wadver, dataver, appsize, origname, entries})
|
||||
}
|
||||
}
|
||||
|
||||
fn get_chunks(b: &[u8], o: bool) -> ResultS<ChunkMap>
|
||||
fn get_chunks(b: &[u8], is_old: bool) -> ResultS<ChunkMap>
|
||||
{
|
||||
const SIZE_CHUNK_NEW: usize = 16;
|
||||
const SIZE_CHUNK_OLD: usize = 12;
|
||||
let chnksize = if !is_old {16} else {12};
|
||||
|
||||
let mut map = ChunkMap::new();
|
||||
let mut p = 0;
|
||||
let h = if o {SIZE_CHUNK_OLD} else {SIZE_CHUNK_NEW};
|
||||
let mut chunks = ChunkMap::new();
|
||||
let mut p = 0;
|
||||
|
||||
while p < b.len()
|
||||
{
|
||||
let k = b.c_iden(p )?;
|
||||
// nx = b.c_u32b(p+ 4)?;
|
||||
let l = b.c_u32b(p+ 8)? as usize;
|
||||
// o = b.c_u32b(p+12)?;
|
||||
map.insert(k, &b[p+h ..p+h+l]);
|
||||
p += l + h;
|
||||
let ident = b.c_iden(p )?;
|
||||
// offset = b.c_u32b(p+ 4)?;
|
||||
let size = b.c_u32b(p+ 8)? as usize;
|
||||
// patchofs = b.c_u32b(p+12)?;
|
||||
let beg = p + chnksize;
|
||||
let end = beg + size;
|
||||
chunks.insert(ident, &b[beg..end]);
|
||||
p = end;
|
||||
}
|
||||
|
||||
Ok(map)
|
||||
Ok(chunks)
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
Loading…
Reference in New Issue