//! `Info` type. use crate::{err::*, text::*}; /// Reads a `Minf` chunk. pub fn read(b: &[u8]) -> ResultS { read_data! { 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 MissionFlags; let envi_flags = u16[8] flag EnvironmentFlags; let level_name = mac_roman_cstr[18; 66] no_try; let entr_flags = u32[84] flag EntryFlags; } } Ok(Info{texture_id, physics_id, skypict_id, miss_flags, envi_flags, entr_flags, level_name}) } /// Writes a `Minf` chunk. pub fn write(v: &Info) -> Vec { let mut o = Vec::with_capacity(4); o.extend(&v.texture_id.to_be_bytes()); o.extend(&v.physics_id.to_be_bytes()); o.extend(&v.skypict_id.to_be_bytes()); o.extend(&v.miss_flags.bits().to_be_bytes()); o.extend(&v.envi_flags.bits().to_be_bytes()); o.extend(&pad_zero(to_mac_roman(&v.level_name), 66)); o.extend(&v.entr_flags.bits().to_be_bytes()); o } /// Reads an old `Minf` chunk. pub fn read_old(b: &[u8]) -> ResultS { let minf = read(b)?; let mut entr_flags = if minf.entr_flags.is_empty() { EntryFlags::SOLO } else { minf.entr_flags }; if entr_flags.intersects(EntryFlags::SOLO | EntryFlags::CARNAGE) { entr_flags.insert(EntryFlags::CO_OP) } Ok(Info{entr_flags, ..minf}) } impl Default for Info { fn default() -> Self { Self{texture_id: 0, physics_id: 1, skypict_id: 0, miss_flags: MissionFlags::empty(), envi_flags: EnvironmentFlags::empty(), entr_flags: EntryFlags::SOLO, level_name: "Map".to_string()} } } /// Static map information. #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[derive(Clone, Debug, Eq, PartialEq)] pub struct Info { pub texture_id: u16, pub physics_id: u16, pub skypict_id: u16, pub miss_flags: MissionFlags, pub envi_flags: EnvironmentFlags, pub entr_flags: EntryFlags, pub level_name: String, } c_bitfield! { /// Static environment flags. #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] pub struct EnvironmentFlags: u16 { VACUUM = 0, MAGNETIC = 1, REBELLION = 2, LOW_GRAV = 3, M1_GLUE = 4, LAVA_FLOOR = 5, REBELLION2 = 6, MUSIC = 7, TERM_PAUSE = 8, M1_MONSTER = 9, M1_WEPS = 10, } } c_bitfield! { /// Static entry point flags. #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] pub struct EntryFlags: u32 { SOLO = 0, CO_OP = 1, CARNAGE = 2, KTMWTB = 3, KOTH = 4, DEFENSE = 5, RUGBY = 6, CTF = 7, } } c_bitfield! { /// Static mission flags. #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] pub struct MissionFlags: u16 { EXTERMINATION = 0, EXPLORATION = 1, RETRIEVAL = 2, REPAIR = 3, RESCUE = 4, M1_EXPLORATION = 5, M1_RESCUE = 6, M1_REPAIR = 7, } } // EOF