add new loaders for map data
parent
e62f14752b
commit
252d6b8edd
23
src/main.rs
23
src/main.rs
|
@ -1,7 +1,8 @@
|
|||
#[macro_use]
|
||||
pub mod durandal;
|
||||
pub mod marathon;
|
||||
|
||||
use crate::durandal::{err::*, image::Image, pict::load_pict};
|
||||
use crate::durandal::{chunk::*, err::*, image::Image, pict::load_pict};
|
||||
use crate::marathon::{map, wad, term};
|
||||
use memmap::Mmap;
|
||||
use std::{io, io::Write, fs, env};
|
||||
|
@ -44,6 +45,26 @@ fn main() -> ResultS<()>
|
|||
println!("entry {} has {:#?}", id, minf);
|
||||
}
|
||||
|
||||
if let Some(b) = ent.chunks.get(b"EPNT") {
|
||||
let epnt = map::Endpoint::chunk(b)?;
|
||||
println!("entry {} has EPNT {:#?}", id, epnt);
|
||||
}
|
||||
|
||||
if let Some(b) = ent.chunks.get(b"PNTS") {
|
||||
let epnt = map::Point::chunk(b)?;
|
||||
println!("entry {} has PNTS {:#?}", id, epnt);
|
||||
}
|
||||
|
||||
if let Some(b) = ent.chunks.get(b"LINS") {
|
||||
let line = map::Line::chunk(b)?;
|
||||
println!("entry {} has LINS {:#?}", id, line);
|
||||
}
|
||||
|
||||
if let Some(b) = ent.chunks.get(b"SIDS") {
|
||||
let line = map::Side::chunk(b)?;
|
||||
println!("entry {} has SIDS {:#?}", id, line);
|
||||
}
|
||||
|
||||
if let Some(b) = ent.chunks.get(b"term") {
|
||||
let term = term::Terminal::chunk(b)?;
|
||||
println!("entry {} has term {:#?}", id, term);
|
||||
|
|
|
@ -1,11 +1,103 @@
|
|||
use crate::durandal::{bin::*, err::*, text::mac_roman_conv};
|
||||
use bitflags::bitflags;
|
||||
use crate::durandal::{bin::*, chunk::*, err::*, fx32::*, text::mac_roman_conv};
|
||||
use std::fmt;
|
||||
|
||||
impl Minf
|
||||
impl Chunked<Point> for Point
|
||||
{
|
||||
pub fn chunk(b: &[u8]) -> ResultS<Minf>
|
||||
{
|
||||
if b.len() < 88 {return err_msg("not enough data for Minf")}
|
||||
const SIZE_CHUNK: usize = 4;
|
||||
|
||||
fn read(b: &[u8]) -> ResultS<Point>
|
||||
{
|
||||
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<Endpoint>
|
||||
{
|
||||
let flags = b.c_u16b(0)?;
|
||||
let adj_hi = b.c_i16b(2)?;
|
||||
let adj_lo = b.c_i16b(4)?;
|
||||
let pos = Point::read(&b[ 6..10])?;
|
||||
// xform = Point::read(&b[10..14])?;
|
||||
let support = b.c_u16b(14)?;
|
||||
let flags = EndpointFlags::from_bits_truncate(flags);
|
||||
Ok(Endpoint{flags, adj_hi, adj_lo, pos, support})
|
||||
}
|
||||
}
|
||||
|
||||
impl Chunked<Line> for Line
|
||||
{
|
||||
const SIZE_CHUNK: usize = 32;
|
||||
|
||||
fn read(b: &[u8]) -> ResultS<Line>
|
||||
{
|
||||
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 = LineFlags::from_bits_truncate(flags);
|
||||
Ok(Line{flags, length, adj_hi, adj_lo, epnt_f, epnt_b, side_f, side_b, poly_f, poly_b})
|
||||
}
|
||||
}
|
||||
|
||||
fn read_side_tex(b: &[u8]) -> ResultS<SideTex>
|
||||
{
|
||||
let offs = Point::read(&b[0..4])?;
|
||||
let tex_id = b.c_u16b(4)?;
|
||||
Ok(SideTex{offs, tex_id})
|
||||
}
|
||||
|
||||
impl Chunked<Side> for Side
|
||||
{
|
||||
const SIZE_CHUNK: usize = 64;
|
||||
|
||||
fn read(b: &[u8]) -> ResultS<Side>
|
||||
{
|
||||
let stype = b.c_u16b(0)?;
|
||||
let flags = b.c_u16b(2)?;
|
||||
let tex_pri = read_side_tex(&b[ 4..10])?;
|
||||
let tex_sec = read_side_tex(&b[10..16])?;
|
||||
let tex_tra = read_side_tex(&b[16..22])?;
|
||||
let ex_tleft = Point::read(&b[22..26])?;
|
||||
let ex_trigh = Point::read(&b[26..30])?;
|
||||
let ex_bleft = Point::read(&b[30..34])?;
|
||||
let ex_brigh = Point::read(&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 = SideFlags::from_bits_truncate(flags);
|
||||
let paneltyp =
|
||||
if flags.contains(SideFlags::Panel) {
|
||||
Some(PanelType::from_repr(paneltyp)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
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<Minf>
|
||||
{
|
||||
let env_code = b.c_u16b( 0)?;
|
||||
let physi_id = b.c_u16b( 2)?;
|
||||
let music_id = b.c_u16b( 4)?;
|
||||
|
@ -13,21 +105,186 @@ impl Minf
|
|||
let env_flag = b.c_u16b( 8)?;
|
||||
let levelnam = mac_roman_conv(&b[18..84]);
|
||||
let ent_flag = b.c_u32b(84)?;
|
||||
|
||||
let msn_flag = MsnFlags::from_bits_truncate(msn_flag);
|
||||
let env_flag = EnvFlags::from_bits_truncate(env_flag);
|
||||
let ent_flag = EntFlags::from_bits_truncate(ent_flag);
|
||||
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: EndpointFlags,
|
||||
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: u16,
|
||||
}
|
||||
|
||||
#[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: Option<PanelType>,
|
||||
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: u16,
|
||||
env_flag: u16,
|
||||
ent_flag: u32,
|
||||
msn_flag: MsnFlags,
|
||||
env_flag: EnvFlags,
|
||||
ent_flag: EntFlags,
|
||||
levelnam: String,
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct EndpointFlags: 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;
|
||||
}
|
||||
}
|
||||
|
||||
c_enum! {
|
||||
#[derive(Debug)]
|
||||
pub enum PanelType: u16
|
||||
{
|
||||
0 => Oxygen,
|
||||
1 => Shield,
|
||||
2 => Shield2x,
|
||||
3 => Shield3x,
|
||||
4 => Light,
|
||||
5 => Platform,
|
||||
6 => Tag,
|
||||
7 => PatternBuf,
|
||||
8 => Terminal,
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Point
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
|
||||
{
|
||||
write!(f, "({}, {})", self.x, self.y)
|
||||
}
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
Loading…
Reference in New Issue