add ObjID and bad_flag
parent
6d99752e6e
commit
06524be57b
|
@ -1,6 +1,8 @@
|
|||
//! Binary data conversion utilities.
|
||||
|
||||
use crate::durandal::err::*;
|
||||
use std::{fmt,
|
||||
num::NonZeroU16};
|
||||
|
||||
pub type Ident = [u8; 4];
|
||||
|
||||
|
@ -121,4 +123,45 @@ pub fn d_i16b(n: i16) -> [u8; 2]
|
|||
d_u16b(n as u16)
|
||||
}
|
||||
|
||||
pub struct ObjID(Option<NonZeroU16>);
|
||||
|
||||
impl fmt::Debug for ObjID
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
|
||||
{
|
||||
match self.0 {
|
||||
None => write!(f, "ObjID(None)"),
|
||||
Some(n) => write!(f, "ObjID({})", n.get()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjID
|
||||
{
|
||||
pub fn from_repr(n: u16) -> ObjID
|
||||
{
|
||||
if n == u16::max_value() {
|
||||
ObjID(None)
|
||||
} else {
|
||||
ObjID(NonZeroU16::new(n + 1))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_repr(&self) -> u16
|
||||
{
|
||||
match self.0 {
|
||||
None => u16::max_value(),
|
||||
Some(n) => n.get() - 1,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> Option<u16>
|
||||
{
|
||||
match self.0 {
|
||||
None => None,
|
||||
Some(n) => Some(n.get()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -28,4 +28,9 @@ impl<T> fmt::Debug for ReprError<T> where T: PrimInt
|
|||
|
||||
pub type ResultS<T> = Result<T, Error>;
|
||||
|
||||
pub fn bad_flag() -> Error
|
||||
{
|
||||
err_msg("bad flag")
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -6,7 +6,7 @@ impl Chunked<Point> for Point
|
|||
{
|
||||
const SIZE_CHUNK: usize = 4;
|
||||
|
||||
fn read(b: &[u8]) -> ResultS<Point>
|
||||
fn read(b: &[u8]) -> ResultS<Self>
|
||||
{
|
||||
let x = b.c_i16b(0)?;
|
||||
let y = b.c_i16b(2)?;
|
||||
|
@ -18,14 +18,14 @@ impl Chunked<Endpoint> for Endpoint
|
|||
{
|
||||
const SIZE_CHUNK: usize = 16;
|
||||
|
||||
fn read(b: &[u8]) -> ResultS<Endpoint>
|
||||
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(&b[6..10])?;
|
||||
let support = b.c_u16b(14)?;
|
||||
let flags = EndpointFlags::from_bits_truncate(flags);
|
||||
let flags = EndpointFlags::from_bits(flags).ok_or_else(bad_flag)?;
|
||||
Ok(Endpoint{flags, adj_hi, adj_lo, pos, support})
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ impl Chunked<Line> for Line
|
|||
{
|
||||
const SIZE_CHUNK: usize = 32;
|
||||
|
||||
fn read(b: &[u8]) -> ResultS<Line>
|
||||
fn read(b: &[u8]) -> ResultS<Self>
|
||||
{
|
||||
let epnt_f = b.c_u16b(0)?;
|
||||
let epnt_b = b.c_u16b(2)?;
|
||||
|
@ -46,31 +46,34 @@ impl Chunked<Line> for Line
|
|||
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);
|
||||
let flags = LineFlags::from_bits(flags).ok_or_else(bad_flag)?;
|
||||
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>
|
||||
impl SideTex
|
||||
{
|
||||
let offs = Point::read(&b[0..4])?;
|
||||
let tex_id = b.c_u16b(4)?;
|
||||
let tex_id = if tex_id == 65535 {None} else {Some(tex_id)};
|
||||
Ok(SideTex{offs, tex_id})
|
||||
fn read(b: &[u8]) -> ResultS<Self>
|
||||
{
|
||||
let offs = Point::read(&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<Side>
|
||||
fn read(b: &[u8]) -> ResultS<Self>
|
||||
{
|
||||
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 tex_pri = SideTex::read(&b[4..10])?;
|
||||
let tex_sec = SideTex::read(&b[10..16])?;
|
||||
let tex_tra = SideTex::read(&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])?;
|
||||
|
@ -81,7 +84,7 @@ impl Chunked<Side> for Side
|
|||
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 flags = SideFlags::from_bits(flags).ok_or_else(bad_flag)?;
|
||||
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,
|
||||
|
@ -91,7 +94,7 @@ impl Chunked<Side> for Side
|
|||
|
||||
impl Chunker<Minf> for Minf
|
||||
{
|
||||
fn chunk(b: &[u8]) -> ResultS<Minf>
|
||||
fn chunk(b: &[u8]) -> ResultS<Self>
|
||||
{
|
||||
let env_code = b.c_u16b(0)?;
|
||||
let physi_id = b.c_u16b(2)?;
|
||||
|
@ -100,9 +103,9 @@ impl Chunker<Minf> for 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);
|
||||
let msn_flag = MsnFlags::from_bits(msn_flag).ok_or_else(bad_flag)?;
|
||||
let env_flag = EnvFlags::from_bits(env_flag).ok_or_else(bad_flag)?;
|
||||
let ent_flag = EntFlags::from_bits(ent_flag).ok_or_else(bad_flag)?;
|
||||
Ok(Minf{env_code, physi_id, music_id, msn_flag, env_flag, ent_flag,
|
||||
levelnam})
|
||||
}
|
||||
|
@ -145,7 +148,7 @@ pub struct Line
|
|||
pub struct SideTex
|
||||
{
|
||||
offs: Point,
|
||||
tex_id: Option<u16>,
|
||||
tex_id: ObjID,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
Loading…
Reference in New Issue