2019-02-12 09:53:25 -08:00
|
|
|
use crate::{durandal::{bin::*, chunk::*, err::*, fx32::*,
|
|
|
|
text::mac_roman_conv},
|
2019-02-12 05:33:23 -08:00
|
|
|
marathon::xfer::TransferMode};
|
2019-02-08 21:53:27 -08:00
|
|
|
use bitflags::bitflags;
|
2019-02-12 14:32:16 -08:00
|
|
|
use serde::Serialize;
|
2018-12-13 01:08:02 -08:00
|
|
|
use std::fmt;
|
2018-12-11 19:59:15 -08:00
|
|
|
|
2018-12-13 01:08:02 -08:00
|
|
|
impl Chunked<Point> for Point
|
2018-12-11 19:59:15 -08:00
|
|
|
{
|
2018-12-13 01:08:02 -08:00
|
|
|
const SIZE_CHUNK: usize = 4;
|
|
|
|
|
2019-02-09 11:01:35 -08:00
|
|
|
fn read(b: &[u8]) -> ResultS<Self>
|
2018-12-13 01:08:02 -08:00
|
|
|
{
|
2019-02-10 20:29:06 -08:00
|
|
|
let x = c_i16b(b, 0)?;
|
|
|
|
let y = c_i16b(b, 2)?;
|
2018-12-13 01:08:02 -08:00
|
|
|
Ok(Point{x, y})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Chunked<Endpoint> for Endpoint
|
|
|
|
{
|
|
|
|
const SIZE_CHUNK: usize = 16;
|
|
|
|
|
2019-02-09 11:01:35 -08:00
|
|
|
fn read(b: &[u8]) -> ResultS<Self>
|
2018-12-13 01:08:02 -08:00
|
|
|
{
|
2019-02-10 20:29:06 -08:00
|
|
|
let flags = c_u16b(b, 0)?;
|
|
|
|
let adj_hi = c_i16b(b, 2)?;
|
|
|
|
let adj_lo = c_i16b(b, 4)?;
|
2019-02-10 02:31:57 -08:00
|
|
|
let pos = Point::read(c_data(b, 6..10)?)?;
|
2019-02-10 20:29:06 -08:00
|
|
|
let support = c_u16b(b, 14)?;
|
2019-02-10 02:31:57 -08:00
|
|
|
let flags = ok!(EndpFlags::from_bits(flags), "bad EndpFlags")?;
|
2018-12-13 01:08:02 -08:00
|
|
|
Ok(Endpoint{flags, adj_hi, adj_lo, pos, support})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Chunked<Line> for Line
|
|
|
|
{
|
|
|
|
const SIZE_CHUNK: usize = 32;
|
|
|
|
|
2019-02-09 11:01:35 -08:00
|
|
|
fn read(b: &[u8]) -> ResultS<Self>
|
2018-12-13 01:08:02 -08:00
|
|
|
{
|
2019-02-10 20:29:06 -08:00
|
|
|
let epnt_f = c_u16b(b, 0)?;
|
|
|
|
let epnt_b = c_u16b(b, 2)?;
|
|
|
|
let flags = c_u16b(b, 4)?;
|
|
|
|
let length = c_i16b(b, 6)?;
|
|
|
|
let adj_hi = c_i16b(b, 8)?;
|
|
|
|
let adj_lo = c_i16b(b, 10)?;
|
|
|
|
let side_f = c_u16b(b, 12)?;
|
|
|
|
let side_b = c_u16b(b, 14)?;
|
|
|
|
let poly_f = c_u16b(b, 16)?;
|
|
|
|
let poly_b = c_u16b(b, 18)?;
|
2019-02-10 02:31:57 -08:00
|
|
|
let flags = ok!(LineFlags::from_bits(flags), "bad LineFlags")?;
|
2019-02-05 23:01:47 -08:00
|
|
|
Ok(Line{flags, length, adj_hi, adj_lo, epnt_f, epnt_b, side_f, side_b,
|
|
|
|
poly_f, poly_b})
|
2018-12-13 01:08:02 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-09 11:01:35 -08:00
|
|
|
impl SideTex
|
2018-12-13 01:08:02 -08:00
|
|
|
{
|
2019-02-09 11:01:35 -08:00
|
|
|
fn read(b: &[u8]) -> ResultS<Self>
|
|
|
|
{
|
2019-02-10 02:31:57 -08:00
|
|
|
let offs = Point::read(c_data(b, 0..4)?)?;
|
2019-02-10 20:29:06 -08:00
|
|
|
let tex_id = c_u16b(b, 4)?;
|
2019-02-09 11:01:35 -08:00
|
|
|
let tex_id = ObjID::from_repr(tex_id);
|
|
|
|
Ok(SideTex{offs, tex_id})
|
|
|
|
}
|
2018-12-13 01:08:02 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Chunked<Side> for Side
|
|
|
|
{
|
|
|
|
const SIZE_CHUNK: usize = 64;
|
|
|
|
|
2019-02-09 11:01:35 -08:00
|
|
|
fn read(b: &[u8]) -> ResultS<Self>
|
2018-12-11 19:59:15 -08:00
|
|
|
{
|
2019-02-10 20:29:06 -08:00
|
|
|
let stype = c_u16b(b, 0)?;
|
|
|
|
let flags = c_u16b(b, 2)?;
|
2019-02-10 02:31:57 -08:00
|
|
|
let tex_pri = SideTex::read(c_data(b, 4..10)?)?;
|
|
|
|
let tex_sec = SideTex::read(c_data(b, 10..16)?)?;
|
|
|
|
let tex_tra = SideTex::read(c_data(b, 16..22)?)?;
|
|
|
|
let ex_tleft = Point::read(c_data(b, 22..26)?)?;
|
|
|
|
let ex_trigh = Point::read(c_data(b, 26..30)?)?;
|
|
|
|
let ex_bleft = Point::read(c_data(b, 30..34)?)?;
|
|
|
|
let ex_brigh = Point::read(c_data(b, 34..38)?)?;
|
2019-02-10 20:29:06 -08:00
|
|
|
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)?;
|
2019-02-10 02:31:57 -08:00
|
|
|
let flags = ok!(SideFlags::from_bits(flags), "bad SideFlags")?;
|
2019-02-12 05:33:23 -08:00
|
|
|
let xfer_pri = TransferMode::from_repr(xfer_pri)?;
|
|
|
|
let xfer_sec = TransferMode::from_repr(xfer_sec)?;
|
|
|
|
let xfer_tra = TransferMode::from_repr(xfer_tra)?;
|
2019-02-08 21:53:27 -08:00
|
|
|
let shade = Fx32::from_bits(shade);
|
2018-12-13 01:08:02 -08:00
|
|
|
Ok(Side{stype, flags, tex_pri, tex_sec, tex_tra, ex_tleft, ex_trigh,
|
|
|
|
ex_bleft, ex_brigh, paneltyp, paneldat, xfer_pri, xfer_sec,
|
|
|
|
xfer_tra, shade})
|
|
|
|
}
|
|
|
|
}
|
2018-12-11 19:59:15 -08:00
|
|
|
|
2018-12-13 01:08:02 -08:00
|
|
|
impl Chunker<Minf> for Minf
|
|
|
|
{
|
2019-02-09 11:01:35 -08:00
|
|
|
fn chunk(b: &[u8]) -> ResultS<Self>
|
2018-12-13 01:08:02 -08:00
|
|
|
{
|
2019-02-10 20:29:06 -08:00
|
|
|
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)?;
|
2019-02-10 02:31:57 -08:00
|
|
|
let levelnam = mac_roman_conv(c_data(b, 18..84)?);
|
2019-02-10 20:29:06 -08:00
|
|
|
let ent_flag = c_u32b(b, 84)?;
|
2019-02-10 02:31:57 -08:00
|
|
|
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")?;
|
2019-02-05 23:01:47 -08:00
|
|
|
Ok(Minf{env_code, physi_id, music_id, msn_flag, env_flag, ent_flag,
|
|
|
|
levelnam})
|
2018-12-11 19:59:15 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-13 01:08:02 -08:00
|
|
|
type Unit = i16;
|
|
|
|
|
2019-02-12 14:32:16 -08:00
|
|
|
#[derive(Serialize)]
|
2018-12-13 01:08:02 -08:00
|
|
|
pub struct Point
|
|
|
|
{
|
|
|
|
x: Unit,
|
|
|
|
y: Unit,
|
|
|
|
}
|
|
|
|
|
2019-02-12 14:32:16 -08:00
|
|
|
#[derive(Debug, Serialize)]
|
2018-12-13 01:08:02 -08:00
|
|
|
pub struct Endpoint
|
|
|
|
{
|
2019-02-10 02:31:57 -08:00
|
|
|
flags: EndpFlags,
|
2019-02-08 21:53:27 -08:00
|
|
|
adj_hi: Unit,
|
|
|
|
adj_lo: Unit,
|
|
|
|
pos: Point,
|
2018-12-13 01:08:02 -08:00
|
|
|
support: u16,
|
|
|
|
}
|
|
|
|
|
2019-02-12 14:32:16 -08:00
|
|
|
#[derive(Debug, Serialize)]
|
2018-12-13 01:08:02 -08:00
|
|
|
pub struct Line
|
|
|
|
{
|
2019-02-08 21:53:27 -08:00
|
|
|
flags: LineFlags,
|
2018-12-13 01:08:02 -08:00
|
|
|
length: Unit,
|
|
|
|
adj_hi: Unit,
|
|
|
|
adj_lo: Unit,
|
|
|
|
epnt_f: u16,
|
|
|
|
epnt_b: u16,
|
|
|
|
side_f: u16,
|
|
|
|
side_b: u16,
|
|
|
|
poly_f: u16,
|
|
|
|
poly_b: u16,
|
|
|
|
}
|
|
|
|
|
2019-02-12 14:32:16 -08:00
|
|
|
#[derive(Debug, Serialize)]
|
2018-12-13 01:08:02 -08:00
|
|
|
pub struct SideTex
|
|
|
|
{
|
2019-02-08 21:53:27 -08:00
|
|
|
offs: Point,
|
2019-02-09 11:01:35 -08:00
|
|
|
tex_id: ObjID,
|
2018-12-13 01:08:02 -08:00
|
|
|
}
|
|
|
|
|
2019-02-12 14:32:16 -08:00
|
|
|
#[derive(Debug, Serialize)]
|
2018-12-13 01:08:02 -08:00
|
|
|
pub struct Side
|
|
|
|
{
|
2019-02-08 21:53:27 -08:00
|
|
|
stype: u16,
|
|
|
|
flags: SideFlags,
|
|
|
|
tex_pri: SideTex,
|
|
|
|
tex_sec: SideTex,
|
|
|
|
tex_tra: SideTex,
|
2018-12-13 01:08:02 -08:00
|
|
|
ex_tleft: Point,
|
|
|
|
ex_trigh: Point,
|
|
|
|
ex_bleft: Point,
|
|
|
|
ex_brigh: Point,
|
2019-02-05 01:28:29 -08:00
|
|
|
paneltyp: u16,
|
2018-12-13 01:08:02 -08:00
|
|
|
paneldat: i16,
|
2019-02-12 05:33:23 -08:00
|
|
|
xfer_pri: TransferMode,
|
|
|
|
xfer_sec: TransferMode,
|
|
|
|
xfer_tra: TransferMode,
|
2019-02-08 21:53:27 -08:00
|
|
|
shade: Fx32,
|
2018-12-13 01:08:02 -08:00
|
|
|
}
|
|
|
|
|
2019-02-12 14:32:16 -08:00
|
|
|
#[derive(Debug, Serialize)]
|
2018-12-11 19:59:15 -08:00
|
|
|
pub struct Minf
|
|
|
|
{
|
|
|
|
env_code: u16,
|
|
|
|
physi_id: u16,
|
|
|
|
music_id: u16,
|
2018-12-13 01:08:02 -08:00
|
|
|
msn_flag: MsnFlags,
|
|
|
|
env_flag: EnvFlags,
|
|
|
|
ent_flag: EntFlags,
|
2018-12-11 19:59:15 -08:00
|
|
|
levelnam: String,
|
|
|
|
}
|
|
|
|
|
2018-12-13 01:08:02 -08:00
|
|
|
bitflags! {
|
2019-02-12 14:32:16 -08:00
|
|
|
#[derive(Serialize)]
|
2019-02-10 02:31:57 -08:00
|
|
|
pub struct EndpFlags: u16
|
2018-12-13 01:08:02 -08:00
|
|
|
{
|
|
|
|
const Solid = 0x00_01;
|
|
|
|
const SameHeight = 0x00_02;
|
|
|
|
const Transparent = 0x00_04;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bitflags! {
|
2019-02-12 14:32:16 -08:00
|
|
|
#[derive(Serialize)]
|
2018-12-13 01:08:02 -08:00
|
|
|
pub struct LineFlags: u16
|
|
|
|
{
|
|
|
|
const TransSide = 0x02_00;
|
|
|
|
const ElevVar = 0x04_00;
|
|
|
|
const Elevation = 0x08_00;
|
|
|
|
const Landscape = 0x10_00;
|
|
|
|
const Transparent = 0x20_00;
|
|
|
|
const Solid = 0x40_00;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bitflags! {
|
2019-02-12 14:32:16 -08:00
|
|
|
#[derive(Serialize)]
|
2018-12-13 01:08:02 -08:00
|
|
|
pub struct SideFlags: u16
|
|
|
|
{
|
|
|
|
const Status = 0x00_01;
|
|
|
|
const Panel = 0x00_02;
|
|
|
|
const Repair = 0x00_04;
|
|
|
|
const ItemUse = 0x00_08;
|
|
|
|
const Lighted = 0x00_10;
|
|
|
|
const CanDestroy = 0x00_20;
|
|
|
|
const HitOnly = 0x00_40;
|
|
|
|
const ItemOpt = 0x00_80;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bitflags! {
|
2019-02-12 14:32:16 -08:00
|
|
|
#[derive(Serialize)]
|
2018-12-13 01:08:02 -08:00
|
|
|
pub struct EnvFlags: u16
|
|
|
|
{
|
|
|
|
const Vacuum = 0x00_01;
|
|
|
|
const Magnetic = 0x00_02;
|
|
|
|
const Rebellion = 0x00_04;
|
|
|
|
const LowGrav = 0x00_08;
|
|
|
|
const M1Glue = 0x00_10;
|
|
|
|
const LavaFloor = 0x00_20;
|
|
|
|
const Rebellion2 = 0x00_40;
|
|
|
|
const Music = 0x00_80;
|
|
|
|
const TermPause = 0x01_00;
|
|
|
|
const M1Monster = 0x02_00;
|
|
|
|
const M1Weps = 0x04_00;
|
|
|
|
const NetPlay = 0x20_00;
|
|
|
|
const Solo = 0x40_00;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bitflags! {
|
2019-02-12 14:32:16 -08:00
|
|
|
#[derive(Serialize)]
|
2018-12-13 01:08:02 -08:00
|
|
|
pub struct EntFlags: u32
|
|
|
|
{
|
|
|
|
const Solo = 0x00_01;
|
|
|
|
const CoOp = 0x00_02;
|
|
|
|
const Carnage = 0x00_04;
|
|
|
|
const KTMWTB = 0x00_08;
|
|
|
|
const KOTH = 0x00_10;
|
|
|
|
const Defense = 0x00_20;
|
|
|
|
const Rugby = 0x00_40;
|
|
|
|
const CTF = 0x00_80;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bitflags! {
|
2019-02-12 14:32:16 -08:00
|
|
|
#[derive(Serialize)]
|
2018-12-13 01:08:02 -08:00
|
|
|
pub struct MsnFlags: u16
|
|
|
|
{
|
|
|
|
const Extermination = 0x00_01;
|
|
|
|
const Exploration = 0x00_02;
|
|
|
|
const Retrieval = 0x00_04;
|
|
|
|
const Repair = 0x00_08;
|
|
|
|
const Rescue = 0x00_10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for Point
|
|
|
|
{
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
|
2019-02-08 21:53:27 -08:00
|
|
|
{
|
|
|
|
write!(f, "({}, {})", self.x, self.y)
|
|
|
|
}
|
2018-12-13 01:08:02 -08:00
|
|
|
}
|
|
|
|
|
2018-12-11 19:59:15 -08:00
|
|
|
// EOF
|