195 lines
5.3 KiB
Rust
195 lines
5.3 KiB
Rust
|
//! `Polygon` type.
|
||
|
|
||
|
use super::pnts;
|
||
|
use crate::{bin::OptU16, err::*, fixed::Unit, xfer::TransferMode};
|
||
|
use bitflags::bitflags;
|
||
|
|
||
|
/// 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(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(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,
|
||
|
}
|
||
|
|
||
|
bitflags! {
|
||
|
/// Flags for `Polygon`.
|
||
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||
|
pub struct PolygonFlags: u16
|
||
|
{
|
||
|
const DETACHED = 1 << 14;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// EOF
|