Maraiah/maraiah/map/minf.rs

132 lines
2.8 KiB
Rust

//! `Info` type.
use crate::{err::*, text::*};
/// Reads a `Minf` chunk.
pub fn read(b: &[u8]) -> ResultS<Info>
{
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<u8>
{
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<Info>
{
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