335 lines
8.0 KiB
Rust
335 lines
8.0 KiB
Rust
use crate::{durandal::{bin::*, err::*, fixed::*,
|
|
text::mac_roman_conv},
|
|
marathon::xfer::TransferMode};
|
|
use bitflags::bitflags;
|
|
use serde::Serialize;
|
|
use std::fmt;
|
|
|
|
pub fn read_minf(b: &[u8]) -> ResultS<Minf>
|
|
{
|
|
let env_code = c_u16b(b, 0)?;
|
|
let physi_id = c_u16b(b, 2)?;
|
|
let music_id = c_u16b(b, 4)?;
|
|
let msn_flag = c_u16b(b, 6)?;
|
|
let env_flag = c_u16b(b, 8)?;
|
|
let levelnam = mac_roman_conv(c_data(b, 18..84)?);
|
|
let ent_flag = c_u32b(b, 84)?;
|
|
let msn_flag = ok!(MsnFlags::from_bits(msn_flag), "bad MsnFlags")?;
|
|
let env_flag = ok!(EnvFlags::from_bits(env_flag), "bad EnvFlags")?;
|
|
let ent_flag = ok!(EntFlags::from_bits(ent_flag), "bad EntFlags")?;
|
|
Ok(Minf{env_code, physi_id, music_id, msn_flag, env_flag, ent_flag,
|
|
levelnam})
|
|
}
|
|
|
|
pub fn read_sidetex(b: &[u8]) -> ResultS<SideTex>
|
|
{
|
|
let offs = read_point(c_data(b, 0..4)?)?;
|
|
let tex_id = c_u16b(b, 4)?;
|
|
let tex_id = ObjID::from_repr(tex_id);
|
|
Ok(SideTex{offs, tex_id})
|
|
}
|
|
|
|
pub fn read_point(b: &[u8]) -> ResultS<Point>
|
|
{
|
|
let x = c_u16b(b, 0)?;
|
|
let y = c_u16b(b, 2)?;
|
|
let x = Unit::from_bits(x);
|
|
let y = Unit::from_bits(y);
|
|
Ok(Point{x, y})
|
|
}
|
|
|
|
pub fn read_epnt(b: &[u8]) -> ResultS<(Point, usize)>
|
|
{
|
|
Ok((read_point(c_data(b, 6..10)?)?, 16))
|
|
}
|
|
|
|
pub fn read_pnts(b: &[u8]) -> ResultS<(Point, usize)>
|
|
{
|
|
Ok((read_point(b)?, 4))
|
|
}
|
|
|
|
pub fn read_lins(b: &[u8]) -> ResultS<(Line, usize)>
|
|
{
|
|
let pnt_beg = c_u16b(b, 0)?;
|
|
let pnt_end = c_u16b(b, 2)?;
|
|
let flags = c_u16b(b, 4)?;
|
|
let side_fr = c_u16b(b, 12)?;
|
|
let side_bk = c_u16b(b, 14)?;
|
|
let poly_fr = c_u16b(b, 16)?;
|
|
let poly_bk = c_u16b(b, 18)?;
|
|
let flags = ok!(LineFlags::from_bits(flags), "bad LineFlags")?;
|
|
let side_fr = ObjID::from_repr(side_fr);
|
|
let side_bk = ObjID::from_repr(side_bk);
|
|
let poly_fr = ObjID::from_repr(poly_fr);
|
|
let poly_bk = ObjID::from_repr(poly_bk);
|
|
Ok((Line{flags, pnt_beg, pnt_end, side_fr, side_bk, poly_fr, poly_bk}, 32))
|
|
}
|
|
|
|
pub fn read_sids(b: &[u8]) -> ResultS<(Side, usize)>
|
|
{
|
|
let stype = c_u16b(b, 0)?;
|
|
let flags = c_u16b(b, 2)?;
|
|
let tex_pri = read_sidetex(c_data(b, 4..10)?)?;
|
|
let tex_sec = read_sidetex(c_data(b, 10..16)?)?;
|
|
let tex_tra = read_sidetex(c_data(b, 16..22)?)?;
|
|
let paneltyp = c_u16b(b, 38)?;
|
|
let paneldat = c_i16b(b, 40)?;
|
|
let xfer_pri = c_u16b(b, 42)?;
|
|
let xfer_sec = c_u16b(b, 44)?;
|
|
let xfer_tra = c_u16b(b, 46)?;
|
|
let shade = c_u32b(b, 48)?;
|
|
let stype = SideType::from_repr(stype)?;
|
|
let flags = ok!(SideFlags::from_bits(flags), "bad SideFlags")?;
|
|
let xfer_pri = TransferMode::from_repr(xfer_pri)?;
|
|
let xfer_sec = TransferMode::from_repr(xfer_sec)?;
|
|
let xfer_tra = TransferMode::from_repr(xfer_tra)?;
|
|
let shade = Fixed::from_bits(shade);
|
|
Ok((Side{stype, flags, tex_pri, tex_sec, tex_tra, paneltyp, paneldat,
|
|
xfer_pri, xfer_sec, xfer_tra, shade}, 64))
|
|
}
|
|
|
|
pub fn read_poly(b: &[u8]) -> ResultS<(Polygon, usize)>
|
|
{
|
|
let ptype = c_u16b(b, 0)?;
|
|
let flags = c_u16b(b, 2)?;
|
|
let pdata = c_i16b(b, 4)?;
|
|
let tex_flr = c_u16b(b, 40)?;
|
|
let tex_cei = c_u16b(b, 42)?;
|
|
let hei_flr = c_u16b(b, 44)?;
|
|
let hei_cei = c_u16b(b, 46)?;
|
|
let lit_flr = c_u16b(b, 48)?;
|
|
let lit_cei = c_u16b(b, 50)?;
|
|
let xfr_flr = c_u16b(b, 64)?;
|
|
let xfr_cei = c_u16b(b, 66)?;
|
|
let ori_flr = read_point(c_data(b, 108..112)?)?;
|
|
let ori_cei = read_point(c_data(b, 112..116)?)?;
|
|
let media = c_u16b(b, 116)?;
|
|
let media_l = c_u16b(b, 118)?;
|
|
let sound = c_u16b(b, 120)?;
|
|
let snd_amb = c_u16b(b, 122)?;
|
|
let snd_rnd = c_u16b(b, 124)?;
|
|
let ptype = PolyType::from_repr(ptype)?;
|
|
let flags = ok!(PolyFlags::from_bits(flags), "bad PolyFlags")?;
|
|
let tex_flr = ObjID::from_repr(tex_flr);
|
|
let tex_cei = ObjID::from_repr(tex_cei);
|
|
let hei_flr = Unit::from_bits(hei_flr);
|
|
let hei_cei = Unit::from_bits(hei_cei);
|
|
let xfr_flr = TransferMode::from_repr(xfr_flr)?;
|
|
let xfr_cei = TransferMode::from_repr(xfr_cei)?;
|
|
let snd_amb = ObjID::from_repr(snd_amb);
|
|
let snd_rnd = ObjID::from_repr(snd_rnd);
|
|
|
|
Ok((Polygon{ptype, flags, pdata, tex_flr, tex_cei, hei_flr, hei_cei,
|
|
lit_flr, lit_cei, xfr_flr, xfr_cei, ori_flr, ori_cei, media,
|
|
media_l, sound, snd_amb, snd_rnd},
|
|
128))
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct Point
|
|
{
|
|
x: Unit,
|
|
y: Unit,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
pub struct Line
|
|
{
|
|
flags: LineFlags,
|
|
pnt_beg: u16,
|
|
pnt_end: u16,
|
|
side_fr: ObjID,
|
|
side_bk: ObjID,
|
|
poly_fr: ObjID,
|
|
poly_bk: ObjID,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
pub struct SideTex
|
|
{
|
|
offs: Point,
|
|
tex_id: ObjID,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
pub struct Side
|
|
{
|
|
stype: SideType,
|
|
flags: SideFlags,
|
|
tex_pri: SideTex,
|
|
tex_sec: SideTex,
|
|
tex_tra: SideTex,
|
|
paneltyp: u16,
|
|
paneldat: i16,
|
|
xfer_pri: TransferMode,
|
|
xfer_sec: TransferMode,
|
|
xfer_tra: TransferMode,
|
|
shade: Fixed,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
pub struct Polygon
|
|
{
|
|
ptype: PolyType,
|
|
flags: PolyFlags,
|
|
pdata: i16,
|
|
tex_flr: ObjID,
|
|
tex_cei: ObjID,
|
|
hei_flr: Unit,
|
|
hei_cei: Unit,
|
|
lit_flr: u16,
|
|
lit_cei: u16,
|
|
xfr_flr: TransferMode,
|
|
xfr_cei: TransferMode,
|
|
ori_flr: Point,
|
|
ori_cei: Point,
|
|
media: u16,
|
|
media_l: u16,
|
|
sound: u16,
|
|
snd_amb: ObjID,
|
|
snd_rnd: ObjID,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
pub struct Minf
|
|
{
|
|
env_code: u16,
|
|
physi_id: u16,
|
|
music_id: u16,
|
|
msn_flag: MsnFlags,
|
|
env_flag: EnvFlags,
|
|
ent_flag: EntFlags,
|
|
levelnam: String,
|
|
}
|
|
|
|
bitflags! {
|
|
#[derive(Serialize)]
|
|
pub struct LineFlags: u16
|
|
{
|
|
const TransSide = 1 << 9;
|
|
const ElevVar = 1 << 10;
|
|
const Elevation = 1 << 11;
|
|
const Landscape = 1 << 12;
|
|
const Transparent = 1 << 13;
|
|
const Solid = 1 << 14;
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
#[derive(Serialize)]
|
|
pub struct SideFlags: u16
|
|
{
|
|
const Status = 1;
|
|
const Panel = 1 << 1;
|
|
const Repair = 1 << 2;
|
|
const ItemUse = 1 << 3;
|
|
const Lighted = 1 << 4;
|
|
const CanDestroy = 1 << 5;
|
|
const HitOnly = 1 << 6;
|
|
const ItemOpt = 1 << 7;
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
#[derive(Serialize)]
|
|
pub struct EnvFlags: u16
|
|
{
|
|
const Vacuum = 1;
|
|
const Magnetic = 1 << 1;
|
|
const Rebellion = 1 << 2;
|
|
const LowGrav = 1 << 3;
|
|
const M1Glue = 1 << 4;
|
|
const LavaFloor = 1 << 5;
|
|
const Rebellion2 = 1 << 6;
|
|
const Music = 1 << 7;
|
|
const TermPause = 1 << 8;
|
|
const M1Monster = 1 << 9;
|
|
const M1Weps = 1 << 10;
|
|
const NetPlay = 1 << 13;
|
|
const Solo = 1 << 14;
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
#[derive(Serialize)]
|
|
pub struct EntFlags: u32
|
|
{
|
|
const Solo = 1;
|
|
const CoOp = 1 << 1;
|
|
const Carnage = 1 << 2;
|
|
const KTMWTB = 1 << 3;
|
|
const KOTH = 1 << 4;
|
|
const Defense = 1 << 5;
|
|
const Rugby = 1 << 6;
|
|
const CTF = 1 << 7;
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
#[derive(Serialize)]
|
|
pub struct MsnFlags: u16
|
|
{
|
|
const Extermination = 1;
|
|
const Exploration = 1 << 1;
|
|
const Retrieval = 1 << 2;
|
|
const Repair = 1 << 3;
|
|
const Rescue = 1 << 4;
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
#[derive(Serialize)]
|
|
pub struct PolyFlags: u16
|
|
{
|
|
const Detached = 1 << 14;
|
|
}
|
|
}
|
|
|
|
c_enum! {
|
|
#[derive(Debug, Serialize)]
|
|
pub enum SideType: u16
|
|
{
|
|
0 => Full,
|
|
1 => High,
|
|
2 => Low,
|
|
3 => Composite,
|
|
4 => Split,
|
|
}
|
|
}
|
|
|
|
c_enum! {
|
|
#[derive(Debug, Serialize)]
|
|
pub enum PolyType: u16
|
|
{
|
|
0 => Normal,
|
|
1 => ImpassItem,
|
|
2 => ImpassMons,
|
|
3 => Hill,
|
|
4 => Base,
|
|
5 => Platform,
|
|
6 => TrigLightOn,
|
|
7 => TrigPlatOn,
|
|
8 => TrigLightOff,
|
|
9 => TrigPlatOff,
|
|
10 => Teleporter,
|
|
11 => ZoneBorder,
|
|
12 => Goal,
|
|
13 => TrigMonsVis,
|
|
14 => TrigMonsInv,
|
|
15 => TrigMonsDual,
|
|
16 => TrigItems,
|
|
17 => MustExplore,
|
|
18 => AutoExit,
|
|
}
|
|
}
|
|
|
|
impl fmt::Debug for Point
|
|
{
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
|
|
{
|
|
write!(f, "({}, {})", self.x, self.y)
|
|
}
|
|
}
|
|
|
|
// EOF
|