Maraiah/source/marathon/map.rs

104 lines
2.0 KiB
Rust

//! 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<Wad>
{
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