191 lines
5.3 KiB
Rust
191 lines
5.3 KiB
Rust
//! `Polygon` type.
|
|
|
|
use super::pnts;
|
|
use crate::{bin::OptU16, err::*, fixed::Unit, xfer::TransferMode};
|
|
|
|
/// Reads a polygon for either M1 or M2.
|
|
pub fn read_poly_inter(b: &[u8]) -> ResultS<Polygon>
|
|
{
|
|
read_data! {
|
|
endian: BIG, buf: b, size: 128, start: 0, data {
|
|
let tex_flr = OptU16[40];
|
|
let tex_cei = OptU16[42];
|
|
let hei_flr = Unit[44];
|
|
let hei_cei = Unit[46];
|
|
let lit_flr = u16[48];
|
|
let lit_cei = u16[50];
|
|
let xfr_flr = u16[64] enum TransferMode;
|
|
let xfr_cei = u16[66] enum TransferMode;
|
|
}
|
|
}
|
|
|
|
Ok(Polygon{tex_flr, tex_cei, hei_flr, hei_cei, lit_flr, lit_cei, xfr_flr,
|
|
xfr_cei, ..Polygon::default()})
|
|
}
|
|
|
|
/// Reads a `POLY` chunk.
|
|
pub fn read(b: &[u8]) -> ResultS<(Polygon, usize)>
|
|
{
|
|
read_data! {
|
|
endian: BIG, buf: b, size: 128, start: 0, data {
|
|
let ptype = u16[0];
|
|
let pdata = u16[4];
|
|
let ori_flr = pnts::read_o[108; 4];
|
|
let ori_cei = pnts::read_o[112; 4];
|
|
let med_ind = OptU16[116];
|
|
let med_ctl = u16[118];
|
|
let snd_amb = OptU16[122];
|
|
let snd_ind = u16[120];
|
|
let snd_rnd = OptU16[124];
|
|
}
|
|
}
|
|
|
|
let poly = read_poly_inter(b)?;
|
|
let ptype = PolygonType::new(ptype, pdata)?;
|
|
|
|
Ok((Polygon{ptype, ori_flr, ori_cei, med_ind, med_ctl, snd_ind, snd_amb,
|
|
snd_rnd, ..poly}, 128))
|
|
}
|
|
|
|
/// Reads an old `POLY` chunk.
|
|
pub fn read_old(b: &[u8]) -> ResultS<(Polygon, usize)>
|
|
{
|
|
read_data! {
|
|
endian: BIG, buf: b, size: 128, start: 0, data {
|
|
let ptype = u16[0];
|
|
let pdata = u16[4];
|
|
}
|
|
}
|
|
|
|
let poly = read_poly_inter(b)?;
|
|
let ptype = PolygonType::new_old(ptype, pdata)?;
|
|
|
|
Ok((Polygon{ptype, ..poly}, 128))
|
|
}
|
|
|
|
impl PolygonType
|
|
{
|
|
/// Creates a `PolygonType` from a `n`/`pdata` pair.
|
|
pub fn new(n: u16, pdata: u16) -> Result<Self, ReprError>
|
|
{
|
|
match n {
|
|
0 => Ok(PolygonType::Normal),
|
|
1 => Ok(PolygonType::ImpassItem),
|
|
2 => Ok(PolygonType::ImpassMons),
|
|
3 => Ok(PolygonType::Hill),
|
|
4 => Ok(PolygonType::Base),
|
|
5 => Ok(PolygonType::Platform(pdata)),
|
|
6 => Ok(PolygonType::TrigLightOn(pdata)),
|
|
7 => Ok(PolygonType::TrigPlatOn(pdata)),
|
|
8 => Ok(PolygonType::TrigLightOff(pdata)),
|
|
9 => Ok(PolygonType::TrigPlatOff(pdata)),
|
|
10 => Ok(PolygonType::Teleporter(pdata)),
|
|
11 => Ok(PolygonType::ZoneBorder),
|
|
12 => Ok(PolygonType::Goal),
|
|
13 => Ok(PolygonType::TrigMonsVis),
|
|
14 => Ok(PolygonType::TrigMonsInv),
|
|
15 => Ok(PolygonType::TrigMonsDual),
|
|
16 => Ok(PolygonType::TrigItems),
|
|
17 => Ok(PolygonType::MustExplore),
|
|
18 => Ok(PolygonType::AutoExit),
|
|
19 => Ok(PolygonType::OuchMinor),
|
|
20 => Ok(PolygonType::OuchMajor),
|
|
21 => Ok(PolygonType::Glue),
|
|
22 => Ok(PolygonType::GlueTrigger(pdata)),
|
|
23 => Ok(PolygonType::GlueSuper),
|
|
n => Err(ReprError::new("PolygonType", n)),
|
|
}
|
|
}
|
|
|
|
/// Creates a `PolygonType` from a Marathon 1 compatible `n`/`pdata` pair.
|
|
fn new_old(n: u16, pdata: u16) -> Result<Self, ReprError>
|
|
{
|
|
match n {
|
|
0 => Ok(PolygonType::Normal),
|
|
1 => Ok(PolygonType::ImpassItem),
|
|
2 => Ok(PolygonType::ImpassMons),
|
|
3 => Ok(PolygonType::OuchMinor),
|
|
4 => Ok(PolygonType::OuchMajor),
|
|
5 => Ok(PolygonType::Platform(pdata)),
|
|
6 => Ok(PolygonType::TrigLightOn(pdata)),
|
|
7 => Ok(PolygonType::TrigPlatOn(pdata)),
|
|
8 => Ok(PolygonType::TrigLightOff(pdata)),
|
|
9 => Ok(PolygonType::TrigPlatOff(pdata)),
|
|
10 => Ok(PolygonType::Teleporter(pdata)),
|
|
11 => Ok(PolygonType::Glue),
|
|
12 => Ok(PolygonType::GlueTrigger(pdata)),
|
|
13 => Ok(PolygonType::GlueSuper),
|
|
14 => Ok(PolygonType::MustExplore),
|
|
15 => Ok(PolygonType::AutoExit),
|
|
n => Err(ReprError::new("PolygonType", n)),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for PolygonType
|
|
{
|
|
fn default() -> Self {PolygonType::Normal}
|
|
}
|
|
|
|
/// A polygon segment.
|
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
|
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
|
pub struct Polygon {
|
|
pub ptype: PolygonType,
|
|
pub tex_flr: OptU16,
|
|
pub tex_cei: OptU16,
|
|
pub hei_flr: Unit,
|
|
pub hei_cei: Unit,
|
|
pub lit_flr: u16,
|
|
pub lit_cei: u16,
|
|
pub xfr_flr: TransferMode,
|
|
pub xfr_cei: TransferMode,
|
|
pub ori_flr: pnts::Point,
|
|
pub ori_cei: pnts::Point,
|
|
pub med_ind: OptU16,
|
|
pub med_ctl: u16,
|
|
pub snd_ind: u16,
|
|
pub snd_amb: OptU16,
|
|
pub snd_rnd: OptU16,
|
|
}
|
|
|
|
/// The action type of a `Polygon`.
|
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
pub enum PolygonType {
|
|
Normal,
|
|
ImpassItem,
|
|
ImpassMons,
|
|
Hill,
|
|
Base,
|
|
Platform(u16),
|
|
TrigLightOn(u16),
|
|
TrigPlatOn(u16),
|
|
TrigLightOff(u16),
|
|
TrigPlatOff(u16),
|
|
Teleporter(u16),
|
|
ZoneBorder,
|
|
Goal,
|
|
TrigMonsVis,
|
|
TrigMonsInv,
|
|
TrigMonsDual,
|
|
TrigItems,
|
|
MustExplore,
|
|
AutoExit,
|
|
OuchMinor,
|
|
OuchMajor,
|
|
Glue,
|
|
GlueTrigger(u16),
|
|
GlueSuper,
|
|
}
|
|
|
|
c_bitfield! {
|
|
/// Flags for `Polygon`.
|
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
|
pub struct PolygonFlags: u16 {
|
|
DETACHED = 14,
|
|
}
|
|
}
|
|
|
|
// EOF
|