Maraiah/src/marathon/map.rs

364 lines
7.9 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>
{
read_data! {
88, BE in b =>
env_code = u16[0];
physi_id = u16[2];
music_id = u16[4];
msn_flag = u16[6];
env_flag = u16[8];
levelnam = mac_roman_conv[18..84] nt;
ent_flag = u32[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>
{
read_data! {
6, BE in b =>
offs = read_point[0..4];
tex_id = u16[4];
}
let tex_id = ObjID::from_repr(tex_id);
Ok(SideTex{offs, tex_id})
}
pub fn read_point(b: &[u8]) -> ResultS<Point>
{
read_data! {
4, BE in b =>
x = u16[0];
y = u16[2];
}
Ok(Point{x: Unit::from_bits(x), y: Unit::from_bits(y)})
}
pub fn read_epnt(b: &[u8]) -> ResultS<(Point, usize)>
{
read_data! {
16, BE in b =>
pnt = read_point[6..10];
}
Ok((pnt, 16))
}
pub fn read_pnts(b: &[u8]) -> ResultS<(Point, usize)>
{
Ok((read_point(b)?, 4))
}
pub fn read_lins(b: &[u8]) -> ResultS<(Line, usize)>
{
read_data! {
32, BE in b =>
pnt_beg = u16[0];
pnt_end = u16[2];
flags = u16[4];
side_fr = u16[12];
side_bk = u16[14];
poly_fr = u16[16];
poly_bk = u16[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)>
{
read_data! {
64, BE in b =>
stype = u16[0];
flags = u16[2];
tex_pri = read_sidetex[4..10];
tex_sec = read_sidetex[10..16];
tex_tra = read_sidetex[16..22];
paneltyp = u16[38];
paneldat = i16[40];
xfer_pri = u16[42];
xfer_sec = u16[44];
xfer_tra = u16[46];
shade = u32[48];
}
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 stype = SideType::from_repr(stype)?;
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)>
{
read_data! {
128, BE in b =>
ptype = u16[0];
flags = u16[2];
pdata = i16[4];
tex_flr = u16[40];
tex_cei = u16[42];
hei_flr = u16[44];
hei_cei = u16[46];
lit_flr = u16[48];
lit_cei = u16[50];
xfr_flr = u16[64];
xfr_cei = u16[66];
ori_flr = read_point[108..112];
ori_cei = read_point[112..116];
media = u16[116];
media_l = u16[118];
sound = u16[120];
snd_amb = u16[122];
snd_rnd = u16[124];
}
let flags = ok!(PolyFlags::from_bits(flags), "bad PolyFlags")?;
let xfr_flr = TransferMode::from_repr(xfr_flr)?;
let xfr_cei = TransferMode::from_repr(xfr_cei)?;
let ptype = PolyType::from_repr(ptype)?;
let tex_flr = ObjID::from_repr(tex_flr);
let tex_cei = ObjID::from_repr(tex_cei);
let snd_amb = ObjID::from_repr(snd_amb);
let snd_rnd = ObjID::from_repr(snd_rnd);
let hei_flr = Unit::from_bits(hei_flr);
let hei_cei = Unit::from_bits(hei_cei);
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(Clone, PartialEq, Serialize)]
pub struct Point
{
pub x: Unit,
pub 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, PartialEq, Serialize)]
pub struct Minf
{
pub env_code: u16,
pub physi_id: u16,
pub music_id: u16,
pub msn_flag: MsnFlags,
pub env_flag: EnvFlags,
pub ent_flag: EntFlags,
pub 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