From 6ee6140ba8f08cd174a43cc45ef8c0b4af8747c9 Mon Sep 17 00:00:00 2001 From: Marrub Date: Mon, 18 Mar 2019 12:07:44 -0400 Subject: [PATCH 1/4] simplify OptU16 API --- source/durandal/bin.rs | 85 ++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/source/durandal/bin.rs b/source/durandal/bin.rs index f4c8e60..0be9177 100644 --- a/source/durandal/bin.rs +++ b/source/durandal/bin.rs @@ -49,7 +49,7 @@ macro_rules! _durandal_read_impl { }; ($e:ident $b:expr; $nam:ident OptU16 $n:expr) => { _durandal_read_impl!($e $b; $nam u16 $n); - let $nam = OptU16::from_repr($nam); + let $nam = OptU16::from($nam); }; ($e:ident $b:expr; $nam:ident usize u16 $n:expr) => { _durandal_read_impl!($e $b; $nam u16 $n); @@ -114,7 +114,7 @@ macro_rules! _durandal_read_impl { /// - `Unit`: same as `u16`, but the result is passed to /// `fixed::Unit::from_bits`, resulting in a `fixed::Unit` object. /// - `OptU16`: same as `u16`, but the result is passed to -/// `OptU16::from_repr`, resulting in an `OptU16` object. +/// `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: @@ -376,6 +376,46 @@ pub fn rd_ofstable(b: &[u8], Ok(v) } +impl From for OptU16 +{ + #[inline] + fn from(n: u16) -> Self + { + if n == u16::max_value() { + Self(None) + } else { + Self(NonZeroU16::new(n + 1)) + } + } +} + +impl Into for OptU16 +{ + /// Returns the `u16` representation. + /// + /// # Examples + /// + /// ``` + /// use maraiah::durandal::bin::OptU16; + /// + /// let u16_max = u16::max_value(); + /// + /// // These type annotations are necessary. + /// + /// assert_eq!(>::into(OptU16::from(500u16)), 500u16); + /// assert_eq!(>::into(OptU16::from(u16_max)), u16_max); + /// assert_eq!(>::into(OptU16::from(0u16)), 0u16); + /// ``` + #[inline] + fn into(self) -> u16 + { + match self.0 { + None => u16::max_value(), + Some(n) => n.get() - 1, + } + } +} + impl OptU16 { /// Creates an `OptU16` representing `None`. @@ -385,41 +425,11 @@ impl OptU16 /// ``` /// use maraiah::durandal::bin::OptU16; /// - /// assert_eq!(OptU16::none(), OptU16::from_repr(u16::max_value())); + /// assert_eq!(OptU16::none(), OptU16::from(u16::max_value())); /// ``` + #[inline] pub const fn none() -> Self {Self(None)} - /// Creates an `OptU16` from a `u16`. - pub fn from_repr(n: u16) -> Self - { - if n == u16::max_value() { - Self(None) - } else { - Self(NonZeroU16::new(n + 1)) - } - } - - /// Returns the `u16` representation. - /// - /// # Examples - /// - /// ``` - /// use maraiah::durandal::bin::OptU16; - /// - /// let u16max = u16::max_value(); - /// - /// assert_eq!(OptU16::from_repr(500u16).get_repr(), 500u16); - /// assert_eq!(OptU16::from_repr(u16max).get_repr(), u16max); - /// assert_eq!(OptU16::from_repr(0u16).get_repr(), 0u16); - /// ``` - pub fn get_repr(self) -> u16 - { - match self.0 { - None => u16::max_value(), - Some(n) => n.get() - 1, - } - } - /// Returns the `Option` representation. /// /// # Examples @@ -427,10 +437,11 @@ impl OptU16 /// ``` /// use maraiah::durandal::bin::OptU16; /// - /// assert_eq!(OptU16::from_repr(500u16).get(), Some(500u16)); - /// assert_eq!(OptU16::from_repr(u16::max_value()).get(), None); - /// assert_eq!(OptU16::from_repr(0u16).get(), Some(0u16)); + /// assert_eq!(OptU16::from(500u16).get(), Some(500u16)); + /// assert_eq!(OptU16::from(u16::max_value()).get(), None); + /// assert_eq!(OptU16::from(0u16).get(), Some(0u16)); /// ``` + #[inline] pub fn get(self) -> Option { match self.0 { From ee35332b238ff015b7e023cdb3fc624bf841acfd Mon Sep 17 00:00:00 2001 From: Marrub Date: Mon, 18 Mar 2019 12:08:49 -0400 Subject: [PATCH 2/4] make c_enum use primitive repr --- source/durandal/cenum.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/durandal/cenum.rs b/source/durandal/cenum.rs index 62d4317..95186ac 100644 --- a/source/durandal/cenum.rs +++ b/source/durandal/cenum.rs @@ -36,16 +36,17 @@ macro_rules! c_enum { ( $(#[$outer:meta])* - $vi:vis enum $t:ident: $ti:ty + $vi:vis enum $t:ident: $ti:ident { - $($(#[$inner:meta])* $va:expr => $en:ident,)+ + $($va:expr => $en:ident,)+ } ) => { $(#[$outer])* + #[repr($ti)] #[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd)] $vi enum $t { - $($en,)+ + $($en = $va,)+ } impl $t @@ -54,7 +55,7 @@ macro_rules! c_enum $vi fn from_repr(n: $ti) -> Result { match n { - $($(#[$inner])* $va => Ok($t::$en),)+ + $($va => Ok($t::$en),)+ n => Err(ReprError::new(n)) } } From b830718258cebcc9ce566dbb79cea5b0c7b3fc14 Mon Sep 17 00:00:00 2001 From: Marrub Date: Mon, 18 Mar 2019 12:22:10 -0400 Subject: [PATCH 3/4] simplify c_enum API --- source/durandal/cenum.rs | 46 ++++++++++++------------ source/marathon/map.rs | 56 ++++++++++++++--------------- source/marathon/phy.rs | 78 ++++++++++++++++++++-------------------- source/marathon/pict.rs | 26 +++++++------- source/marathon/shp.rs | 34 +++++++++--------- source/marathon/snd.rs | 8 ++--- source/marathon/wad.rs | 10 +++--- source/marathon/xfer.rs | 44 +++++++++++------------ 8 files changed, 151 insertions(+), 151 deletions(-) diff --git a/source/durandal/cenum.rs b/source/durandal/cenum.rs index 95186ac..dd2a34d 100644 --- a/source/durandal/cenum.rs +++ b/source/durandal/cenum.rs @@ -6,7 +6,7 @@ /// The syntax is similar to the `bitflags` macro, but each value has the /// syntax `value => enumeration`. `enum` is used instead of `struct`. /// -/// This will generate an `enum $t` as well as a function `$t::from_repr` which +/// This will generate an `enum $t` as well as a function `$t::try_from` which /// will return `Result<$t, ReprError>`. /// /// # Examples @@ -18,18 +18,18 @@ /// #[derive(Debug)] /// enum MyEnum: u16 /// { -/// 0 => Zero, -/// 1 => One, -/// 2 => Two, +/// Zero = 0, +/// One = 1, +/// Two = 2 /// } /// } /// -/// assert_eq!(MyEnum::from_repr(0), Ok(MyEnum::Zero)); -/// assert_eq!(MyEnum::from_repr(1), Ok(MyEnum::One)); -/// assert_eq!(MyEnum::from_repr(2), Ok(MyEnum::Two)); -/// assert_eq!(MyEnum::from_repr(3), Err(ReprError::new(3))); -/// assert_eq!(MyEnum::from_repr(4), Err(ReprError::new(4))); -/// assert_eq!(MyEnum::from_repr(5), Err(ReprError::new(5))); +/// assert_eq!(MyEnum::try_from(0), Ok(MyEnum::Zero)); +/// assert_eq!(MyEnum::try_from(1), Ok(MyEnum::One)); +/// assert_eq!(MyEnum::try_from(2), Ok(MyEnum::Two)); +/// assert_eq!(MyEnum::try_from(3), Err(ReprError::new(3))); +/// assert_eq!(MyEnum::try_from(4), Err(ReprError::new(4))); +/// assert_eq!(MyEnum::try_from(5), Err(ReprError::new(5))); /// ``` #[macro_export] macro_rules! c_enum @@ -38,12 +38,12 @@ macro_rules! c_enum $(#[$outer:meta])* $vi:vis enum $t:ident: $ti:ident { - $($va:expr => $en:ident,)+ + $($en:ident = $va:expr),+ $(,)? } ) => { $(#[$outer])* - #[repr($ti)] #[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd)] + #[repr($ti)] $vi enum $t { $($en = $va,)+ @@ -52,7 +52,7 @@ macro_rules! c_enum impl $t { /// Returns, if representable, the variant of `Self` from `n`. - $vi fn from_repr(n: $ti) -> Result + $vi fn try_from(n: $ti) -> Result { match n { $($va => Ok($t::$en),)+ @@ -72,26 +72,26 @@ mod test #[derive(Debug)] enum TestEnum: u16 { - 0 => Zero, - 1 => One, - 2 => Two, + Zero = 0, + One = 1, + Two = 2, } } #[test] fn c_enum_should_be_ok() { - assert_eq!(TestEnum::from_repr(0), Ok(TestEnum::Zero)); - assert_eq!(TestEnum::from_repr(1), Ok(TestEnum::One)); - assert_eq!(TestEnum::from_repr(2), Ok(TestEnum::Two)); - assert_eq!(TestEnum::from_repr(3), Err(ReprError::new(3))); - assert_eq!(TestEnum::from_repr(4), Err(ReprError::new(4))); - assert_eq!(TestEnum::from_repr(5), Err(ReprError::new(5))); + assert_eq!(TestEnum::try_from(0), Ok(TestEnum::Zero)); + assert_eq!(TestEnum::try_from(1), Ok(TestEnum::One)); + assert_eq!(TestEnum::try_from(2), Ok(TestEnum::Two)); + assert_eq!(TestEnum::try_from(3), Err(ReprError::new(3))); + assert_eq!(TestEnum::try_from(4), Err(ReprError::new(4))); + assert_eq!(TestEnum::try_from(5), Err(ReprError::new(5))); } #[test] #[should_panic] - fn c_enum_should_error() {TestEnum::from_repr(3).unwrap();} + fn c_enum_should_error() {TestEnum::try_from(3).unwrap();} } // EOF diff --git a/source/marathon/map.rs b/source/marathon/map.rs index fb10b80..7381618 100644 --- a/source/marathon/map.rs +++ b/source/marathon/map.rs @@ -16,7 +16,7 @@ pub fn read_lightfunc(b: &[u8]) -> ResultS val_dta = Fixed[10]; } - let ftype = LightFuncType::from_repr(ftype)?; + let ftype = LightFuncType::try_from(ftype)?; Ok(LightFunc{ftype, prd_nrm, prd_dta, val_nrm, val_dta}) } @@ -148,10 +148,10 @@ pub fn read_sids(b: &[u8]) -> ResultS<(Side, usize)> } let flags = flag_ok!(SideFlags, flags)?; - let xfer_pri = TransferMode::from_repr(xfer_pri)?; - let xfer_sec = TransferMode::from_repr(xfer_sec)?; - let xfer_tra = TransferMode::from_repr(xfer_tra)?; - let stype = SideType::from_repr(stype)?; + 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)) @@ -183,8 +183,8 @@ fn read_poly_inter(b: &[u8]) -> ResultS xfr_cei = u16[66]; } - let xfr_flr = TransferMode::from_repr(xfr_flr)?; - let xfr_cei = TransferMode::from_repr(xfr_cei)?; + 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()}) @@ -246,7 +246,7 @@ pub fn read_lite(b: &[u8]) -> ResultS<(Light, usize)> } let flags = flag_ok!(LightFlags, flags)?; - let ltype = LightType::from_repr(ltype)?; + 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)) @@ -390,8 +390,8 @@ pub fn read_medi(b: &[u8]) -> ResultS<(Media, usize)> xfer = u16[26]; } - let mtype = MediaType::from_repr(mtype)?; - let xfer = TransferMode::from_repr(xfer)?; + 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, @@ -908,11 +908,11 @@ c_enum! { #[derive(Debug)] pub enum SideType: u16 { - 0 => Full, - 1 => High, - 2 => Low, - 3 => Composite, - 4 => Split, + Full = 0, + High = 1, + Low = 2, + Composite = 3, + Split = 4, } } @@ -922,12 +922,12 @@ c_enum! { #[derive(Debug)] pub enum LightFuncType: u16 { - 0 => Constant, - 1 => Linear, - 2 => Smooth, - 3 => Flicker, - 4 => Random, - 5 => Fluorescent, + Constant = 0, + Linear = 1, + Smooth = 2, + Flicker = 3, + Random = 4, + Fluorescent = 5, } } @@ -937,9 +937,9 @@ c_enum! { #[derive(Debug)] pub enum LightType: u16 { - 0 => Normal, - 1 => Strobe, - 2 => Media, + Normal = 0, + Strobe = 1, + Media = 2, } } @@ -949,10 +949,10 @@ c_enum! { #[derive(Debug)] pub enum MediaType: u16 { - 0 => Water, - 1 => Lava, - 2 => Goo, - 3 => Sewage, + Water = 0, + Lava = 1, + Goo = 2, + Sewage = 3, } } diff --git a/source/marathon/phy.rs b/source/marathon/phy.rs index ab4ebcd..746edbc 100644 --- a/source/marathon/phy.rs +++ b/source/marathon/phy.rs @@ -92,7 +92,7 @@ pub fn read_wppx(b: &[u8]) -> ResultS<(Weapon, usize)> trig_sec = read_trigger[98..134]; } - let typ_weapon = WeaponType::from_repr(typ_weapon)?; + 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, @@ -239,7 +239,7 @@ fn read_trigger(b: &[u8]) -> ResultS burst = u16[34]; } - let typ_casing = CasingType::from_repr(typ_casing)?; + 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, @@ -258,7 +258,7 @@ fn read_damage(b: &[u8]) -> ResultS scale = Fixed[8]; } - let dtype = DamageType::from_repr(dtype)?; + let dtype = DamageType::try_from(dtype)?; let alien = flags != 0; Ok(Damage{dtype, alien, dmg_base, dmg_rand, scale}) @@ -653,12 +653,12 @@ c_enum! { #[derive(Debug)] pub enum CasingType: u16 { - 0 => Rifle, - 1 => Pistol, - 2 => PistolLeft, - 3 => PistolRight, - 4 => SMG, - 0xFFFF => None, + Rifle = 0, + Pistol = 1, + PistolLeft = 2, + PistolRight = 3, + SMG = 4, + None = 0xFFFF, } } @@ -668,11 +668,11 @@ c_enum! { #[derive(Debug)] pub enum WeaponType: u16 { - 0 => Melee, - 1 => Normal, - 2 => DualFunc, - 3 => DualPistol, - 4 => Multipurpose, + Melee = 0, + Normal = 1, + DualFunc = 2, + DualPistol = 3, + Multipurpose = 4, } } @@ -682,31 +682,31 @@ c_enum! { #[derive(Debug)] pub enum DamageType: u16 { - 0 => Explosion, - 1 => ElectricalStaff, - 2 => Projectile, - 3 => Absorbed, - 4 => Flame, - 5 => HoundClaws, - 6 => AlienProjectile, - 7 => HulkSlap, - 8 => CompilerBolt, - 9 => FusionBolt, - 10 => HunterBolt, - 11 => Fist, - 12 => Teleporter, - 13 => Defender, - 14 => YetiClaws, - 15 => YetiProjectile, - 16 => Crushing, - 17 => Lava, - 18 => Suffocation, - 19 => Goo, - 20 => EnergyDrain, - 21 => OxygenDrain, - 22 => HummerBolt, - 23 => ShotgunProjectile, - 0xFFFF => None, + Explosion = 0, + ElectricalStaff = 1, + Projectile = 2, + Absorbed = 3, + Flame = 4, + HoundClaws = 5, + AlienProjectile = 6, + HulkSlap = 7, + CompilerBolt = 8, + FusionBolt = 9, + HunterBolt = 10, + Fist = 11, + Teleporter = 12, + Defender = 13, + YetiClaws = 14, + YetiProjectile = 15, + Crushing = 16, + Lava = 17, + Suffocation = 18, + Goo = 19, + EnergyDrain = 20, + OxygenDrain = 21, + HummerBolt = 22, + ShotgunProjectile = 23, + None = 0xFFFF, } } diff --git a/source/marathon/pict.rs b/source/marathon/pict.rs index c894803..5d635f8 100644 --- a/source/marathon/pict.rs +++ b/source/marathon/pict.rs @@ -20,8 +20,8 @@ fn read_pm_header<'a>(b: &'a [u8], depth = u16[28]; } - let pack_t = PackType::from_repr(pack_t)?; - let depth = Depth::from_repr(depth)?; + let pack_t = PackType::try_from(pack_t)?; + let depth = Depth::try_from(depth)?; if pt_fl & 0x8000 == 0 { bail!("PICT1 not supported"); @@ -481,23 +481,23 @@ struct Header c_enum! { enum Depth: u16 { - 1 => Bits1, - 2 => Bits2, - 4 => Bits4, - 8 => Bits8, - 16 => Bits16, - 32 => Bits32, + Bits1 = 1, + Bits2 = 2, + Bits4 = 4, + Bits8 = 8, + Bits16 = 16, + Bits32 = 32, } } c_enum! { enum PackType: u16 { - 0 => Default, - 1 => None, - 2 => NoPad, - 3 => Rle16, - 4 => Rle32, + Default = 0, + None = 1, + NoPad = 2, + Rle16 = 3, + Rle32 = 4, } } diff --git a/source/marathon/shp.rs b/source/marathon/shp.rs index 5f05563..658b6db 100644 --- a/source/marathon/shp.rs +++ b/source/marathon/shp.rs @@ -158,8 +158,8 @@ pub fn read_sequence(b: &[u8]) -> ResultS } let name = mac_roman_conv(ok!(pascal_str(name), "bad string")?); - let xfer = TransferMode::from_repr(xfer)?; - let v_type = ViewType::from_repr(v_type)?; + let xfer = TransferMode::try_from(xfer)?; + let v_type = ViewType::try_from(v_type)?; Ok(Sequence{name, v_type, frames, ticks, key, xfer, xfer_pd, snd_beg, snd_key, snd_end, loop_f}) @@ -183,7 +183,7 @@ pub fn read_collection(b: &[u8]) -> ResultS bmp_ofs = u32[28] usize; } - let cl_type = CollectionType::from_repr(cl_type)?; + let cl_type = CollectionType::try_from(cl_type)?; if version != 3 { bail!("invalid collection definition"); @@ -478,11 +478,11 @@ c_enum! { #[derive(Debug)] pub enum CollectionType: u16 { - 0 => Unused, - 1 => Wall, - 2 => Object, - 3 => Interface, - 4 => Scenery, + Unused = 0, + Wall = 1, + Object = 2, + Interface = 3, + Scenery = 4, } } @@ -492,15 +492,15 @@ c_enum! { #[derive(Debug)] pub enum ViewType: u16 { - 1 => Anim, - 2 => Anim8from2, - 3 => Anim4from3, - 4 => Anim4, - 5 => Anim8from5, - 8 => Anim8, - 9 => Anim5from3, - 10 => Still, - 11 => Anim5, + Anim = 1, + Anim8from2 = 2, + Anim4from3 = 3, + Anim4 = 4, + Anim8from5 = 5, + Anim8 = 8, + Anim5from3 = 9, + Still = 10, + Anim5 = 11, } } diff --git a/source/marathon/snd.rs b/source/marathon/snd.rs index 44426c6..019c3cf 100644 --- a/source/marathon/snd.rs +++ b/source/marathon/snd.rs @@ -60,7 +60,7 @@ pub fn read_sound_def(b: &[u8]) -> ResultS, u16, SoundDef)>> } let flags = flag_ok!(SoundFlags, flags)?; - let volume = Volume::from_repr(volume)?; + let volume = Volume::try_from(volume)?; if index == u16::max_value() { return Ok(None); @@ -177,9 +177,9 @@ c_enum! { #[derive(Debug)] pub enum Volume: u16 { - 0 => Quiet, - 1 => Normal, - 2 => Loud, + Quiet = 0, + Normal = 1, + Loud = 2, } } diff --git a/source/marathon/wad.rs b/source/marathon/wad.rs index 31889fe..f7a46bc 100644 --- a/source/marathon/wad.rs +++ b/source/marathon/wad.rs @@ -112,7 +112,7 @@ pub fn read_wad(b: &[u8]) -> ResultS } let old_dat = ver_dat == 0; - let old_wad = match Ver::from_repr(ver_wad)? { + let old_wad = match Ver::try_from(ver_wad)? { Ver::Base => true, _ => false, }; @@ -217,10 +217,10 @@ c_enum! { #[derive(Debug)] enum Ver: u16 { - 0 => Base, - 1 => Dir, - 2 => Over, - 4 => Inf, + Base = 0, + Dir = 1, + Over = 2, + Inf = 4, } } diff --git a/source/marathon/xfer.rs b/source/marathon/xfer.rs index d82d4c3..cd86be7 100644 --- a/source/marathon/xfer.rs +++ b/source/marathon/xfer.rs @@ -13,28 +13,28 @@ c_enum! { #[derive(Debug)] pub enum TransferMode: u16 { - 0 => Normal, - 1 => FadeBlack, - 2 => Invisibility, - 3 => Invisibility2, - 4 => Pulsate, - 5 => Wobble, - 6 => Wobble2, - 7 => Static, - 8 => Static2, - 9 => Sky, - 10 => Smear, - 11 => StaticFade, - 12 => StaticPulse, - 13 => FoldIn, - 14 => FoldOut, - 15 => SlideHorz, - 16 => SlideHorz2, - 17 => SlideVert, - 18 => SlideVert2, - 19 => Wander, - 20 => Wander2, - 21 => BigSky, + Normal = 0, + FadeBlack = 1, + Invisibility = 2, + Invisibility2 = 3, + Pulsate = 4, + Wobble = 5, + Wobble2 = 6, + Static = 7, + Static2 = 8, + Sky = 9, + Smear = 10, + StaticFade = 11, + StaticPulse = 12, + FoldIn = 13, + FoldOut = 14, + SlideHorz = 15, + SlideHorz2 = 16, + SlideVert = 17, + SlideVert2 = 18, + Wander = 19, + Wander2 = 20, + BigSky = 21, } } From 7e5375f32c6bf5509c48c942b52fae194be0c4ce Mon Sep 17 00:00:00 2001 From: Marrub Date: Mon, 18 Mar 2019 15:31:14 -0400 Subject: [PATCH 4/4] 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, };