//! Marathon Map format handling. pub mod ambi; pub mod attk; pub mod bonk; pub mod chnk; pub mod damg; pub mod entr; pub mod epnt; pub mod fxpx; pub mod iidx; pub mod lins; pub mod lite; pub mod ltfn; pub mod medi; pub mod minf; pub mod mnpx; pub mod note; pub mod objs; pub mod plac; pub mod plat; pub mod pnts; pub mod poly; pub mod prpx; pub mod pxpx; pub mod sids; pub mod stex; pub mod term; pub mod trig; pub mod trmf; pub mod trmg; pub mod wppx; use crate::{durandal::err::*, marathon::text::mac_roman_cstr}; use std::convert::TryFrom; /// Reads a Map file. pub fn read(b: &[u8]) -> ResultS { read_data! { 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_wad { Ver::Base => true, _ => false, }; let siz_ent = if old_wad {8 } else {10}; let siz_cnk = if old_wad {12} else {16}; if !old_wad && siz_ent != siz_went { bail!("invalid entry size"); } if !old_wad && siz_cnk != siz_wcnk { bail!("invalid chunk size"); } let entries = entr::read(b, old_wad, old_dat, siz_app, siz_ent, siz_cnk)?; Ok(Wad{name, siz_app, entries}) } /// A Map file containing entries. #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[derive(Debug, Eq, PartialEq)] pub struct Wad { /// The original name of this file. pub name: String, /// The size of each `Entry`'s `appdata` field. pub siz_app: usize, /// All of the entries in this `Wad`. pub entries: entr::EntryMap, } c_enum! { /// The version of a `Wad`. #[derive(Debug)] enum Ver: u16 { Base = 0, Dir = 1, Over = 2, Inf = 4, } } /// The number of game ticks per second. pub const TICKS_PER_SECOND: u16 = 30; // EOF