From 7e5375f32c6bf5509c48c942b52fae194be0c4ce Mon Sep 17 00:00:00 2001 From: Marrub Date: Mon, 18 Mar 2019 15:31:14 -0400 Subject: [PATCH] change read_data API --- source/durandal/bin.rs | 185 ++++++++++++--------- source/marathon/defl.rs | 38 +++-- source/marathon/map.rs | 319 ++++++++++++++++++------------------ source/marathon/phy.rs | 350 ++++++++++++++++++++-------------------- source/marathon/pict.rs | 59 +++---- source/marathon/shp.rs | 124 +++++++------- source/marathon/snd.rs | 53 +++--- source/marathon/trm.rs | 38 ++--- source/marathon/wad.rs | 40 ++--- 9 files changed, 620 insertions(+), 586 deletions(-) diff --git a/source/durandal/bin.rs b/source/durandal/bin.rs index 0be9177..e5124a5 100644 --- a/source/durandal/bin.rs +++ b/source/durandal/bin.rs @@ -5,75 +5,92 @@ use std::{fmt, num::NonZeroU16}; #[doc(hidden)] #[macro_export] -macro_rules! _durandal_read_impl { +macro_rules! _rd_impl { // big endian - (BE $b:expr; $nam:ident u16 $n:expr) => { - _durandal_read_impl!($b; u16::from_be_bytes, $nam 2 $n); + (BIG $b:expr; $nam:ident u16 $n:expr; $at:expr) => { + _rd_impl!($b; u16::from_be_bytes, $nam 2 $n + $at); }; - (BE $b:expr; $nam:ident i16 $n:expr) => { - _durandal_read_impl!($b; i16::from_be_bytes, $nam 2 $n); + (BIG $b:expr; $nam:ident i16 $n:expr; $at:expr) => { + _rd_impl!($b; i16::from_be_bytes, $nam 2 $n + $at); }; - (BE $b:expr; $nam:ident u32 $n:expr) => { - _durandal_read_impl!($b; u32::from_be_bytes, $nam 4 $n); + (BIG $b:expr; $nam:ident u32 $n:expr; $at:expr) => { + _rd_impl!($b; u32::from_be_bytes, $nam 4 $n + $at); }; - (BE $b:expr; $nam:ident i32 $n:expr) => { - _durandal_read_impl!($b; i32::from_be_bytes, $nam 4 $n); + (BIG $b:expr; $nam:ident i32 $n:expr; $at:expr) => { + _rd_impl!($b; i32::from_be_bytes, $nam 4 $n + $at); }; - // little endian - (LE $b:expr; $nam:ident u16 $n:expr) => { - _durandal_read_impl!($b; u16::from_le_bytes, $nam 2 $n); + (LITTLE $b:expr; $nam:ident u16 $n:expr; $at:expr) => { + _rd_impl!($b; u16::from_le_bytes, $nam 2 $n + $at); }; - (LE $b:expr; $nam:ident i16 $n:expr) => { - _durandal_read_impl!($b; i16::from_le_bytes, $nam 2 $n); + (LITTLE $b:expr; $nam:ident i16 $n:expr; $at:expr) => { + _rd_impl!($b; i16::from_le_bytes, $nam 2 $n + $at); }; - (LE $b:expr; $nam:ident u32 $n:expr) => { - _durandal_read_impl!($b; u32::from_le_bytes, $nam 4 $n); + (LITTLE $b:expr; $nam:ident u32 $n:expr; $at:expr) => { + _rd_impl!($b; u32::from_le_bytes, $nam 4 $n + $at); }; - (LE $b:expr; $nam:ident i32 $n:expr) => { - _durandal_read_impl!($b; i32::from_le_bytes, $nam 4 $n); + (LITTLE $b:expr; $nam:ident i32 $n:expr; $at:expr) => { + _rd_impl!($b; i32::from_le_bytes, $nam 4 $n + $at); }; // either endianness - ($e:ident $b:expr; $nam:ident Angle $n:expr) => { - _durandal_read_impl!($e $b; $nam u16 $n); + ($e:ident $b:expr; $nam:ident Angle $n:expr; $at:expr) => { + _rd_impl!($e $b; $nam u16 $n; $at); let $nam = Angle::from_bits($nam); }; - ($e:ident $b:expr; $nam:ident Fixed $n:expr) => { - _durandal_read_impl!($e $b; $nam u32 $n); + ($e:ident $b:expr; $nam:ident Fixed $n:expr; $at:expr) => { + _rd_impl!($e $b; $nam u32 $n; $at); let $nam = Fixed::from_bits($nam); }; - ($e:ident $b:expr; $nam:ident Unit $n:expr) => { - _durandal_read_impl!($e $b; $nam u16 $n); + ($e:ident $b:expr; $nam:ident Unit $n:expr; $at:expr) => { + _rd_impl!($e $b; $nam u16 $n; $at); let $nam = Unit::from_bits($nam); }; - ($e:ident $b:expr; $nam:ident OptU16 $n:expr) => { - _durandal_read_impl!($e $b; $nam u16 $n); + ($e:ident $b:expr; $nam:ident OptU16 $n:expr; $at:expr) => { + _rd_impl!($e $b; $nam u16 $n; $at); let $nam = OptU16::from($nam); }; - ($e:ident $b:expr; $nam:ident usize u16 $n:expr) => { - _durandal_read_impl!($e $b; $nam u16 $n); + ($e:ident $b:expr; $nam:ident usize u16 $n:expr; $at:expr) => { + _rd_impl!($e $b; $nam u16 $n; $at); let $nam = usize::from($nam); }; - ($e:ident $b:expr; $nam:ident usize u32 $n:expr) => { - _durandal_read_impl!($e $b; $nam u32 $n); + ($e:ident $b:expr; $nam:ident usize u32 $n:expr; $at:expr) => { + _rd_impl!($e $b; $nam u32 $n; $at); let $nam = usize_from_u32($nam); }; + ( + $e:ident $b:expr; $nam:ident enum $et:ident $t:ident $n:expr; $at:expr + ) => { + _rd_impl!($e $b; $nam $t $n; $at); + let $nam = $et::try_from($nam)?; + }; + ( + $e:ident $b:expr; $nam:ident flag $ft:ident $t:ident $n:expr; $at:expr + ) => { + _rd_impl!($e $b; $nam $t $n; $at); + let $nam = flag_ok!($ft, $nam)?; + }; // no endianness - ($_:ident $b:expr; $nam:ident u8 $n:expr) => {let $nam = $b[$n];}; - ($_:ident $b:expr; $nam:ident slice u8 $n:expr) => {let $nam = &$b[$n];}; - ($_:ident $b:expr; $nam:ident i8 $n:expr) => { - let $nam = i8::from_ne_bytes([$b[$n]]); + ($_:ident $b:expr; $nam:ident u8 $n:expr; $at:expr) => { + let $nam = $b[$n + $at]; }; - ($_:ident $b:expr; $nam:ident Ident $n:expr) => { - let $nam = Ident([$b[$n], $b[$n + 1], $b[$n + 2], $b[$n + 3]]); + ($_:ident $b:expr; $nam:ident i8 $n:expr; $at:expr) => { + let $nam = $b[$n + $at] as i8; }; - ($_:ident $b:expr; $nam:ident $f:ident $n:expr) => { - let $nam = $f(&$b[$n])?; + ($_:ident $b:expr; $nam:ident u8 $n:expr; $rn:expr; $at:expr) => { + let $nam = &$b[$n + $at..$n + $at + $rn]; }; - ($_:ident $b:expr; $nam:ident no_try $f:ident $n:expr) => { - let $nam = $f(&$b[$n]); + ($_:ident $b:expr; $nam:ident Ident $n:expr; $at:expr) => { + _rd_impl!($b; Ident, $nam 4 $n + $at); + }; + ( + $_:ident $b:expr; $nam:ident no_try $f:ident $n:expr; $rn:expr; $at:expr + ) => { + let $nam = $f(&$b[$n + $at..$n + $at + $rn]); + }; + ($_:ident $b:expr; $nam:ident $f:ident $n:expr; $rn:expr; $at:expr) => { + let $nam = $f(&$b[$n + $at..$n + $at + $rn])?; }; // worker - creates let statement @@ -89,23 +106,31 @@ macro_rules! _durandal_read_impl { /// /// # Syntax /// -/// First start by specifying the endianness, size and source using the syntax -/// `endian, size in source =>` where: +/// First start by specifying the basic information, using the syntax: +/// `endian: ENDIAN, buf: BUFFER, size: SIZE, start: START,` where: /// -/// - `endian` is `BE` or `LE` for big- or little-endian respectively. -/// - `size` is an expression specifying the last index that should be used by -/// this macro in `source`. -/// - `source` is a `u8` slice to read data from. +/// - `ENDIAN` is `BIG` or `LITTLE` for big- or little-endian respectively. +/// - `BUFFER` is a `u8` slice to read data from. This expression will be +/// evaluated many times, so be careful when specifying it. +/// - `SIZE` is an expression specifying the last index that should be used by +/// this macro in `BUFFER`. +/// - `START` is an expression specifying the index to start at in `BUFFER`. +/// All indices and sizes will have this added to them. /// -/// After the initializer line, all lines have the syntax -/// `name = type[place] opts;` where: +/// Following that is a block with the syntax `data { ... }`. All lines within +/// this block have the syntax `let NAME = TYPE[INDEX] OPTS;` where: /// -/// - `name` is the binding to put the resulting data in. -/// - `type` is one of: -/// - `u8` or `i8`: one byte will be read at `place`. -/// - `u16` or `i16`: two bytes will be read at `place` with `from_*_bytes`. -/// - `u32` or `i32`: four bytes will be read at `place` with `from_*_bytes`. -/// - `Ident`: four bytes will be read at `place` into an array, disregarding +/// - `NAME` is the binding to put the resulting data in. +/// - `TYPE` is one of: +/// - `u8` or `i8`: one byte will be read at `INDEX`. If `INDEX` is a range, +/// this will be a slice into `BUFFER` instead. +/// - `u16` or `i16`: two bytes will be read at `INDEX` with `from_*_bytes`. +/// If `OPTS` is `usize`, this converts the resulting number to `usize` by +/// using `usize::from`. +/// - `u32` or `i32`: four bytes will be read at `INDEX` with `from_*_bytes`. +/// If `OPTS` is `usize`, this converts the resulting number to `usize` by +/// using `usize_from_u32`. +/// - `Ident`: four bytes will be read at `INDEX` into an array, disregarding /// endianness, creating an `Ident` object. /// - `Angle`: same as `u16`, but the result is passed to /// `fixed::Angle::from_bits`, resulting in a `fixed::Angle` object. @@ -115,24 +140,20 @@ macro_rules! _durandal_read_impl { /// `fixed::Unit::from_bits`, resulting in a `fixed::Unit` object. /// - `OptU16`: same as `u16`, but the result is passed to /// `OptU16::from`, resulting in an `OptU16` object. -/// - The name of a function, which is passed `&source[place]` as its only -/// argument. The function's result has the `?` operator applied to it. -/// - `opts` may be one of: -/// - `slice` when `type` is `u8`: `place` is a range specifying a `u8` slice -/// to be taken from `source`. -/// - `usize` when `type` is `u16` or `u32`: converts the resulting integer to -/// `usize` by `usize_to_u32` for `u32` or by `from` for `u16`. -/// - `no_try` when `type` is a function name: does not use the `?` operator -/// on the resulting function call. -/// - Nothing at all. -/// - `place` is either an integer literal which must be representable as -/// `usize`, or a range, which may only be used when `type` is a function -/// name. +/// - The name of a function, which is passed the index range as its only +/// argument. The function's result has the `?` operator applied to it, +/// unless `OPTS` is `no_try`. +/// - `OPT`, if not one of the things listed above, may be `enum TYPE` to apply +/// an enumeration made by `c_enum!`, or `flag TYPE` to apply a bitfield made +/// by `bitflags!`. +/// - `INDEX` is either an integer literal which must be representable as +/// `usize`, or a range with the syntax `INDEX; SIZE` denoting the beginning +/// and size of the range. /// /// # Panics /// /// This macro will not panic unless any index expression used exceeds or -/// equals `size`. +/// equals `SIZE + START`, or a function passed to it panics. /// /// # Examples /// @@ -144,35 +165,37 @@ macro_rules! _durandal_read_impl { /// let buffer = &[4, 0, 2, 0, 0, 0, 6]; /// /// read_data! { -/// 7, LE in buffer => -/// four = u16[0]; -/// two = u32[2]; -/// six = u8 [6]; +/// endian: LITTLE, buf: buffer, size: 7, start: 0, data { +/// let four = u16[0]; +/// let two = u32[2]; +/// let six = u8[6]; +/// let byte = u8[2; 4]; +/// } /// } /// /// assert_eq!(four, 4_u16); /// assert_eq!(two, 2_u32); /// assert_eq!(six, 6_u8); +/// assert_eq!(byte, &[2, 0, 0, 0]); /// # Ok(()) /// # } /// ``` #[macro_export] macro_rules! read_data { ( - $sz:expr , $ty:ident in $b:expr => - $( $nam:ident = $t:ident [ $n:expr ] $( $ex:ident )* ; )* + endian: $ty:ident, buf: $b:expr, size: $sz:expr, start: $at:expr, data { + $(let $nam:ident = $t:ident[$n:expr $(; $rn:expr)?] $($ex:ident)*;)* + } ) => { - $crate::check_data!($sz, $b); - $($crate::_durandal_read_impl!($ty $b; $nam $($ex)* $t $n);)* + $crate::check_data!($at + $sz, $b); + $($crate::_rd_impl!($ty $b; $nam $($ex)* $t ($n); $(($rn);)? ($at));)* }; } /// Checks if there is enough data in `b`. #[macro_export] macro_rules! check_data { - ( - $sz:expr , $b:expr - ) => { + ($sz:expr, $b:expr) => { if $b.len() < $sz { return Err(err_msg("not enough data")); } @@ -220,6 +243,7 @@ pub const fn ident(b: &[u8]) -> Ident {Ident([b[0], b[1], b[2], b[3]])} /// /// assert_eq!(u32b(&[0x00, 0x0B, 0xDE, 0x31]), 777_777u32); /// ``` +#[inline] pub fn u32b(b: &[u8]) -> u32 {u32::from_be_bytes([b[0], b[1], b[2], b[3]])} /// Applies `u16::from_be_bytes` to a slice. @@ -235,6 +259,7 @@ pub fn u32b(b: &[u8]) -> u32 {u32::from_be_bytes([b[0], b[1], b[2], b[3]])} /// /// assert_eq!(u16b(&[0x1E, 0x61]), 7_777u16); /// ``` +#[inline] pub fn u16b(b: &[u8]) -> u16 {u16::from_be_bytes([b[0], b[1]])} /// Applies `i32::from_be_bytes` to a slice. @@ -250,6 +275,7 @@ pub fn u16b(b: &[u8]) -> u16 {u16::from_be_bytes([b[0], b[1]])} /// /// assert_eq!(i32b(&[0xFF, 0x89, 0x52, 0x0F]), -7_777_777i32); /// ``` +#[inline] pub fn i32b(b: &[u8]) -> i32 {i32::from_be_bytes([b[0], b[1], b[2], b[3]])} /// Applies `i16::from_be_bytes` to a slice. @@ -265,6 +291,7 @@ pub fn i32b(b: &[u8]) -> i32 {i32::from_be_bytes([b[0], b[1], b[2], b[3]])} /// /// assert_eq!(i16b(&[0xE1, 0x9F]), -7_777i16); /// ``` +#[inline] pub fn i16b(b: &[u8]) -> i16 {i16::from_be_bytes([b[0], b[1]])} /// Applies a read function over a slice. diff --git a/source/marathon/defl.rs b/source/marathon/defl.rs index 23f60d2..2580240 100644 --- a/source/marathon/defl.rs +++ b/source/marathon/defl.rs @@ -11,10 +11,11 @@ pub fn load_zlib_header(b: &[u8]) -> ResultS const FDICT: u8 = 0b0010_0000; read_data! { - 2, BE in b => - fcheck = u16[0]; - cmf = u8[0]; - flg = u8[1]; + endian: BIG, buf: b, size: 2, start: 0, data { + let fcheck = u16[0]; + let cmf = u8[0]; + let flg = u8[1]; + } } let cm = cmf & CM; @@ -49,10 +50,11 @@ pub fn load_gzip_header(b: &[u8]) -> ResultS const FRESERVED: u8 = 0xE0; read_data! { - 10, LE in b => - id = u16[0]; - cm = u8[2]; - fl = u8[3]; + endian: LITTLE, buf: b, size: 10, start: 0, data { + let id = u16[0]; + let cm = u8[2]; + let fl = u8[3]; + } } if id != 0x8B1F || cm != 8 { @@ -66,10 +68,15 @@ pub fn load_gzip_header(b: &[u8]) -> ResultS } if fl & FEXTRA != 0 { - read_data!(p + 2, LE in b => xlen = u16[p] usize;); - check_data!(p + 2 + xlen, b); + read_data! { + endian: LITTLE, buf: b, size: 2, start: p, data { + let xlen = u16[0] usize; + } + } - p += xlen; + p += 2 + xlen; + + check_data!(p, b); } if fl & FNAME != 0 { @@ -81,9 +88,9 @@ pub fn load_gzip_header(b: &[u8]) -> ResultS } if fl & FHCRC != 0 { - check_data!(p + 2, b); - p += 2; + + check_data!(p, b); } Ok(p) @@ -189,8 +196,9 @@ fn stream_literal(v: &mut Vec, b: &[u8], p: usize) -> ResultS let mut p = p / 8 + 1; read_data! { - p + 4, LE in b => - len = u16[p] usize; + endian: LITTLE, buf: b, size: 4, start: p, data { + let len = u16[0] usize; + } } p += 4; diff --git a/source/marathon/map.rs b/source/marathon/map.rs index 7381618..2da456c 100644 --- a/source/marathon/map.rs +++ b/source/marathon/map.rs @@ -8,16 +8,15 @@ use bitflags::bitflags; pub fn read_lightfunc(b: &[u8]) -> ResultS { read_data! { - 14, BE in b => - ftype = u16[0]; - prd_nrm = u16[2]; - prd_dta = u16[4]; - val_nrm = Fixed[6]; - val_dta = Fixed[10]; + endian: BIG, buf: b, size: 14, start: 0, data { + let ftype = u16[0] enum LightFuncType; + let prd_nrm = u16[2]; + let prd_dta = u16[4]; + let val_nrm = Fixed[6]; + let val_dta = Fixed[10]; + } } - let ftype = LightFuncType::try_from(ftype)?; - Ok(LightFunc{ftype, prd_nrm, prd_dta, val_nrm, val_dta}) } @@ -25,9 +24,10 @@ pub fn read_lightfunc(b: &[u8]) -> ResultS pub fn read_sidetex(b: &[u8]) -> ResultS { read_data! { - 6, BE in b => - offs = read_point[0..4]; - tex_id = OptU16[4]; + endian: BIG, buf: b, size: 6, start: 0, data { + let offs = read_point[0; 4]; + let tex_id = OptU16[4]; + } } Ok(SideTex{offs, tex_id}) @@ -37,9 +37,10 @@ pub fn read_sidetex(b: &[u8]) -> ResultS pub fn read_point(b: &[u8]) -> ResultS { read_data! { - 4, BE in b => - x = Unit[0]; - y = Unit[2]; + endian: BIG, buf: b, size: 4, start: 0, data { + let x = Unit[0]; + let y = Unit[2]; + } } Ok(Point{x, y}) @@ -49,20 +50,17 @@ pub fn read_point(b: &[u8]) -> ResultS pub fn read_minf(b: &[u8]) -> ResultS { read_data! { - 88, BE in b => - texture_id = u16[0]; - physics_id = u16[2]; - skypict_id = u16[4]; - miss_flags = u16[6]; - envi_flags = u16[8]; - level_name = mac_roman_cstr[18..84] no_try; - entr_flags = u32[84]; + endian: BIG, buf: b, size: 88, start: 0, data { + let texture_id = u16[0]; + let physics_id = u16[2]; + let skypict_id = u16[4]; + let miss_flags = u16[6] flag MsnFlags; + let envi_flags = u16[8] flag EnvFlags; + let level_name = mac_roman_cstr[18; 66] no_try; + let entr_flags = u32[84] flag EntFlags; + } } - let miss_flags = flag_ok!(MsnFlags, miss_flags)?; - let envi_flags = flag_ok!(EnvFlags, envi_flags)?; - let entr_flags = flag_ok!(EntFlags, entr_flags)?; - Ok(Minf{texture_id, physics_id, skypict_id, miss_flags, envi_flags, entr_flags, level_name}) } @@ -97,8 +95,9 @@ pub fn read_iidx(b: &[u8]) -> ResultS<(u16, usize)> pub fn read_epnt(b: &[u8]) -> ResultS<(Point, usize)> { read_data! { - 16, BE in b => - pnt = read_point[6..10]; + endian: BIG, buf: b, size: 16, start: 0, data { + let pnt = read_point[6; 4]; + } } Ok((pnt, 16)) @@ -114,18 +113,17 @@ pub fn read_pnts(b: &[u8]) -> ResultS<(Point, usize)> pub fn read_lins(b: &[u8]) -> ResultS<(Line, usize)> { read_data! { - 32, BE in b => - pnt_beg = u16[0]; - pnt_end = u16[2]; - flags = u16[4]; - side_fr = OptU16[12]; - side_bk = OptU16[14]; - poly_fr = OptU16[16]; - poly_bk = OptU16[18]; + endian: BIG, buf: b, size: 32, start: 0, data { + let pnt_beg = u16[0]; + let pnt_end = u16[2]; + let flags = u16[4] flag LineFlags; + let side_fr = OptU16[12]; + let side_bk = OptU16[14]; + let poly_fr = OptU16[16]; + let poly_bk = OptU16[18]; + } } - let flags = flag_ok!(LineFlags, flags)?; - Ok((Line{flags, pnt_beg, pnt_end, side_fr, side_bk, poly_fr, poly_bk}, 32)) } @@ -133,26 +131,21 @@ pub fn read_lins(b: &[u8]) -> ResultS<(Line, usize)> pub fn read_sids(b: &[u8]) -> ResultS<(Side, usize)> { read_data! { - 64, BE in b => - stype = u16[0]; - flags = u16[2]; - tex_pri = read_sidetex[4..10]; - tex_sec = read_sidetex[10..16]; - tex_tra = read_sidetex[16..22]; - paneltyp = u16[38]; - paneldat = i16[40]; - xfer_pri = u16[42]; - xfer_sec = u16[44]; - xfer_tra = u16[46]; - shade = Fixed[48]; + endian: BIG, buf: b, size: 64, start: 0, data { + let stype = u16[0] enum SideType; + let flags = u16[2] flag SideFlags; + let tex_pri = read_sidetex[4; 6]; + let tex_sec = read_sidetex[10; 6]; + let tex_tra = read_sidetex[16; 6]; + let paneltyp = u16[38]; + let paneldat = i16[40]; + let xfer_pri = u16[42] enum TransferMode; + let xfer_sec = u16[44] enum TransferMode; + let xfer_tra = u16[46] enum TransferMode; + let shade = Fixed[48]; + } } - let flags = flag_ok!(SideFlags, flags)?; - let xfer_pri = TransferMode::try_from(xfer_pri)?; - let xfer_sec = TransferMode::try_from(xfer_sec)?; - let xfer_tra = TransferMode::try_from(xfer_tra)?; - let stype = SideType::try_from(stype)?; - Ok((Side{stype, flags, tex_pri, tex_sec, tex_tra, paneltyp, paneldat, xfer_pri, xfer_sec, xfer_tra, shade}, 64)) } @@ -172,20 +165,18 @@ pub fn read_old_sids(b: &[u8]) -> ResultS<(Side, usize)> fn read_poly_inter(b: &[u8]) -> ResultS { read_data! { - 128, BE in b => - tex_flr = OptU16[40]; - tex_cei = OptU16[42]; - hei_flr = Unit[44]; - hei_cei = Unit[46]; - lit_flr = u16[48]; - lit_cei = u16[50]; - xfr_flr = u16[64]; - xfr_cei = u16[66]; + endian: BIG, buf: b, size: 128, start: 0, data { + let tex_flr = OptU16[40]; + let tex_cei = OptU16[42]; + let hei_flr = Unit[44]; + let hei_cei = Unit[46]; + let lit_flr = u16[48]; + let lit_cei = u16[50]; + let xfr_flr = u16[64] enum TransferMode; + let xfr_cei = u16[66] enum TransferMode; + } } - let xfr_flr = TransferMode::try_from(xfr_flr)?; - let xfr_cei = TransferMode::try_from(xfr_cei)?; - Ok(Polygon{tex_flr, tex_cei, hei_flr, hei_cei, lit_flr, lit_cei, xfr_flr, xfr_cei, ..Default::default()}) } @@ -194,16 +185,17 @@ fn read_poly_inter(b: &[u8]) -> ResultS pub fn read_poly(b: &[u8]) -> ResultS<(Polygon, usize)> { read_data! { - 128, BE in b => - ptype = u16[0]; - pdata = u16[4]; - ori_flr = read_point[108..112]; - ori_cei = read_point[112..116]; - med_ind = OptU16[116]; - med_ctl = u16[118]; - snd_amb = OptU16[122]; - snd_ind = u16[120]; - snd_rnd = OptU16[124]; + endian: BIG, buf: b, size: 128, start: 0, data { + let ptype = u16[0]; + let pdata = u16[4]; + let ori_flr = read_point[108; 4]; + let ori_cei = read_point[112; 4]; + let med_ind = OptU16[116]; + let med_ctl = u16[118]; + let snd_amb = OptU16[122]; + let snd_ind = u16[120]; + let snd_rnd = OptU16[124]; + } } let poly = read_poly_inter(b)?; @@ -217,9 +209,10 @@ pub fn read_poly(b: &[u8]) -> ResultS<(Polygon, usize)> pub fn read_old_poly(b: &[u8]) -> ResultS<(Polygon, usize)> { read_data! { - 128, BE in b => - ptype = u16[0]; - pdata = u16[4]; + endian: BIG, buf: b, size: 128, start: 0, data { + let ptype = u16[0]; + let pdata = u16[4]; + } } let poly = read_poly_inter(b)?; @@ -232,22 +225,20 @@ pub fn read_old_poly(b: &[u8]) -> ResultS<(Polygon, usize)> pub fn read_lite(b: &[u8]) -> ResultS<(Light, usize)> { read_data! { - 100, BE in b => - ltype = u16[0]; - flags = u16[2]; - phase = i16[4]; - act_pri = read_lightfunc[6..20]; - act_sec = read_lightfunc[20..34]; - act_mid = read_lightfunc[34..48]; - ina_pri = read_lightfunc[48..62]; - ina_sec = read_lightfunc[62..76]; - ina_mid = read_lightfunc[76..90]; - tag = u16[90]; + endian: BIG, buf: b, size: 100, start: 0, data { + let ltype = u16[0] enum LightType; + let flags = u16[2] flag LightFlags; + let phase = i16[4]; + let act_pri = read_lightfunc[6; 14]; + let act_sec = read_lightfunc[20; 14]; + let act_mid = read_lightfunc[34; 14]; + let ina_pri = read_lightfunc[48; 14]; + let ina_sec = read_lightfunc[62; 14]; + let ina_mid = read_lightfunc[76; 14]; + let tag = u16[90]; + } } - let flags = flag_ok!(LightFlags, flags)?; - let ltype = LightType::try_from(ltype)?; - Ok((Light{ltype, flags, phase, act_pri, act_sec, act_mid, ina_pri, ina_sec, ina_mid, tag}, 100)) } @@ -256,13 +247,14 @@ pub fn read_lite(b: &[u8]) -> ResultS<(Light, usize)> pub fn read_old_lite(b: &[u8]) -> ResultS<(Light, usize)> { read_data! { - 32, BE in b => - ltype = u16[2] usize; - mode = u16[4]; - phase = i16[6]; - min = Fixed[8]; - max = Fixed[12]; - prd = u16[16]; + endian: BIG, buf: b, size: 32, start: 0, data { + let ltype = u16[2] usize; + let mode = u16[4]; + let phase = i16[6]; + let min = Fixed[8]; + let max = Fixed[12]; + let prd = u16[16]; + } } if OLD_LIGHT_DEFINITIONS.len() < ltype { @@ -299,15 +291,16 @@ pub fn read_old_lite(b: &[u8]) -> ResultS<(Light, usize)> pub fn read_objs(b: &[u8]) -> ResultS<(Object, usize)> { read_data! { - 16, BE in b => - group = u16[0]; - index = u16[2]; - angle = Angle[4]; - poly = u16[6]; - pos_x = Unit[8]; - pos_y = Unit[10]; - pos_z = Unit[12]; - flags = u16[14]; + endian: BIG, buf: b, size: 16, start: 0, data { + let group = u16[0]; + let index = u16[2]; + let angle = Angle[4]; + let poly = u16[6]; + let pos_x = Unit[8]; + let pos_y = Unit[10]; + let pos_z = Unit[12]; + let flags = u16[14]; + } } let bias = flags & 0xF0_00; @@ -322,13 +315,14 @@ pub fn read_objs(b: &[u8]) -> ResultS<(Object, usize)> pub fn read_plac(b: &[u8]) -> ResultS<(ObjectFreq, usize)> { read_data! { - 12, BE in b => - flags = u16[0]; - cnt_ini = u16[2]; - cnt_min = u16[4]; - cnt_max = u16[6]; - cnt_rnd = u16[8]; - chance = u16[10]; + endian: BIG, buf: b, size: 12, start: 0, data { + let flags = u16[0]; + let cnt_ini = u16[2]; + let cnt_min = u16[4]; + let cnt_max = u16[6]; + let cnt_rnd = u16[8]; + let chance = u16[10]; + } } let rnd_loc = flags != 0; @@ -340,9 +334,10 @@ pub fn read_plac(b: &[u8]) -> ResultS<(ObjectFreq, usize)> pub fn read_ambi(b: &[u8]) -> ResultS<(SoundAmbi, usize)> { read_data! { - 16, BE in b => - index = u16[2]; - volume = u16[4]; + endian: BIG, buf: b, size: 16, start: 0, data { + let index = u16[2]; + let volume = u16[4]; + } } Ok((SoundAmbi{index, volume}, 16)) @@ -352,17 +347,18 @@ pub fn read_ambi(b: &[u8]) -> ResultS<(SoundAmbi, usize)> pub fn read_bonk(b: &[u8]) -> ResultS<(SoundRand, usize)> { read_data! { - 32, BE in b => - flags = u16[0]; - index = u16[2]; - vol_nrm = u16[4]; - vol_dta = u16[6]; - prd_nrm = u16[8]; - prd_dta = u16[10]; - yaw_nrm = Angle[12]; - yaw_dta = Angle[14]; - pit_nrm = Fixed[16]; - pit_dta = Fixed[20]; + endian: BIG, buf: b, size: 32, start: 0, data { + let flags = u16[0]; + let index = u16[2]; + let vol_nrm = u16[4]; + let vol_dta = u16[6]; + let prd_nrm = u16[8]; + let prd_dta = u16[10]; + let yaw_nrm = Angle[12]; + let yaw_dta = Angle[14]; + let pit_nrm = Fixed[16]; + let pit_dta = Fixed[20]; + } } let no_dir = flags != 0; @@ -375,23 +371,22 @@ pub fn read_bonk(b: &[u8]) -> ResultS<(SoundRand, usize)> pub fn read_medi(b: &[u8]) -> ResultS<(Media, usize)> { read_data! { - 32, BE in b => - mtype = u16[0]; - flags = u16[2]; - control = u16[4]; - dir = Angle[6]; - mag = Unit[8]; - hei_lo = Unit[10]; - hei_hi = Unit[12]; - orig = read_point[14..18]; - hei_nrm = Unit[18]; - min_lt = Fixed[20]; - texture = OptU16[24]; - xfer = u16[26]; + endian: BIG, buf: b, size: 32, start: 0, data { + let mtype = u16[0] enum MediaType; + let flags = u16[2]; + let control = u16[4]; + let dir = Angle[6]; + let mag = Unit[8]; + let hei_lo = Unit[10]; + let hei_hi = Unit[12]; + let orig = read_point[14; 4]; + let hei_nrm = Unit[18]; + let min_lt = Fixed[20]; + let texture = OptU16[24]; + let xfer = u16[26] enum TransferMode; + } } - let mtype = MediaType::try_from(mtype)?; - let xfer = TransferMode::try_from(xfer)?; let flr_obs = flags != 0; Ok((Media{mtype, flr_obs, control, dir, mag, hei_lo, hei_hi, orig, hei_nrm, @@ -402,19 +397,18 @@ pub fn read_medi(b: &[u8]) -> ResultS<(Media, usize)> pub fn read_plat(b: &[u8]) -> ResultS<(Platform, usize)> { read_data! { - 32, BE in b => - ptype = u16[0]; - speed = u16[2]; - delay = u16[4]; - hei_max = Unit[6]; - hei_min = Unit[8]; - flags = u32[10]; - index = u16[14]; - tag = u16[16]; + endian: BIG, buf: b, size: 32, start: 0, data { + let ptype = u16[0]; + let speed = u16[2]; + let delay = u16[4]; + let hei_max = Unit[6]; + let hei_min = Unit[8]; + let flags = u32[10] flag PlatformFlags; + let index = u16[14]; + let tag = u16[16]; + } } - let flags = flag_ok!(PlatformFlags, flags)?; - Ok((Platform{ptype, speed, delay, hei_min, hei_max, flags, index, tag}, 32)) } @@ -422,10 +416,11 @@ pub fn read_plat(b: &[u8]) -> ResultS<(Platform, usize)> pub fn read_note(b: &[u8]) -> ResultS<(Note, usize)> { read_data! { - 72, BE in b => - pos = read_point[2..6]; - poly = u16[6]; - text = mac_roman_cstr[8..72] no_try; + endian: BIG, buf: b, size: 72, start: 0, data { + let pos = read_point[2; 4]; + let poly = u16[6]; + let text = mac_roman_cstr[8; 64] no_try; + } } Ok((Note{pos, poly, text}, 72)) diff --git a/source/marathon/phy.rs b/source/marathon/phy.rs index 746edbc..80417d6 100644 --- a/source/marathon/phy.rs +++ b/source/marathon/phy.rs @@ -7,33 +7,34 @@ use bitflags::bitflags; pub fn read_pxpx(b: &[u8]) -> ResultS<(Physics, usize)> { read_data! { - 104, BE in b => - vel_fwd = Fixed[0]; - vel_bkw = Fixed[4]; - vel_prp = Fixed[8]; - acc_nrm = Fixed[12]; - dec_nrm = Fixed[16]; - dec_air = Fixed[20]; - acc_grv = Fixed[24]; - acc_cli = Fixed[28]; - vel_trm = Fixed[32]; - dec_ext = Fixed[36]; - acc_ang = Fixed[40]; - dec_ang = Fixed[44]; - vel_ang = Fixed[48]; - vel_rec = Fixed[52]; - fng_vel = Fixed[56]; - fng_max = Fixed[60]; - ele_max = Fixed[64]; - dec_xng = Fixed[68]; - stp_dta = Fixed[72]; - stp_amp = Fixed[76]; - ply_rad = Fixed[80]; - ply_hei = Fixed[84]; - ply_dhi = Fixed[88]; - ply_cam = Fixed[92]; - ply_spl = Fixed[96]; - ply_hcm = Fixed[100]; + endian: BIG, buf: b, size: 104, start: 0, data { + let vel_fwd = Fixed[0]; + let vel_bkw = Fixed[4]; + let vel_prp = Fixed[8]; + let acc_nrm = Fixed[12]; + let dec_nrm = Fixed[16]; + let dec_air = Fixed[20]; + let acc_grv = Fixed[24]; + let acc_cli = Fixed[28]; + let vel_trm = Fixed[32]; + let dec_ext = Fixed[36]; + let acc_ang = Fixed[40]; + let dec_ang = Fixed[44]; + let vel_ang = Fixed[48]; + let vel_rec = Fixed[52]; + let fng_vel = Fixed[56]; + let fng_max = Fixed[60]; + let ele_max = Fixed[64]; + let dec_xng = Fixed[68]; + let stp_dta = Fixed[72]; + let stp_amp = Fixed[76]; + let ply_rad = Fixed[80]; + let ply_hei = Fixed[84]; + let ply_dhi = Fixed[88]; + let ply_cam = Fixed[92]; + let ply_spl = Fixed[96]; + let ply_hcm = Fixed[100]; + } } Ok((Physics{acc_ang, acc_cli, acc_grv, acc_nrm, dec_air, dec_ang, dec_ext, @@ -46,17 +47,16 @@ pub fn read_pxpx(b: &[u8]) -> ResultS<(Physics, usize)> pub fn read_fxpx(b: &[u8]) -> ResultS<(Effect, usize)> { read_data! { - 14, BE in b => - collection = u16[0]; - shape = u16[2]; - pitch = Fixed[4]; - flags = u16[8]; - delay = OptU16[10]; - delay_snd = OptU16[12]; + endian: BIG, buf: b, size: 14, start: 0, data { + let collection = u16[0]; + let shape = u16[2]; + let pitch = Fixed[4]; + let flags = u16[8] flag EffectFlags; + let delay = OptU16[10]; + let delay_snd = OptU16[12]; + } } - let flags = flag_ok!(EffectFlags, flags)?; - Ok((Effect{collection, shape, pitch, flags, delay, delay_snd}, 14)) } @@ -64,37 +64,35 @@ pub fn read_fxpx(b: &[u8]) -> ResultS<(Effect, usize)> pub fn read_wppx(b: &[u8]) -> ResultS<(Weapon, usize)> { read_data! { - 134, BE in b => - typ_item = u16[0]; - typ_powerup = OptU16[2]; - typ_weapon = u16[4]; - flags = u16[6]; - lit_value = Fixed[8]; - lit_decay = u16[12]; - hei_idle = Fixed[14]; - amp_bob = Fixed[18]; - hei_kick = Fixed[22]; - hei_reload = Fixed[26]; - wid_idle = Fixed[30]; - amp_horz = Fixed[34]; - collection = u16[38]; - frm_idle = u16[40]; - frm_firing = u16[42]; - frm_reload = OptU16[44]; - frm_charge = OptU16[48]; - frm_charged = OptU16[50]; - tic_ready = u16[52]; - tic_load_beg = u16[54]; - tic_load_mid = u16[56]; - tic_load_end = u16[58]; - tic_powerup = u16[60]; - trig_pri = read_trigger[62..98]; - trig_sec = read_trigger[98..134]; + endian: BIG, buf: b, size: 134, start: 0, data { + let typ_item = u16[0]; + let typ_powerup = OptU16[2]; + let typ_weapon = u16[4] enum WeaponType; + let flags = u16[6] flag WeaponFlags; + let lit_value = Fixed[8]; + let lit_decay = u16[12]; + let hei_idle = Fixed[14]; + let amp_bob = Fixed[18]; + let hei_kick = Fixed[22]; + let hei_reload = Fixed[26]; + let wid_idle = Fixed[30]; + let amp_horz = Fixed[34]; + let collection = u16[38]; + let frm_idle = u16[40]; + let frm_firing = u16[42]; + let frm_reload = OptU16[44]; + let frm_charge = OptU16[48]; + let frm_charged = OptU16[50]; + let tic_ready = u16[52]; + let tic_load_beg = u16[54]; + let tic_load_mid = u16[56]; + let tic_load_end = u16[58]; + let tic_powerup = u16[60]; + let trig_pri = read_trigger[62; 36]; + let trig_sec = read_trigger[98; 36]; + } } - let typ_weapon = WeaponType::try_from(typ_weapon)?; - let flags = flag_ok!(WeaponFlags, flags)?; - Ok((Weapon{amp_bob, amp_horz, collection, flags, frm_charge, frm_charged, frm_firing, frm_idle, frm_reload, hei_idle, hei_kick, hei_reload, lit_decay, lit_value, tic_load_beg, tic_load_end, tic_load_mid, @@ -106,28 +104,27 @@ pub fn read_wppx(b: &[u8]) -> ResultS<(Weapon, usize)> pub fn read_prpx(b: &[u8]) -> ResultS<(Projectile, usize)> { read_data! { - 48, BE in b => - collection = OptU16[0]; - shape = u16[2]; - fxt_explode = OptU16[4]; - fxt_exp_media = OptU16[6]; - fxt_trail = OptU16[8]; - tic_trail = u16[10]; - max_trail = OptU16[12]; - typ_media = OptU16[14]; - radius = Unit[16]; - dmg_rad = Unit[18]; - dmg_def = read_damage[20..32]; - flags = u32[32]; - speed = Unit[36]; - range = Unit[38]; - snd_pitch = Fixed[40]; - snd_fly = OptU16[44]; - snd_bounce = OptU16[46]; + endian: BIG, buf: b, size: 48, start: 0, data { + let collection = OptU16[0]; + let shape = u16[2]; + let fxt_explode = OptU16[4]; + let fxt_exp_media = OptU16[6]; + let fxt_trail = OptU16[8]; + let tic_trail = u16[10]; + let max_trail = OptU16[12]; + let typ_media = OptU16[14]; + let radius = Unit[16]; + let dmg_rad = Unit[18]; + let dmg_def = read_damage[20; 12]; + let flags = u32[32] flag ProjectileFlags; + let speed = Unit[36]; + let range = Unit[38]; + let snd_pitch = Fixed[40]; + let snd_fly = OptU16[44]; + let snd_bounce = OptU16[46]; + } } - let flags = flag_ok!(ProjectileFlags, flags)?; - Ok((Projectile{collection, shape, fxt_explode, fxt_exp_media, fxt_trail, tic_trail, max_trail, typ_media, radius, dmg_rad, dmg_def, flags, speed, range, snd_pitch, snd_fly, snd_bounce}, 48)) @@ -137,67 +134,64 @@ pub fn read_prpx(b: &[u8]) -> ResultS<(Projectile, usize)> pub fn read_mnpx(b: &[u8]) -> ResultS<(Monster, usize)> { read_data! { - 156, BE in b => - collection = u16[0]; - vitality = u16[2]; - dty_immune = u32[4]; - dty_weak = u32[8]; - flags = u32[12]; - cls_self = u32[16]; - cls_friend = u32[20]; - cls_enemy = u32[24]; - snd_pitch = Fixed[28]; - snd_see_enemy = OptU16[32]; - snd_see_friend = OptU16[34]; - snd_seeclear = OptU16[36]; - snd_kill = OptU16[38]; - snd_apologize = OptU16[40]; - snd_amicide = OptU16[42]; - snd_flaming = OptU16[44]; - snd_active = OptU16[46]; - snd_active_mask = u16[48]; - typ_item = OptU16[50]; - radius = Unit[52]; - height = Unit[54]; - height_hover = Unit[56]; - ledge_min = Unit[58]; - ledge_max = Unit[60]; - ext_vel_scale = Fixed[62]; - fxt_impact = OptU16[66]; - fxt_impact_melee = OptU16[68]; - fxt_trail = OptU16[70]; - half_fov_horz = u16[72]; - half_fov_vert = u16[74]; - view_range = Unit[76]; - view_range_dark = Unit[78]; - intelligence = u16[80]; - speed = u16[82]; - gravity = u16[84]; - vel_terminal = u16[86]; - door_try_mask = u16[88]; - expl_radius = OptU16[90]; - expl_damage = read_damage[92..104]; - seq_hit = OptU16[104]; - seq_dying_hard = OptU16[106]; - seq_dying_soft = OptU16[108]; - seq_dead_hard = OptU16[110]; - seq_dead_soft = OptU16[112]; - seq_standing = u16[114]; - seq_moving = u16[116]; - seq_tele_in = OptU16[118]; - seq_tele_out = OptU16[120]; - atk_frequency = u16[122]; - atk_melee = read_attack[124..140]; - atk_range = read_attack[140..156]; + endian: BIG, buf: b, size: 156, start: 0, data { + let collection = u16[0]; + let vitality = u16[2]; + let dty_immune = u32[4] flag DamageTypeFlags; + let dty_weak = u32[8] flag DamageTypeFlags; + let flags = u32[12] flag MonsterFlags; + let cls_self = u32[16] flag MonsterClass; + let cls_friend = u32[20]; + let cls_enemy = u32[24]; + let snd_pitch = Fixed[28]; + let snd_see_enemy = OptU16[32]; + let snd_see_friend = OptU16[34]; + let snd_seeclear = OptU16[36]; + let snd_kill = OptU16[38]; + let snd_apologize = OptU16[40]; + let snd_amicide = OptU16[42]; + let snd_flaming = OptU16[44]; + let snd_active = OptU16[46]; + let snd_active_mask = u16[48]; + let typ_item = OptU16[50]; + let radius = Unit[52]; + let height = Unit[54]; + let height_hover = Unit[56]; + let ledge_min = Unit[58]; + let ledge_max = Unit[60]; + let ext_vel_scale = Fixed[62]; + let fxt_impact = OptU16[66]; + let fxt_impact_melee = OptU16[68]; + let fxt_trail = OptU16[70]; + let half_fov_horz = u16[72]; + let half_fov_vert = u16[74]; + let view_range = Unit[76]; + let view_range_dark = Unit[78]; + let intelligence = u16[80]; + let speed = u16[82]; + let gravity = u16[84]; + let vel_terminal = u16[86]; + let door_try_mask = u16[88]; + let expl_radius = OptU16[90]; + let expl_damage = read_damage[92; 12]; + let seq_hit = OptU16[104]; + let seq_dying_hard = OptU16[106]; + let seq_dying_soft = OptU16[108]; + let seq_dead_hard = OptU16[110]; + let seq_dead_soft = OptU16[112]; + let seq_standing = u16[114]; + let seq_moving = u16[116]; + let seq_tele_in = OptU16[118]; + let seq_tele_out = OptU16[120]; + let atk_frequency = u16[122]; + let atk_melee = read_attack[124; 16]; + let atk_range = read_attack[140; 16]; + } } // friend and enemy fields MUST truncate because the original source code // used `-1` to represent "all classes" which should be invalid normally - let dty_immune = flag_ok!(DamageTypeFlags, dty_immune)?; - let dty_weak = flag_ok!(DamageTypeFlags, dty_weak)?; - let flags = flag_ok!(MonsterFlags, flags)?; - let cls_self = flag_ok!(MonsterClass, cls_self)?; let cls_friend = MonsterClass::from_bits_truncate(cls_friend); let cls_enemy = MonsterClass::from_bits_truncate(cls_enemy); @@ -218,29 +212,28 @@ pub fn read_mnpx(b: &[u8]) -> ResultS<(Monster, usize)> fn read_trigger(b: &[u8]) -> ResultS { read_data! { - 36, BE in b => - magazine = u16[0]; - typ_ammo = OptU16[2]; - tic_round = OptU16[4]; - tic_recover = u16[6]; - tic_charge = u16[8]; - recoil = Unit[10]; - snd_fire = OptU16[12]; - snd_click = OptU16[14]; - snd_charge = OptU16[16]; - snd_casing = OptU16[18]; - snd_reload = OptU16[20]; - snd_charged = OptU16[22]; - typ_proj = u16[24]; - theta = u16[26]; - dx = i16[28]; - dz = i16[30]; - typ_casing = u16[32]; - burst = u16[34]; + endian: BIG, buf: b, size: 36, start: 0, data { + let magazine = u16[0]; + let typ_ammo = OptU16[2]; + let tic_round = OptU16[4]; + let tic_recover = u16[6]; + let tic_charge = u16[8]; + let recoil = Unit[10]; + let snd_fire = OptU16[12]; + let snd_click = OptU16[14]; + let snd_charge = OptU16[16]; + let snd_casing = OptU16[18]; + let snd_reload = OptU16[20]; + let snd_charged = OptU16[22]; + let typ_proj = u16[24]; + let theta = u16[26]; + let dx = i16[28]; + let dz = i16[30]; + let typ_casing = u16[32] enum CasingType; + let burst = u16[34]; + } } - let typ_casing = CasingType::try_from(typ_casing)?; - Ok(Trigger{burst, dx, dz, magazine, recoil, snd_casing, snd_charge, snd_charged, snd_click, snd_fire, snd_reload, theta, tic_charge, tic_recover, tic_round, typ_ammo, typ_casing, typ_proj}) @@ -250,15 +243,15 @@ fn read_trigger(b: &[u8]) -> ResultS fn read_damage(b: &[u8]) -> ResultS { read_data! { - 12, BE in b => - dtype = u16[0]; - flags = u16[2]; - dmg_base = u16[4]; - dmg_rand = u16[6]; - scale = Fixed[8]; + endian: BIG, buf: b, size: 12, start: 0, data { + let dtype = u16[0] enum DamageType; + let flags = u16[2]; + let dmg_base = u16[4]; + let dmg_rand = u16[6]; + let scale = Fixed[8]; + } } - let dtype = DamageType::try_from(dtype)?; let alien = flags != 0; Ok(Damage{dtype, alien, dmg_base, dmg_rand, scale}) @@ -268,15 +261,16 @@ fn read_damage(b: &[u8]) -> ResultS fn read_attack(b: &[u8]) -> ResultS { read_data! { - 16, BE in b => - ptype = OptU16[0]; - rep = u16[2]; - error = Angle[4]; - range = Unit[6]; - shape = u16[8]; - ofs_x = Unit[10]; - ofs_y = Unit[12]; - ofs_z = Unit[14]; + endian: BIG, buf: b, size: 16, start: 0, data { + let ptype = OptU16[0]; + let rep = u16[2]; + let error = Angle[4]; + let range = Unit[6]; + let shape = u16[8]; + let ofs_x = Unit[10]; + let ofs_y = Unit[12]; + let ofs_z = Unit[14]; + } } Ok(Attack{ptype, rep, error, range, shape, ofs_x, ofs_y, ofs_z}) diff --git a/source/marathon/pict.rs b/source/marathon/pict.rs index 5d635f8..4dc88e3 100644 --- a/source/marathon/pict.rs +++ b/source/marathon/pict.rs @@ -10,19 +10,17 @@ fn read_pm_header<'a>(b: &'a [u8], -> ResultS<(&'a [u8], Header)> { read_data! { - 36, BE in b => - pt_fl = u16[0]; - top = u16[2] usize; - left = u16[4] usize; - bottom = u16[6] usize; - right = u16[8] usize; - pack_t = u16[12]; - depth = u16[28]; + endian: BIG, buf: b, size: 36, start: 0, data { + let pt_fl = u16[0]; + let top = u16[2] usize; + let left = u16[4] usize; + let bottom = u16[6] usize; + let right = u16[8] usize; + let pack_t = u16[12] enum PackType; + let depth = u16[28] enum Depth; + } } - let pack_t = PackType::try_from(pack_t)?; - let depth = Depth::try_from(depth)?; - if pt_fl & 0x8000 == 0 { bail!("PICT1 not supported"); } @@ -153,10 +151,11 @@ fn read_pm_32(mut im: Image8, b: &[u8], hdr: Header) -> ResultS } read_data! { - p + 3, BE in b => - r = u8[p]; - g = u8[p + 1]; - b = u8[p + 2]; + endian: BIG, buf: b, size: 3, start: p, data { + let r = u8[0]; + let g = u8[1]; + let b = u8[2]; + } } im.cr.push(Color8::new(r, g, b)); @@ -209,9 +208,10 @@ fn read_pm_area(im: Image8, b: &[u8], pack: bool, clip: bool) pub fn load_pict(b: &[u8]) -> ResultS { read_data! { - 10, BE in b => - h = u16[6] usize; - w = u16[8] usize; + endian: BIG, buf: b, size: 10, start: 0, data { + let h = u16[6] usize; + let w = u16[8] usize; + } } if w * h > 16_000_000 { @@ -224,8 +224,9 @@ pub fn load_pict(b: &[u8]) -> ResultS while p < b.len() { read_data! { - p + 2, BE in b => - op = u16[p]; + endian: BIG, buf: b, size: 2, start: p, data { + let op = u16[0]; + } } p += 2; @@ -315,9 +316,10 @@ pub fn load_pict(b: &[u8]) -> ResultS pub fn get_clut(b: &[u8]) -> ResultS<(Vec, usize)> { read_data! { - 8, BE in b => - dev = u16[4]; - num = u16[6] usize; + endian: BIG, buf: b, size: 8, start: 0, data { + let dev = u16[4]; + let num = u16[6] usize; + } } let dev = dev & 0x8000 != 0; @@ -328,11 +330,12 @@ pub fn get_clut(b: &[u8]) -> ResultS<(Vec, usize)> for i in 0..num { read_data! { - p + 8, BE in b => - n = u16[p] usize; - r = u8[p + 2]; - g = u8[p + 4]; - b = u8[p + 6]; + endian: BIG, buf: b, size: 8, start: p, data { + let n = u16[0] usize; + let r = u8[2]; + let g = u8[4]; + let b = u8[6]; + } } // with device mapping, we ignore the index entirely diff --git a/source/marathon/shp.rs b/source/marathon/shp.rs index 658b6db..a387234 100644 --- a/source/marathon/shp.rs +++ b/source/marathon/shp.rs @@ -8,12 +8,13 @@ use bitflags::bitflags; fn read_color(b: &[u8], clut: &mut [ColorShp]) -> ResultS<()> { read_data! { - 8, BE in b => - flag = u8[0]; - ind = u8[1]; - r = u16[2]; - g = u16[4]; - b = u16[6]; + endian: BIG, buf: b, size: 8, start: 0, data { + let flag = u8[0]; + let ind = u8[1]; + let r = u16[2]; + let g = u16[4]; + let b = u16[6]; + } } let cr = ok!(clut.get_mut(usize::from(ind)), "bad index")?; @@ -57,16 +58,16 @@ fn color_tables(b: &[u8], pub fn read_bitmap(b: &[u8]) -> ResultS { read_data! { - 26, BE in b => - width = u16[0] usize; - height = u16[2] usize; - compr = u16[4]; - flags = u16[6]; - depth = u16[8]; + endian: BIG, buf: b, size: 26, start: 0, data { + let width = u16[0] usize; + let height = u16[2] usize; + let compr = u16[4]; + let flags = u16[6] flag BmpFlags; + let depth = u16[8]; + } } let compr = compr == u16::max_value(); - let flags = flag_ok!(BmpFlags, flags)?; let alpha = flags.contains(BmpFlags::TRANSPARENT); let cmajr = flags.contains(BmpFlags::COLUMN_MAJOR); @@ -84,9 +85,10 @@ pub fn read_bitmap(b: &[u8]) -> ResultS // compressed scanlines (transparency RLE) for _ in 0..scanlines { read_data! { - p + 4, BE in b => - fst = u16[p] usize; - lst = u16[p + 2] usize; + endian: BIG, buf: b, size: 4, start: p, data { + let fst = u16[0] usize; + let lst = u16[2] usize; + } } let end = lst - fst; @@ -122,20 +124,19 @@ pub fn read_bitmap(b: &[u8]) -> ResultS pub fn read_frame(b: &[u8]) -> ResultS { read_data! { - 36, BE in b => - flags = u16[0]; - min_lt = Fixed[2]; - bmp_ind = u16[6] usize; - wrl_l = Unit[16]; - wrl_r = Unit[18]; - wrl_t = Unit[20]; - wrl_b = Unit[22]; - wrl_x = Unit[24]; - wrl_y = Unit[26]; + endian: BIG, buf: b, size: 36, start: 0, data { + let flags = u16[0] flag FrameFlags; + let min_lt = Fixed[2]; + let bmp_ind = u16[6] usize; + let wrl_l = Unit[16]; + let wrl_r = Unit[18]; + let wrl_t = Unit[20]; + let wrl_b = Unit[22]; + let wrl_x = Unit[24]; + let wrl_y = Unit[26]; + } } - let flags = flag_ok!(FrameFlags, flags)?; - Ok(Frame{flags, min_lt, bmp_ind, wrl_l, wrl_r, wrl_t, wrl_b, wrl_x, wrl_y}) } @@ -143,23 +144,22 @@ pub fn read_frame(b: &[u8]) -> ResultS pub fn read_sequence(b: &[u8]) -> ResultS { read_data! { - 88, BE in b => - name = u8[4..38] slice; - v_type = u16[38]; - frames = u16[40]; - ticks = u16[42]; - key = u16[44]; - xfer = u16[46]; - xfer_pd = u16[48]; - snd_beg = OptU16[50]; - snd_key = OptU16[52]; - snd_end = OptU16[54]; - loop_f = u16[58]; + endian: BIG, buf: b, size: 88, start: 0, data { + let name = u8[4; 34]; + let v_type = u16[38] enum ViewType; + let frames = u16[40]; + let ticks = u16[42]; + let key = u16[44]; + let xfer = u16[46] enum TransferMode; + let xfer_pd = u16[48]; + let snd_beg = OptU16[50]; + let snd_key = OptU16[52]; + let snd_end = OptU16[54]; + let loop_f = u16[58]; + } } - let name = mac_roman_conv(ok!(pascal_str(name), "bad string")?); - let xfer = TransferMode::try_from(xfer)?; - let v_type = ViewType::try_from(v_type)?; + let name = mac_roman_conv(ok!(pascal_str(name), "bad string")?); Ok(Sequence{name, v_type, frames, ticks, key, xfer, xfer_pd, snd_beg, snd_key, snd_end, loop_f}) @@ -169,22 +169,21 @@ pub fn read_sequence(b: &[u8]) -> ResultS pub fn read_collection(b: &[u8]) -> ResultS { read_data! { - 544, BE in b => - version = u16[0]; - cl_type = u16[2]; - clr_num = u16[6] usize; - tab_num = u16[8] usize; - tab_ofs = u32[10] usize; - seq_num = u16[14] usize; - seq_ofs = u32[16] usize; - frm_num = u16[20] usize; - frm_ofs = u32[22] usize; - bmp_num = u16[26] usize; - bmp_ofs = u32[28] usize; + endian: BIG, buf: b, size: 544, start: 0, data { + let version = u16[0]; + let cl_type = u16[2] enum CollectionType; + let clr_num = u16[6] usize; + let tab_num = u16[8] usize; + let tab_ofs = u32[10] usize; + let seq_num = u16[14] usize; + let seq_ofs = u32[16] usize; + let frm_num = u16[20] usize; + let frm_ofs = u32[22] usize; + let bmp_num = u16[26] usize; + let bmp_ofs = u32[28] usize; + } } - let cl_type = CollectionType::try_from(cl_type)?; - if version != 3 { bail!("invalid collection definition"); } @@ -205,11 +204,12 @@ pub fn read_shapes(b: &[u8]) -> ResultS> for _ in 0..32 { read_data! { - p + 32, BE in b => - lo_ofs = u32[p + 4] usize; - lo_len = u32[p + 8] usize; - hi_ofs = u32[p + 12] usize; - hi_len = u32[p + 16] usize; + endian: BIG, buf: b, size: 32, start: p, data { + let lo_ofs = u32[4] usize; + let lo_len = u32[8] usize; + let hi_ofs = u32[12] usize; + let hi_len = u32[16] usize; + } } let c_lo = if lo_ofs == usize_from_u32(u32::max_value()) { diff --git a/source/marathon/snd.rs b/source/marathon/snd.rs index 019c3cf..00d4e49 100644 --- a/source/marathon/snd.rs +++ b/source/marathon/snd.rs @@ -8,12 +8,13 @@ use std::collections::BTreeMap; pub fn read_sound(b: &[u8]) -> ResultS { read_data! { - 21, BE in b => - len = u32[4] usize; - rate = u16[8]; - lp_beg = u32[12] usize; - lp_end = u32[16] usize; - magic = u8[20]; + endian: BIG, buf: b, size: 21, start: 0, data { + let len = u32[4] usize; + let rate = u16[8]; + let lp_beg = u32[12] usize; + let lp_end = u32[16] usize; + let magic = u8[20]; + } } match magic { @@ -23,9 +24,10 @@ pub fn read_sound(b: &[u8]) -> ResultS } 0xFF => { read_data! { - 63, BE in b => - len = u32[22] usize; - bps = u16[48]; + endian: BIG, buf: b, size: 42, start: 22, data { + let len = u32[0] usize; + let bps = u16[26]; + } } match bps { @@ -48,20 +50,18 @@ pub fn read_sound(b: &[u8]) -> ResultS pub fn read_sound_def(b: &[u8]) -> ResultS, u16, SoundDef)>> { read_data! { - 64, BE in b => - index = u16[0]; - volume = u16[2]; - flags = u16[4]; - chance = u16[6]; - pitch_lo = Fixed[8]; - pitch_hi = Fixed[12]; - n_sounds = u16[16] usize; - grp_ofs = u32[20] usize; + endian: BIG, buf: b, size: 64, start: 0, data { + let index = u16[0]; + let volume = u16[2] enum Volume; + let flags = u16[4] flag SoundFlags; + let chance = u16[6]; + let pitch_lo = Fixed[8]; + let pitch_hi = Fixed[12]; + let n_sounds = u16[16] usize; + let grp_ofs = u32[20] usize; + } } - let flags = flag_ok!(SoundFlags, flags)?; - let volume = Volume::try_from(volume)?; - if index == u16::max_value() { return Ok(None); } @@ -88,11 +88,12 @@ pub fn read_sound_def(b: &[u8]) -> ResultS, u16, SoundDef)>> pub fn read_sounds(b: &[u8]) -> ResultS> { read_data! { - 260, BE in b => - version = u32[0]; - magic = u8[4..8] slice; - src_num = u16[8] usize; - snd_num = u16[10] usize; + endian: BIG, buf: b, size: 260, start: 0, data { + let version = u32[0]; + let magic = Ident[4]; + let src_num = u16[8] usize; + let snd_num = u16[10] usize; + } } if version != 1 || magic != b"snd2" { diff --git a/source/marathon/trm.rs b/source/marathon/trm.rs index a059dab..5e7edc4 100644 --- a/source/marathon/trm.rs +++ b/source/marathon/trm.rs @@ -7,16 +7,16 @@ use bitflags::bitflags; pub fn read_group(b: &[u8]) -> ResultS<(InterGroup, usize)> { read_data! { - 12, BE in b => - flags = u16[0]; - ttype = u16[2]; - pdata = u16[4]; - beg = u16[6] usize; - len = u16[8] usize; - lines = u16[10]; + endian: BIG, buf: b, size: 12, start: 0, data { + let flags = u16[0] flag GroupFlags; + let ttype = u16[2]; + let pdata = u16[4]; + let beg = u16[6] usize; + let len = u16[8] usize; + let lines = u16[10]; + } } - let flags = flag_ok!(GroupFlags, flags)?; let ttype = match ttype { 0 => GroupType::Logon(pdata), 1 => GroupType::Unfinished, @@ -45,10 +45,11 @@ pub fn read_group(b: &[u8]) -> ResultS<(InterGroup, usize)> pub fn read_face(b: &[u8]) -> ResultS<(Face, usize)> { read_data! { - 6, BE in b => - start = u16[0] usize; - face = u16[2]; - color = u16[4]; + endian: BIG, buf: b, size: 6, start: 0, data { + let start = u16[0] usize; + let face = u16[2]; + let color = u16[4]; + } } Ok((Face{start, face, color}, 6)) @@ -58,12 +59,13 @@ pub fn read_face(b: &[u8]) -> ResultS<(Face, usize)> pub fn read_term(b: &[u8]) -> ResultS<(Terminal, usize)> { read_data! { - 10, BE in b => - end = u16[0] usize; - encoded = u16[2]; - lines = u16[4]; - group_n = u16[6] usize; - face_n = u16[8] usize; + endian: BIG, buf: b, size: 10, start: 0, data { + let end = u16[0] usize; + let encoded = u16[2]; + let lines = u16[4]; + let group_n = u16[6] usize; + let face_n = u16[8] usize; + } } let encoded = encoded != 0; diff --git a/source/marathon/wad.rs b/source/marathon/wad.rs index f7a46bc..cdd64fe 100644 --- a/source/marathon/wad.rs +++ b/source/marathon/wad.rs @@ -18,9 +18,10 @@ pub fn read_chunks(b: &[u8], old_dat: bool, siz_cnk: usize) while p < b.len() { read_data! { - p + siz_cnk, BE in b => - iden = Ident[p]; - size = u32[p + 8] usize; + endian: BIG, buf: b, size: siz_cnk, start: p, data { + let iden = Ident[0]; + let size = u32[8] usize; + } } let beg = p + siz_cnk; @@ -69,9 +70,10 @@ pub fn read_entries(b: &[u8], -> ResultS> { read_data! { - 128, BE in b => - dirofs = u32[72] usize; - numents = u16[76] usize; + endian: BIG, buf: b, size: 128, start: 0, data { + let dirofs = u32[72] usize; + let numents = u16[76] usize; + } } let mut entries = BTreeMap::new(); @@ -79,10 +81,11 @@ pub fn read_entries(b: &[u8], for i in 0..numents { read_data! { - p + siz_ent, BE in b => - offset = u32[p] usize; - size = u32[p + 4] usize; - index = u16[p + 8]; + endian: BIG, buf: b, size: siz_ent, start: p, data { + let offset = u32[0] usize; + let size = u32[4] usize; + let index = u16[8]; + } } let index = if old_wad {i as u16} else {index}; @@ -102,17 +105,18 @@ pub fn read_entries(b: &[u8], pub fn read_wad(b: &[u8]) -> ResultS { read_data! { - 128, BE in b => - ver_wad = u16[0]; - ver_dat = u16[2]; - name = mac_roman_cstr[4..68] no_try; - siz_app = u16[78] usize; - siz_wcnk = u16[80] usize; - siz_went = u16[82] usize; + endian: BIG, buf: b, size: 128, start: 0, data { + let ver_wad = u16[0] enum Ver; + let ver_dat = u16[2]; + let name = mac_roman_cstr[4; 64] no_try; + let siz_app = u16[78] usize; + let siz_wcnk = u16[80] usize; + let siz_went = u16[82] usize; + } } let old_dat = ver_dat == 0; - let old_wad = match Ver::try_from(ver_wad)? { + let old_wad = match ver_wad { Ver::Base => true, _ => false, };