rename Chunked to ArrayRead and remove Chunker

png-branch
an 2019-02-17 21:17:02 -05:00
parent b135077b8f
commit a8f04cc01c
7 changed files with 112 additions and 142 deletions

View File

@ -100,13 +100,25 @@ pub fn o_i16b(b: &[u8], i: usize) -> Option<i16>
}
}
/// Returns a big-endian `i16` from `b` at `i`.
pub fn o_i16b(b: &[u8], i: usize) -> Option<i16>
/// Reads an array of any type with the `ArrayRead` trait.
pub fn c_array<T: ArrayRead>(b: &[u8]) -> ResultS<Vec<T>>
{
match o_u16b(b, i) {
Some(n) => Some(n as i16),
None => None,
let mut v = Vec::with_capacity(b.len() / T::SIZE);
let mut p = 0;
while p < b.len() {
v.push(T::read(&b[p..])?);
p += T::SIZE;
}
Ok(v)
}
/// Trait for any structure which can be deserialized from an array of bytes.
pub trait ArrayRead: Sized
{
const SIZE: usize;
fn read(b: &[u8]) -> ResultS<Self>;
}
impl ObjID

View File

@ -1,32 +0,0 @@
//! Traits for data which can be read as a sized array.
use crate::durandal::err::*;
pub trait Chunked<T>
{
const SIZE_CHUNK: usize;
fn read(b: &[u8]) -> ResultS<T>;
}
pub trait Chunker<T>
{
fn chunk(b: &[u8]) -> ResultS<T>;
}
impl<T: Chunked<T>> Chunker<Vec<T>> for T
{
fn chunk(b: &[u8]) -> ResultS<Vec<T>>
{
let mut v = Vec::with_capacity(b.len() / T::SIZE_CHUNK);
let mut p = 0;
while p < b.len() {
v.push(T::read(&b[p..])?);
p += T::SIZE_CHUNK;
}
Ok(v)
}
}
// EOF

View File

@ -99,9 +99,9 @@ pub trait Color
impl Image16
{
/// Creates a new Image16.
pub fn new(w: usize, h: usize) -> Image16
pub fn new(w: usize, h: usize) -> Self
{
Image16{w, h, cr: Vec::with_capacity(w * h)}
Self{w, h, cr: Vec::with_capacity(w * h)}
}
}
@ -121,9 +121,9 @@ impl Image for Image16
impl Image8
{
/// Creates a new Image8.
pub fn new(w: usize, h: usize) -> Image8
pub fn new(w: usize, h: usize) -> Self
{
Image8{w, h, cr: Vec::with_capacity(w * h)}
Self{w, h, cr: Vec::with_capacity(w * h)}
}
}

View File

@ -6,7 +6,6 @@ pub mod cenum;
pub mod err;
pub mod bin;
pub mod chunk;
pub mod crc;
pub mod file;
pub mod fixed;

View File

@ -1,13 +1,37 @@
use crate::{durandal::{bin::*, chunk::*, err::*, fixed::*,
use crate::{durandal::{bin::*, err::*, fixed::*,
text::mac_roman_conv},
marathon::xfer::TransferMode};
use bitflags::bitflags;
use serde::Serialize;
use std::fmt;
impl Chunked<Point> for Point
fn read_sidetex(b: &[u8]) -> ResultS<SideTex>
{
const SIZE_CHUNK: usize = 4;
let offs = Point::read(c_data(b, 0..4)?)?;
let tex_id = c_u16b(b, 4)?;
let tex_id = ObjID::from_repr(tex_id);
Ok(SideTex{offs, tex_id})
}
pub fn read_minf(b: &[u8]) -> ResultS<Minf>
{
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)?;
let levelnam = mac_roman_conv(c_data(b, 18..84)?);
let ent_flag = c_u32b(b, 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})
}
impl ArrayRead for Point
{
const SIZE: usize = 4;
fn read(b: &[u8]) -> ResultS<Self>
{
@ -19,9 +43,9 @@ impl Chunked<Point> for Point
}
}
impl Chunked<Endpoint> for Endpoint
impl ArrayRead for Endpoint
{
const SIZE_CHUNK: usize = 16;
const SIZE: usize = 16;
fn read(b: &[u8]) -> ResultS<Self>
{
@ -37,9 +61,9 @@ impl Chunked<Endpoint> for Endpoint
}
}
impl Chunked<Line> for Line
impl ArrayRead for Line
{
const SIZE_CHUNK: usize = 32;
const SIZE: usize = 32;
fn read(b: &[u8]) -> ResultS<Self>
{
@ -62,28 +86,17 @@ impl Chunked<Line> for Line
}
}
impl SideTex
impl ArrayRead for Side
{
fn read(b: &[u8]) -> ResultS<Self>
{
let offs = Point::read(c_data(b, 0..4)?)?;
let tex_id = c_u16b(b, 4)?;
let tex_id = ObjID::from_repr(tex_id);
Ok(SideTex{offs, tex_id})
}
}
impl Chunked<Side> for Side
{
const SIZE_CHUNK: usize = 64;
const SIZE: usize = 64;
fn read(b: &[u8]) -> ResultS<Self>
{
let stype = c_u16b(b, 0)?;
let flags = c_u16b(b, 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 tex_pri = read_sidetex(c_data(b, 4..10)?)?;
let tex_sec = read_sidetex(c_data(b, 10..16)?)?;
let tex_tra = read_sidetex(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)?)?;
@ -105,25 +118,6 @@ impl Chunked<Side> for Side
}
}
impl Chunker<Minf> for Minf
{
fn chunk(b: &[u8]) -> ResultS<Self>
{
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)?;
let levelnam = mac_roman_conv(c_data(b, 18..84)?);
let ent_flag = c_u32b(b, 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})
}
}
#[derive(Serialize)]
pub struct Point
{
@ -199,9 +193,9 @@ bitflags! {
#[derive(Serialize)]
pub struct EndpFlags: u16
{
const Solid = 0x00_01;
const SameHeight = 0x00_02;
const Transparent = 0x00_04;
const Solid = 1;
const SameHeight = 1 << 1;
const Transparent = 1 << 2;
}
}
@ -209,12 +203,12 @@ bitflags! {
#[derive(Serialize)]
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;
const TransSide = 1 << 9;
const ElevVar = 1 << 10;
const Elevation = 1 << 11;
const Landscape = 1 << 12;
const Transparent = 1 << 13;
const Solid = 1 << 14;
}
}
@ -222,14 +216,14 @@ bitflags! {
#[derive(Serialize)]
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;
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;
}
}
@ -237,19 +231,19 @@ bitflags! {
#[derive(Serialize)]
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;
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;
}
}
@ -257,14 +251,14 @@ bitflags! {
#[derive(Serialize)]
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;
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;
}
}
@ -272,11 +266,11 @@ bitflags! {
#[derive(Serialize)]
pub struct MsnFlags: u16
{
const Extermination = 0x00_01;
const Exploration = 0x00_02;
const Retrieval = 0x00_04;
const Repair = 0x00_08;
const Rescue = 0x00_10;
const Extermination = 1;
const Exploration = 1 << 1;
const Retrieval = 1 << 2;
const Repair = 1 << 3;
const Rescue = 1 << 4;
}
}

View File

@ -392,8 +392,8 @@ pub type CollectionDef = (Option<Collection>, Option<Collection>);
bitflags! {
struct BmpFlags: u16
{
const ColumnMajor = 0x80_00;
const Transparent = 0x40_00;
const ColumnMajor = 0x80_00;
}
}

View File

@ -1,4 +1,4 @@
use crate::durandal::{bin::*, chunk::*, err::*, text::*};
use crate::durandal::{bin::*, err::*, text::*};
use bitflags::bitflags;
use serde::Serialize;
use std::fmt;
@ -42,7 +42,7 @@ fn read_terminal(b: &[u8]) -> ResultS<(usize, Terminal)>
let mut groups = Vec::with_capacity(group_n);
let mut faces = Vec::with_capacity(face_n);
let mut p = 10; // size of header
let mut p = 10;
let text_st = p + SIZE_GROUP * group_n + SIZE_FACE * face_n;
let text = c_data(b, text_st..end)?;
@ -65,21 +65,18 @@ fn read_terminal(b: &[u8]) -> ResultS<(usize, Terminal)>
Ok((end, Terminal{lines, groups, faces}))
}
impl Chunker<Vec<Terminal>> for Terminal
pub fn read_term(b: &[u8]) -> ResultS<Vec<Terminal>>
{
fn chunk(b: &[u8]) -> ResultS<Vec<Terminal>>
{
let mut v = Vec::new();
let mut p = 0;
let mut v = Vec::new();
let mut p = 0;
while p < b.len() {
let (size, trm) = read_terminal(c_data(b, p..)?)?;
v.push(trm);
p += size;
}
Ok(v)
while p < b.len() {
let (size, trm) = read_terminal(c_data(b, p..)?)?;
v.push(trm);
p += size;
}
Ok(v)
}
#[derive(Debug, Serialize)]