Maraiah/src/marathon/map.rs

274 lines
6.2 KiB
Rust

use crate::durandal::{bin::*, chunk::*, err::*, fx32::*, text::mac_roman_conv};
use bitflags::bitflags;
use std::fmt;
impl Chunked<Point> for Point
{
const SIZE_CHUNK: usize = 4;
fn read(b: &[u8]) -> ResultS<Self>
{
let x = b.c_i16b(0)?;
let y = b.c_i16b(2)?;
Ok(Point{x, y})
}
}
impl Chunked<Endpoint> for Endpoint
{
const SIZE_CHUNK: usize = 16;
fn read(b: &[u8]) -> ResultS<Self>
{
let flags = b.c_u16b(0)?;
let adj_hi = b.c_i16b(2)?;
let adj_lo = b.c_i16b(4)?;
let pos = Point::read(c_data(b, 6..10)?)?;
let support = b.c_u16b(14)?;
let flags = ok!(EndpFlags::from_bits(flags), "bad EndpFlags")?;
Ok(Endpoint{flags, adj_hi, adj_lo, pos, support})
}
}
impl Chunked<Line> for Line
{
const SIZE_CHUNK: usize = 32;
fn read(b: &[u8]) -> ResultS<Self>
{
let epnt_f = b.c_u16b(0)?;
let epnt_b = b.c_u16b(2)?;
let flags = b.c_u16b(4)?;
let length = b.c_i16b(6)?;
let adj_hi = b.c_i16b(8)?;
let adj_lo = b.c_i16b(10)?;
let side_f = b.c_u16b(12)?;
let side_b = b.c_u16b(14)?;
let poly_f = b.c_u16b(16)?;
let poly_b = b.c_u16b(18)?;
let flags = ok!(LineFlags::from_bits(flags), "bad LineFlags")?;
Ok(Line{flags, length, adj_hi, adj_lo, epnt_f, epnt_b, side_f, side_b,
poly_f, poly_b})
}
}
impl SideTex
{
fn read(b: &[u8]) -> ResultS<Self>
{
let offs = Point::read(c_data(b, 0..4)?)?;
let tex_id = b.c_u16b(4)?;
let tex_id = ObjID::from_repr(tex_id);
Ok(SideTex{offs, tex_id})
}
}
impl Chunked<Side> for Side
{
const SIZE_CHUNK: usize = 64;
fn read(b: &[u8]) -> ResultS<Self>
{
let stype = b.c_u16b(0)?;
let flags = b.c_u16b(2)?;
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)?)?;
let paneltyp = b.c_u16b(38)?;
let paneldat = b.c_i16b(40)?;
let xfer_pri = b.c_u16b(42)?;
let xfer_sec = b.c_u16b(44)?;
let xfer_tra = b.c_u16b(46)?;
let shade = b.c_u32b(48)?;
let flags = ok!(SideFlags::from_bits(flags), "bad SideFlags")?;
let shade = Fx32::from_bits(shade);
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})
}
}
impl Chunker<Minf> for Minf
{
fn chunk(b: &[u8]) -> ResultS<Self>
{
let env_code = b.c_u16b(0)?;
let physi_id = b.c_u16b(2)?;
let music_id = b.c_u16b(4)?;
let msn_flag = b.c_u16b(6)?;
let env_flag = b.c_u16b(8)?;
let levelnam = mac_roman_conv(c_data(b, 18..84)?);
let ent_flag = b.c_u32b(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})
}
}
type Unit = i16;
pub struct Point
{
x: Unit,
y: Unit,
}
#[derive(Debug)]
pub struct Endpoint
{
flags: EndpFlags,
adj_hi: Unit,
adj_lo: Unit,
pos: Point,
support: u16,
}
#[derive(Debug)]
pub struct Line
{
flags: LineFlags,
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,
}
#[derive(Debug)]
pub struct SideTex
{
offs: Point,
tex_id: ObjID,
}
#[derive(Debug)]
pub struct Side
{
stype: u16,
flags: SideFlags,
tex_pri: SideTex,
tex_sec: SideTex,
tex_tra: SideTex,
ex_tleft: Point,
ex_trigh: Point,
ex_bleft: Point,
ex_brigh: Point,
paneltyp: u16,
paneldat: i16,
xfer_pri: u16,
xfer_sec: u16,
xfer_tra: u16,
shade: Fx32,
}
#[derive(Debug)]
pub struct Minf
{
env_code: u16,
physi_id: u16,
music_id: u16,
msn_flag: MsnFlags,
env_flag: EnvFlags,
ent_flag: EntFlags,
levelnam: String,
}
bitflags! {
pub struct EndpFlags: u16
{
const Solid = 0x00_01;
const SameHeight = 0x00_02;
const Transparent = 0x00_04;
}
}
bitflags! {
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! {
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! {
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! {
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! {
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
{
write!(f, "({}, {})", self.x, self.y)
}
}
// EOF