197 lines
7.0 KiB
Rust
197 lines
7.0 KiB
Rust
//! Map file entry data.
|
|
|
|
use crate::{bin::*, err::*, image::{self, pict}, map};
|
|
use super::{entr, head};
|
|
use std::collections::BTreeMap;
|
|
|
|
/// Reads all chunks in an entry.
|
|
pub fn read(head: &head::Header, b: &[u8]) -> ResultS<EntryData>
|
|
{
|
|
let mut data = EntryData::default();
|
|
|
|
let old = head.old_data();
|
|
|
|
let rd_cminf = if old {map::minf::read_old} else {map::minf::read};
|
|
let rd_csids = if old {map::sids::read_old} else {map::sids::read};
|
|
let rd_cpoly = if old {map::poly::read_old} else {map::poly::read};
|
|
let rd_clite = if old {map::lite::read_old} else {map::lite::read};
|
|
|
|
let mut p = 0;
|
|
|
|
while p < b.len() {
|
|
read_data! {
|
|
endian: BIG, buf: b, size: head.size_chunk(), start: p, data {
|
|
let iden = Ident[0];
|
|
let size = u32[8] usize;
|
|
}
|
|
}
|
|
|
|
let beg = p + head.size_chunk();
|
|
let end = beg + size;
|
|
let buf = ok!(b.get(beg..end), "not enough data")?;
|
|
|
|
match &iden.0 {
|
|
b"EPNT" => data.epnt = Some(rd_array(buf, map::epnt::read)?),
|
|
b"FXpx" => data.fxpx = Some(rd_array(buf, map::fxpx::read)?),
|
|
b"LINS" => data.lins = Some(rd_array(buf, map::lins::read)?),
|
|
b"LITE" => data.lite = Some(rd_array(buf, rd_clite)?),
|
|
b"MNpx" => data.mnpx = Some(rd_array(buf, map::mnpx::read)?),
|
|
b"Minf" => data.minf = Some(rd_cminf(buf)?),
|
|
b"NAME" => data.name = Some(rd_array(buf, map::name::read)?),
|
|
b"NOTE" => data.note = Some(rd_array(buf, map::note::read)?),
|
|
b"OBJS" => data.objs = Some(rd_array(buf, map::objs::read)?),
|
|
b"PICT" => data.pict = Some(pict::read(buf)?),
|
|
b"PNTS" => data.pnts = Some(rd_array(buf, map::pnts::read)?),
|
|
b"POLY" => data.poly = Some(rd_array(buf, rd_cpoly)?),
|
|
b"PRpx" => data.prpx = Some(rd_array(buf, map::prpx::read)?),
|
|
b"PXpx" => data.pxpx = Some(rd_array(buf, map::pxpx::read)?),
|
|
b"SIDS" => data.sids = Some(rd_array(buf, rd_csids)?),
|
|
b"WPpx" => data.wppx = Some(rd_array(buf, map::wppx::read)?),
|
|
b"ambi" => data.ambi = Some(rd_array(buf, map::ambi::read)?),
|
|
b"bonk" => data.bonk = Some(rd_array(buf, map::bonk::read)?),
|
|
b"iidx" => data.iidx = Some(rd_array(buf, map::iidx::read)?),
|
|
b"medi" => data.medi = Some(rd_array(buf, map::medi::read)?),
|
|
b"plac" => data.plac = Some(rd_array(buf, map::plac::read)?),
|
|
b"plat" => data.plat = Some(rd_array(buf, map::plat::read)?),
|
|
b"term" => data.term = Some(rd_array(buf, map::term::read)?),
|
|
_ => data.unkn.push((iden, buf.to_vec())),
|
|
}
|
|
|
|
p = end;
|
|
}
|
|
|
|
Ok(data)
|
|
}
|
|
|
|
/// Reads all of the data from an entry map.
|
|
pub fn read_all(head: &head::Header,
|
|
map: &entr::EntryMap<'_>) -> ResultS<EntryDataMap>
|
|
{
|
|
let mut data_map = EntryDataMap::new();
|
|
|
|
for (&index, entry) in map {
|
|
data_map.insert(index, read(head, entry.data)?);
|
|
}
|
|
|
|
Ok(data_map)
|
|
}
|
|
|
|
impl EntryData
|
|
{
|
|
pub fn get_type(&self) -> EntryType
|
|
{
|
|
if self.has_minf() {
|
|
EntryType::Map
|
|
} else if self.has_fxpx() ||
|
|
self.has_mnpx() ||
|
|
self.has_prpx() ||
|
|
self.has_pxpx() ||
|
|
self.has_wppx() {
|
|
EntryType::Physics
|
|
} else if self.has_pict() {
|
|
EntryType::Image
|
|
} else {
|
|
EntryType::Other
|
|
}
|
|
}
|
|
|
|
pub fn has_epnt(&self) -> bool {self.epnt.is_some()}
|
|
pub fn has_fxpx(&self) -> bool {self.fxpx.is_some()}
|
|
pub fn has_lins(&self) -> bool {self.lins.is_some()}
|
|
pub fn has_lite(&self) -> bool {self.lite.is_some()}
|
|
pub fn has_mnpx(&self) -> bool {self.mnpx.is_some()}
|
|
pub fn has_minf(&self) -> bool {self.minf.is_some()}
|
|
pub fn has_name(&self) -> bool {self.name.is_some()}
|
|
pub fn has_note(&self) -> bool {self.note.is_some()}
|
|
pub fn has_objs(&self) -> bool {self.objs.is_some()}
|
|
pub fn has_pict(&self) -> bool {self.pict.is_some()}
|
|
pub fn has_pnts(&self) -> bool {self.pnts.is_some()}
|
|
pub fn has_poly(&self) -> bool {self.poly.is_some()}
|
|
pub fn has_prpx(&self) -> bool {self.prpx.is_some()}
|
|
pub fn has_pxpx(&self) -> bool {self.pxpx.is_some()}
|
|
pub fn has_sids(&self) -> bool {self.sids.is_some()}
|
|
pub fn has_wppx(&self) -> bool {self.wppx.is_some()}
|
|
pub fn has_ambi(&self) -> bool {self.ambi.is_some()}
|
|
pub fn has_bonk(&self) -> bool {self.bonk.is_some()}
|
|
pub fn has_iidx(&self) -> bool {self.iidx.is_some()}
|
|
pub fn has_medi(&self) -> bool {self.medi.is_some()}
|
|
pub fn has_plac(&self) -> bool {self.plac.is_some()}
|
|
pub fn has_plat(&self) -> bool {self.plat.is_some()}
|
|
pub fn has_term(&self) -> bool {self.term.is_some()}
|
|
|
|
pub fn num_unknown(&self) -> usize {self.unkn.len()}
|
|
|
|
pub fn len(&self) -> usize
|
|
{
|
|
self.num_unknown() +
|
|
usize::from(self.has_epnt()) +
|
|
usize::from(self.has_fxpx()) +
|
|
usize::from(self.has_lins()) +
|
|
usize::from(self.has_lite()) +
|
|
usize::from(self.has_mnpx()) +
|
|
usize::from(self.has_minf()) +
|
|
usize::from(self.has_name()) +
|
|
usize::from(self.has_note()) +
|
|
usize::from(self.has_objs()) +
|
|
usize::from(self.has_pict()) +
|
|
usize::from(self.has_pnts()) +
|
|
usize::from(self.has_poly()) +
|
|
usize::from(self.has_prpx()) +
|
|
usize::from(self.has_pxpx()) +
|
|
usize::from(self.has_sids()) +
|
|
usize::from(self.has_wppx()) +
|
|
usize::from(self.has_ambi()) +
|
|
usize::from(self.has_bonk()) +
|
|
usize::from(self.has_iidx()) +
|
|
usize::from(self.has_medi()) +
|
|
usize::from(self.has_plac()) +
|
|
usize::from(self.has_plat())
|
|
}
|
|
|
|
pub fn is_empty(&self) -> bool {self.len() == 0}
|
|
}
|
|
|
|
/// The abstract type of an entry.
|
|
pub enum EntryType {
|
|
Other,
|
|
Map,
|
|
Image,
|
|
Physics,
|
|
}
|
|
|
|
/// The loaded data of a Map file entry.
|
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
|
#[derive(Debug, Default, Eq, PartialEq)]
|
|
pub struct EntryData {
|
|
/** `EPNT` chunk data. */ pub epnt: Option<Vec<map::epnt::Endpoint>>,
|
|
/** `FXpx` chunk data. */ pub fxpx: Option<Vec<map::fxpx::Effect>>,
|
|
/** `LINS` chunk data. */ pub lins: Option<Vec<map::lins::Line>>,
|
|
/** `LITE` chunk data. */ pub lite: Option<Vec<map::lite::Light>>,
|
|
/** `MNpx` chunk data. */ pub mnpx: Option<Vec<map::mnpx::Monster>>,
|
|
/** `Minf` chunk data. */ pub minf: Option<map::minf::Info>,
|
|
/** `NAME` chunk data. */ pub name: Option<Vec<String>>,
|
|
/** `NOTE` chunk data. */ pub note: Option<Vec<map::note::Note>>,
|
|
/** `OBJS` chunk data. */ pub objs: Option<Vec<map::objs::Object>>,
|
|
/** `PICT` chunk data. */ pub pict: Option<image::Image8>,
|
|
/** `PNTS` chunk data. */ pub pnts: Option<Vec<map::pnts::Point>>,
|
|
/** `POLY` chunk data. */ pub poly: Option<Vec<map::poly::Polygon>>,
|
|
/** `PRpx` chunk data. */ pub prpx: Option<Vec<map::prpx::Projectile>>,
|
|
/** `PXpx` chunk data. */ pub pxpx: Option<Vec<map::pxpx::Physics>>,
|
|
/** `SIDS` chunk data. */ pub sids: Option<Vec<map::sids::Side>>,
|
|
/** `WPpx` chunk data. */ pub wppx: Option<Vec<map::wppx::Weapon>>,
|
|
/** `ambi` chunk data. */ pub ambi: Option<Vec<map::ambi::SoundAmbi>>,
|
|
/** `bonk` chunk data. */ pub bonk: Option<Vec<map::bonk::SoundRand>>,
|
|
/** `iidx` chunk data. */ pub iidx: Option<Vec<u16>>,
|
|
/** `medi` chunk data. */ pub medi: Option<Vec<map::medi::Media>>,
|
|
/** `plac` chunk data. */ pub plac: Option<Vec<map::plac::ObjectFreq>>,
|
|
/** `plat` chunk data. */ pub plat: Option<Vec<map::plat::Platform>>,
|
|
/** `term` chunk data. */ pub term: Option<Vec<map::term::Terminal>>,
|
|
|
|
pub unkn: Vec<(Ident, Vec<u8>)>,
|
|
}
|
|
|
|
/// A map of indexed entries.
|
|
pub type EntryDataMap = BTreeMap<u16, EntryData>;
|
|
|
|
// EOF
|