diff --git a/source/durandal/bin.rs b/source/durandal/bin.rs index 1234ce6..a243090 100644 --- a/source/durandal/bin.rs +++ b/source/durandal/bin.rs @@ -281,7 +281,7 @@ pub struct Ident(pub [u8; 4]); /// An object identified by a `u16` which may be `u16::max_value()` to /// represent a nulled value. -#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Default, serde::Serialize, serde::Deserialize)] pub struct OptU16(Option); // EOF diff --git a/source/durandal/fixed.rs b/source/durandal/fixed.rs index adf7d3c..ea5691d 100644 --- a/source/durandal/fixed.rs +++ b/source/durandal/fixed.rs @@ -9,7 +9,7 @@ macro_rules! define_fixed_type { struct $Type:ident ($IT:ident) : $UT:ident, $LT:ident, $FracBits:expr; ) => { $(#[$outer])* - #[derive(Copy, Clone, PartialEq, PartialOrd, serde::Serialize)] + #[derive(Copy, Clone, Default, PartialEq, PartialOrd, serde::Serialize)] pub struct $Type($IT); impl $Type diff --git a/source/lib.rs b/source/lib.rs index 69156dd..c4688fd 100644 --- a/source/lib.rs +++ b/source/lib.rs @@ -10,7 +10,6 @@ #![deny(clippy::clone_on_ref_ptr)] #![deny(clippy::copy_iterator)] #![deny(clippy::decimal_literal_representation)] -#![deny(clippy::default_trait_access)] #![deny(clippy::doc_markdown)] #![deny(clippy::empty_enum)] #![deny(clippy::empty_line_after_outer_attr)] diff --git a/source/marathon/map.rs b/source/marathon/map.rs index f723d81..e7c3344 100644 --- a/source/marathon/map.rs +++ b/source/marathon/map.rs @@ -170,13 +170,11 @@ pub fn read_old_sids(b: &[u8]) -> ResultS<(Side, usize)> ..side}, siz)) } -/// Reads a `POLY` chunk. -pub fn read_poly(b: &[u8]) -> ResultS<(Polygon, usize)> +/// Reads a polygon for either M1 or M2. +fn read_poly_inter(b: &[u8]) -> ResultS { read_data! { 128, BE in b => - ptype = u16[0]; - pdata = i16[4]; tex_flr = OptU16[40]; tex_cei = OptU16[42]; hei_flr = Unit[44]; @@ -185,45 +183,51 @@ pub fn read_poly(b: &[u8]) -> ResultS<(Polygon, usize)> lit_cei = u16[50]; xfr_flr = u16[64]; xfr_cei = u16[66]; - ori_flr = read_point[108..112]; - ori_cei = read_point[112..116]; - med_ind = OptU16[116]; - med_ctl = u16[118]; - snd_ind = u16[120]; - snd_amb = OptU16[122]; - snd_rnd = OptU16[124]; } let xfr_flr = TransferMode::from_repr(xfr_flr)?; let xfr_cei = TransferMode::from_repr(xfr_cei)?; - let ptype = PolyType::from_repr(ptype)?; - Ok((Polygon{ptype, pdata, tex_flr, tex_cei, hei_flr, hei_cei, lit_flr, - lit_cei, xfr_flr, xfr_cei, ori_flr, ori_cei, med_ind, med_ctl, - snd_ind, snd_amb, snd_rnd}, 128)) + Ok(Polygon{tex_flr, tex_cei, hei_flr, hei_cei, lit_flr, lit_cei, xfr_flr, + xfr_cei, ..Default::default()}) +} + +/// Reads a `POLY` chunk. +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]; + } + + let poly = read_poly_inter(b)?; + let ptype = PolyType::new(ptype, pdata)?; + + Ok((Polygon{ptype, ori_flr, ori_cei, med_ind, med_ctl, snd_ind, snd_amb, + snd_rnd, ..poly}, 128)) } /// Reads an old `POLY` chunk. pub fn read_old_poly(b: &[u8]) -> ResultS<(Polygon, usize)> { - let (poly, siz) = read_poly(b)?; + read_data! { + 128, BE in b => + ptype = u16[0]; + pdata = u16[4]; + } - Ok((Polygon{ptype: match poly.ptype { - PolyType::Hill => PolyType::OuchMinor, - PolyType::Base => PolyType::OuchMajor, - PolyType::ZoneBorder => PolyType::Glue, - PolyType::Goal => PolyType::GlueTrigger, - PolyType::TrigMonsVis => PolyType::GlueSuper, - PolyType::TrigMonsInv => PolyType::MustExplore, - PolyType::TrigMonsDual => PolyType::AutoExit, - ptype => ptype, - }, - ori_flr: Point{x: 0.into(), y: 0.into()}, - ori_cei: Point{x: 0.into(), y: 0.into()}, - med_ind: OptU16::none(), - snd_amb: OptU16::none(), - snd_rnd: OptU16::none(), - ..poly}, siz)) + let poly = read_poly_inter(b)?; + let ptype = PolyType::new_old(ptype, pdata)?; + + Ok((Polygon{ptype, ..poly}, 128)) } /// Reads a `LITE` chunk. @@ -429,8 +433,70 @@ pub fn read_note(b: &[u8]) -> ResultS<(Note, usize)> Ok((Note{pos, poly, text}, 72)) } +impl PolyType +{ + fn new(n: u16, pdata: u16) -> Result + { + match n { + 0 => Ok(PolyType::Normal), + 1 => Ok(PolyType::ImpassItem), + 2 => Ok(PolyType::ImpassMons), + 3 => Ok(PolyType::Hill), + 4 => Ok(PolyType::Base), + 5 => Ok(PolyType::Platform(pdata)), + 6 => Ok(PolyType::TrigLightOn(pdata)), + 7 => Ok(PolyType::TrigPlatOn(pdata)), + 8 => Ok(PolyType::TrigLightOff(pdata)), + 9 => Ok(PolyType::TrigPlatOff(pdata)), + 10 => Ok(PolyType::Teleporter(pdata)), + 11 => Ok(PolyType::ZoneBorder), + 12 => Ok(PolyType::Goal), + 13 => Ok(PolyType::TrigMonsVis), + 14 => Ok(PolyType::TrigMonsInv), + 15 => Ok(PolyType::TrigMonsDual), + 16 => Ok(PolyType::TrigItems), + 17 => Ok(PolyType::MustExplore), + 18 => Ok(PolyType::AutoExit), + 19 => Ok(PolyType::OuchMinor), + 20 => Ok(PolyType::OuchMajor), + 21 => Ok(PolyType::Glue), + 22 => Ok(PolyType::GlueTrigger(pdata)), + 23 => Ok(PolyType::GlueSuper), + n => Err(ReprError::new(n)), + } + } + + fn new_old(n: u16, pdata: u16) -> Result + { + match n { + 0 => Ok(PolyType::Normal), + 1 => Ok(PolyType::ImpassItem), + 2 => Ok(PolyType::ImpassMons), + 3 => Ok(PolyType::OuchMinor), + 4 => Ok(PolyType::OuchMajor), + 5 => Ok(PolyType::Platform(pdata)), + 6 => Ok(PolyType::TrigLightOn(pdata)), + 7 => Ok(PolyType::TrigPlatOn(pdata)), + 8 => Ok(PolyType::TrigLightOff(pdata)), + 9 => Ok(PolyType::TrigPlatOff(pdata)), + 10 => Ok(PolyType::Teleporter(pdata)), + 11 => Ok(PolyType::Glue), + 12 => Ok(PolyType::GlueTrigger(pdata)), + 13 => Ok(PolyType::GlueSuper), + 14 => Ok(PolyType::MustExplore), + 15 => Ok(PolyType::AutoExit), + n => Err(ReprError::new(n)), + } + } +} + +impl Default for PolyType +{ + fn default() -> Self {PolyType::Normal} +} + /// A point in world-space. -#[derive(Clone, PartialEq, serde::Serialize)] +#[derive(Clone, Default, PartialEq, serde::Serialize)] pub struct Point { pub x: Unit, @@ -476,11 +542,10 @@ pub struct Side } /// A polygon segment. -#[derive(Debug, serde::Serialize)] +#[derive(Debug, Default, serde::Serialize)] pub struct Polygon { pub ptype: PolyType, - pub pdata: i16, pub tex_flr: OptU16, pub tex_cei: OptU16, pub hei_flr: Unit, @@ -630,6 +695,36 @@ pub struct Minf pub level_name: String, } +/// The action type of a `Polygon`. +#[derive(Debug, serde::Serialize)] +pub enum PolyType +{ + Normal, + ImpassItem, + ImpassMons, + Hill, + Base, + Platform(u16), + TrigLightOn(u16), + TrigPlatOn(u16), + TrigLightOff(u16), + TrigPlatOff(u16), + Teleporter(u16), + ZoneBorder, + Goal, + TrigMonsVis, + TrigMonsInv, + TrigMonsDual, + TrigItems, + MustExplore, + AutoExit, + OuchMinor, + OuchMajor, + Glue, + GlueTrigger(u16), + GlueSuper, +} + bitflags! { /// Flags for `Line`. #[derive(serde::Serialize)] @@ -790,38 +885,6 @@ c_enum! { } } -c_enum! { - /// The action type of a `Polygon`. - #[derive(Debug, serde::Serialize)] - pub enum PolyType: u16 - { - 0 => Normal, - 1 => ImpassItem, - 2 => ImpassMons, - 3 => Hill, - 4 => Base, - 5 => Platform, - 6 => TrigLightOn, - 7 => TrigPlatOn, - 8 => TrigLightOff, - 9 => TrigPlatOff, - 10 => Teleporter, - 11 => ZoneBorder, - 12 => Goal, - 13 => TrigMonsVis, - 14 => TrigMonsInv, - 15 => TrigMonsDual, - 16 => TrigItems, - 17 => MustExplore, - 18 => AutoExit, - 19 => OuchMinor, - 20 => OuchMajor, - 21 => Glue, - 22 => GlueTrigger, - 23 => GlueSuper, - } -} - c_enum! { /// The type of function for a `LightFunc`. #[derive(Debug, serde::Serialize)] diff --git a/source/marathon/xfer.rs b/source/marathon/xfer.rs index 792184a..d104738 100644 --- a/source/marathon/xfer.rs +++ b/source/marathon/xfer.rs @@ -2,6 +2,11 @@ use crate::durandal::err::*; +impl Default for TransferMode +{ + fn default() -> Self {TransferMode::Normal} +} + c_enum! { /// A rendering style for many things. #[derive(Debug, serde::Serialize)]