clarity over brevity
parent
9a8573a381
commit
7e0a91cd2b
|
@ -35,20 +35,29 @@ impl BinUtil for [u8]
|
|||
{
|
||||
fn c_iden(&self, i: usize) -> ResultS<Ident>
|
||||
{
|
||||
if i + 3 >= self.len() {return Err(err_msg("not enough data"));}
|
||||
Ok([self[i], self[i+1], self[i+2], self[i+3]])
|
||||
if i + 3 < self.len() {
|
||||
Ok([self[i], self[i + 1], self[i + 2], self[i + 3]])
|
||||
} else {
|
||||
Err(err_msg("not enough data"))
|
||||
}
|
||||
}
|
||||
|
||||
fn c_u32b(&self, i: usize) -> ResultS<u32>
|
||||
{
|
||||
if i + 3 >= self.len() {return Err(err_msg("not enough data"));}
|
||||
Ok(u32::from_be_bytes([self[i], self[i+1], self[i+2], self[i+3]]))
|
||||
if i + 3 < self.len() {
|
||||
Ok(u32::from_be_bytes([self[i], self[i + 1], self[i + 2], self[i + 3]]))
|
||||
} else {
|
||||
Err(err_msg("not enough data"))
|
||||
}
|
||||
}
|
||||
|
||||
fn c_u16b(&self, i: usize) -> ResultS<u16>
|
||||
{
|
||||
if i + 1 >= self.len() {return Err(err_msg("not enough data"));}
|
||||
Ok(u16::from_be_bytes([self[i], self[i+1]]))
|
||||
if i + 1 < self.len() {
|
||||
Ok(u16::from_be_bytes([self[i], self[i + 1]]))
|
||||
} else {
|
||||
Err(err_msg("not enough data"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
//! Traits for data which can be read as a sized array.
|
||||
|
||||
use crate::durandal::err::*;
|
||||
|
||||
pub trait Chunked<T>
|
||||
{
|
||||
const SIZE_CHUNK: usize;
|
||||
fn read(b: &[u8]) -> ResultS<T>;
|
||||
}
|
||||
|
||||
pub trait Chunker<T>
|
||||
{
|
||||
fn chunk(b: &[u8]) -> ResultS<T>;
|
||||
}
|
||||
|
||||
impl<T: Chunked<T>> Chunker<Vec<T>> for T
|
||||
{
|
||||
fn chunk(b: &[u8]) -> ResultS<Vec<T>>
|
||||
|
@ -16,16 +29,4 @@ impl<T: Chunked<T>> Chunker<Vec<T>> for T
|
|||
}
|
||||
}
|
||||
|
||||
pub trait Chunked<T>
|
||||
{
|
||||
const SIZE_CHUNK: usize;
|
||||
|
||||
fn read(b: &[u8]) -> ResultS<T>;
|
||||
}
|
||||
|
||||
pub trait Chunker<T>
|
||||
{
|
||||
fn chunk(b: &[u8]) -> ResultS<T>;
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Cyclic redundancy check function.
|
||||
|
||||
fn crc_accum(a: u32) -> u32
|
||||
{
|
||||
if a & 1 == 1 {0xedb88320 ^ a >> 1}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Error handling.
|
||||
|
||||
pub use failure::{Error, Fail, err_msg, format_err};
|
||||
pub use failure::{Error, Fail, err_msg};
|
||||
|
||||
use crate::durandal::traits::PrimInt;
|
||||
use std::fmt;
|
||||
|
|
|
@ -8,9 +8,9 @@ impl Fx32
|
|||
const FRACMASK: u32 = 0xFFFF;
|
||||
const ONE: i32 = 1 << Fx32::FRACBITS;
|
||||
|
||||
pub fn to_bits(&self) -> u32 {self.0 as u32}
|
||||
pub fn to_bits(&self) -> u32 {self.0 as u32}
|
||||
pub fn set_bits(&mut self, bits: u32) {self.0 = bits as i32}
|
||||
pub fn from_bits(bits: u32) -> Fx32 {Fx32(bits as i32)}
|
||||
pub fn from_bits(bits: u32) -> Fx32 {Fx32( bits as i32)}
|
||||
|
||||
pub fn integ(&self) -> i16 {(self.0 >> Fx32::FRACBITS) as i16}
|
||||
pub fn fract(&self) -> u16 {(self.0 as u32 & Fx32::FRACMASK) as u16}
|
||||
|
@ -22,9 +22,16 @@ impl Fx32
|
|||
impl From<i32> for Fx32 {fn from(n: i32) -> Fx32 {Fx32(n << Fx32::FRACBITS)}}
|
||||
|
||||
impl ops::Add for Fx32
|
||||
{type Output = Fx32; fn add(self, o: Fx32) -> Fx32 {Fx32(self.0 + o.0)}}
|
||||
{
|
||||
type Output = Fx32;
|
||||
fn add(self, o: Fx32) -> Fx32 {Fx32(self.0 + o.0)}
|
||||
}
|
||||
|
||||
impl ops::Sub for Fx32
|
||||
{type Output = Fx32; fn sub(self, o: Fx32) -> Fx32 {Fx32(self.0 - o.0)}}
|
||||
{
|
||||
type Output = Fx32;
|
||||
fn sub(self, o: Fx32) -> Fx32 {Fx32(self.0 - o.0)}
|
||||
}
|
||||
|
||||
impl ops::Mul for Fx32
|
||||
{
|
||||
|
@ -41,9 +48,16 @@ impl ops::Div for Fx32
|
|||
}
|
||||
|
||||
impl ops::Neg for Fx32
|
||||
{type Output = Fx32; fn neg(self) -> Fx32 {Fx32(-self.0)}}
|
||||
{
|
||||
type Output = Fx32;
|
||||
fn neg(self) -> Fx32 {Fx32(-self.0)}
|
||||
}
|
||||
|
||||
impl ops::Not for Fx32
|
||||
{type Output = Fx32; fn not(self) -> Fx32 {Fx32(!self.0)}}
|
||||
{
|
||||
type Output = Fx32;
|
||||
fn not(self) -> Fx32 {Fx32(!self.0)}
|
||||
}
|
||||
|
||||
impl fmt::Display for Fx32
|
||||
{
|
||||
|
|
|
@ -39,9 +39,7 @@ impl Image
|
|||
{
|
||||
/// Creates a new Image structure.
|
||||
pub fn new(w: usize, h: usize) -> Image
|
||||
{
|
||||
Image{w, h, cr: Vec::with_capacity(w * h)}
|
||||
}
|
||||
{Image{w, h, cr: Vec::with_capacity(w * h)}}
|
||||
|
||||
pub fn w(&self) -> usize {self.w}
|
||||
pub fn h(&self) -> usize {self.h}
|
||||
|
@ -52,17 +50,13 @@ impl Index<(usize, usize)> for Image
|
|||
type Output = Color;
|
||||
|
||||
fn index(&self, (x, y): (usize, usize)) -> &Color
|
||||
{
|
||||
&self.cr[x + y * self.w]
|
||||
}
|
||||
{&self.cr[x + y * self.w]}
|
||||
}
|
||||
|
||||
impl IndexMut<(usize, usize)> for Image
|
||||
{
|
||||
fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Color
|
||||
{
|
||||
&mut self.cr[x + y * self.w]
|
||||
}
|
||||
{&mut self.cr[x + y * self.w]}
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -32,7 +32,7 @@ pub fn to_binsize(n: u64) -> String
|
|||
for i in (1..=4).rev() {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,8 @@ impl Chunked<Line> for Line
|
|||
let poly_f = b.c_u16b(16)?;
|
||||
let poly_b = b.c_u16b(18)?;
|
||||
let flags = LineFlags::from_bits_truncate(flags);
|
||||
Ok(Line{flags, length, adj_hi, adj_lo, epnt_f, epnt_b, side_f, side_b, poly_f, poly_b})
|
||||
Ok(Line{flags, length, adj_hi, adj_lo, epnt_f, epnt_b, side_f, side_b,
|
||||
poly_f, poly_b})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,7 +103,8 @@ impl Chunker<Minf> for Minf
|
|||
let msn_flag = MsnFlags::from_bits_truncate(msn_flag);
|
||||
let env_flag = EnvFlags::from_bits_truncate(env_flag);
|
||||
let ent_flag = EntFlags::from_bits_truncate(ent_flag);
|
||||
Ok(Minf{env_code, physi_id, music_id, msn_flag, env_flag, ent_flag, levelnam})
|
||||
Ok(Minf{env_code, physi_id, music_id, msn_flag, env_flag, ent_flag,
|
||||
levelnam})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,9 +262,7 @@ bitflags! {
|
|||
impl fmt::Debug for Point
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
|
||||
{
|
||||
write!(f, "({}, {})", self.x, self.y)
|
||||
}
|
||||
{write!(f, "({}, {})", self.x, self.y)}
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -33,12 +33,10 @@ pub fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Re
|
|||
// planeofs = b.c_u32b(p+34)?;
|
||||
// clut_id = b.c_u32b(p+38)?;
|
||||
|
||||
if pitch_fl & 0x8000 == 0 {
|
||||
return Err(err_msg("PICT1 not supported"));
|
||||
}
|
||||
if right - left != w || bottom - top != h {
|
||||
return Err(err_msg("image bounds are incorrect"));
|
||||
}
|
||||
if pitch_fl & 0x8000 == 0
|
||||
{return Err(err_msg("PICT1 not supported"));}
|
||||
if right - left != w || bottom - top != h
|
||||
{return Err(err_msg("image bounds are incorrect"));}
|
||||
|
||||
p += 46; // size of header
|
||||
|
||||
|
@ -55,7 +53,7 @@ pub fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Re
|
|||
|
||||
if clip {p += b.c_u16b(p)? as usize;} // maskRgn
|
||||
|
||||
let rle = pack_typ == PACK_DEFAULT ||
|
||||
let rle = pack_typ == PACK_DEFAULT ||
|
||||
(pack_typ == PACK_RLE16 && depth == 16) ||
|
||||
(pack_typ == PACK_RLE32 && depth == 32);
|
||||
|
||||
|
@ -85,8 +83,9 @@ pub fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Re
|
|||
}
|
||||
|
||||
Ok(im)
|
||||
} else {
|
||||
Err(err_msg("invalid configuration"))
|
||||
}
|
||||
else {Err(err_msg("invalid configuration"))}
|
||||
},
|
||||
16 =>
|
||||
if pitch < 8 || pack_typ == PACK_NONE {
|
||||
|
@ -109,8 +108,9 @@ pub fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Re
|
|||
}
|
||||
|
||||
Ok(im)
|
||||
}
|
||||
else {Err(err_msg("invalid configuration"))},
|
||||
} else {
|
||||
Err(err_msg("invalid configuration"))
|
||||
},
|
||||
32 =>
|
||||
if pitch < 8 || pack_typ == PACK_NONE || pack_typ == PACK_NOPAD {
|
||||
// uncompressed RGB8 or XRGB8
|
||||
|
@ -139,8 +139,9 @@ pub fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Re
|
|||
}
|
||||
|
||||
Ok(im)
|
||||
}
|
||||
else {Err(err_msg("invalid configuration"))},
|
||||
} else {
|
||||
Err(err_msg("invalid configuration"))
|
||||
},
|
||||
_ => Err(err_msg("invalid bit depth"))
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +242,7 @@ pub fn get_clut(b: &[u8]) -> ResultS<(Vec<Color>, usize)>
|
|||
|
||||
for i in 0..num {
|
||||
// with device mapping, we ignore the index entirely
|
||||
let n = if !dev {b[p + 1] as usize} else {i};
|
||||
let n = if !dev {b[p+1] as usize} else {i};
|
||||
let r = b[p+2];
|
||||
let g = b[p+4];
|
||||
let b = b[p+6];
|
||||
|
@ -270,8 +271,11 @@ pub fn read_rle(b: &[u8], pitch: usize, ln: bool) -> ResultS<(Vec<u8>, usize)>
|
|||
|
||||
o.reserve(len);
|
||||
|
||||
if ln {read_rle_data(cmp, len, &mut o, || (arr![u8; b[p], b[p+1]], p += 2).0)}
|
||||
else {read_rle_data(cmp, len, &mut o, || (arr![u8; b[p] ], p += 1).0)}
|
||||
if ln {
|
||||
read_rle_data(cmp, len, &mut o, || (arr![u8; b[p], b[p+1]], p += 2).0);
|
||||
} else {
|
||||
read_rle_data(cmp, len, &mut o, || (arr![u8; b[p] ], p += 1).0);
|
||||
}
|
||||
}
|
||||
|
||||
if o.len() == pitch {Ok((o, p))}
|
||||
|
@ -303,7 +307,7 @@ pub fn expand_data(b: Vec<u8>, depth: u16) -> ResultS<Vec<u8>>
|
|||
|
||||
for ch in b {
|
||||
match depth {
|
||||
4 => for i in 1..=0 {o.push(ch >> i * 4 & 0xfu8);}, // 2 nibbles
|
||||
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
|
||||
1 => for i in 7..=0 {o.push(ch >> i * 1 & 0x1u8);}, // 8 bits
|
||||
_ => return Err(err_msg("invalid bit depth"))
|
||||
|
|
|
@ -16,13 +16,17 @@ impl Wad<'_>
|
|||
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)?;
|
||||
let wcnksize = b.c_u16b(80)? as usize;
|
||||
let wentsize = b.c_u16b(82)? as usize;
|
||||
// parent = b.c_u32b(84)?;
|
||||
let wadver = Ver::from_repr(wadver)?;
|
||||
|
||||
let wadver = Ver::from_repr(wadver)?;
|
||||
let is_old = match wadver {Ver::Base => true, _ => false};
|
||||
let entsize = if is_old {8} else {10};
|
||||
let entsize = if !is_old {10} else {8 };
|
||||
let cnksize = if !is_old {16} else {12};
|
||||
|
||||
if entsize != wentsize {return Err(err_msg("invalid entry size"));}
|
||||
if cnksize != wcnksize {return Err(err_msg("invalid chunk size"));}
|
||||
|
||||
let mut entries = EntryMap::new();
|
||||
let mut p = dirofs;
|
||||
|
@ -34,7 +38,7 @@ impl Wad<'_>
|
|||
|
||||
if offset + size > b.len() {return Err(err_msg("not enough data for entry"));}
|
||||
|
||||
let chunks = get_chunks(&b[offset..offset+size], is_old)?;
|
||||
let chunks = get_chunks(&b[offset..offset+size], cnksize)?;
|
||||
let appdata = &b[p..p+appsize];
|
||||
|
||||
entries.insert(index, Entry{chunks, appdata});
|
||||
|
@ -46,21 +50,19 @@ impl Wad<'_>
|
|||
}
|
||||
}
|
||||
|
||||
fn get_chunks(b: &[u8], is_old: bool) -> ResultS<ChunkMap>
|
||||
fn get_chunks(b: &[u8], cnksize: usize) -> ResultS<ChunkMap>
|
||||
{
|
||||
let chnksize = if !is_old {16} else {12};
|
||||
|
||||
let mut chunks = ChunkMap::new();
|
||||
let mut p = 0;
|
||||
|
||||
while p < b.len() {
|
||||
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]);
|
||||
let iden = b.c_iden(p )?;
|
||||
// ofs = b.c_u32b(p+ 4)?;
|
||||
let size = b.c_u32b(p+ 8)? as usize;
|
||||
// pofs = b.c_u32b(p+12)?;
|
||||
let beg = p + cnksize;
|
||||
let end = beg + size;
|
||||
chunks.insert(iden, &b[beg..end]);
|
||||
p = end;
|
||||
}
|
||||
|
||||
|
@ -103,8 +105,8 @@ impl fmt::Debug for Entry<'_>
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
|
||||
{
|
||||
write!(f, "Entry{{ ")?;
|
||||
for (ident, _) in &self.chunks {write!(f, "{} ", mac_roman_conv(ident))?;}
|
||||
if self.appdata.len() != 0{write!(f, "\nappdata: {:?} ", self.appdata)?;}
|
||||
for (iden, _) in &self.chunks {write!(f, "{} ", mac_roman_conv(iden))?;}
|
||||
if self.appdata.len() != 0 {write!(f, "\nappdata: {:?} ", self.appdata)?;}
|
||||
write!(f, "}}")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue