From fc27d2d0f4a9a09f6a5d3236e79303789de0907f Mon Sep 17 00:00:00 2001 From: Marrub Date: Fri, 1 Mar 2019 04:27:14 -0500 Subject: [PATCH] add documentation for everything --- src/durandal/bin.rs | 147 ++++++++++++++++++++++++++++++++---------- src/durandal/cenum.rs | 15 +++-- src/durandal/crc.rs | 1 + src/durandal/err.rs | 3 + src/durandal/file.rs | 1 + src/durandal/fixed.rs | 75 ++++++++++++++++++--- src/durandal/image.rs | 34 ++++++++-- src/durandal/mod.rs | 2 +- src/durandal/sound.rs | 24 +++++-- src/marathon/map.rs | 46 +++++++++++++ src/marathon/mod.rs | 2 +- src/marathon/phy.rs | 27 ++++++++ src/marathon/shp.rs | 54 +++++++++++----- src/marathon/snd.rs | 24 ++++--- src/marathon/trm.rs | 14 +++- src/marathon/xfer.rs | 3 + 16 files changed, 385 insertions(+), 87 deletions(-) diff --git a/src/durandal/bin.rs b/src/durandal/bin.rs index 6ca254f..cccb55f 100644 --- a/src/durandal/bin.rs +++ b/src/durandal/bin.rs @@ -5,67 +5,70 @@ use serde::Serialize; use std::{fmt, num::NonZeroU16}; #[doc(hidden)] -macro_rules! rd_1 { +#[macro_export] +macro_rules! _durandal_read_impl { // big endian (BE $b:ident $nam:ident u16 $n:expr) => { - rd_1!($b u16::from_be_bytes, $nam 2 $n); + _durandal_read_impl!($b u16::from_be_bytes, $nam 2 $n); }; (BE $b:ident $nam:ident i16 $n:expr) => { - rd_1!($b i16::from_be_bytes, $nam 2 $n); + _durandal_read_impl!($b i16::from_be_bytes, $nam 2 $n); }; (BE $b:ident $nam:ident u32 $n:expr) => { - rd_1!($b u32::from_be_bytes, $nam 4 $n); + _durandal_read_impl!($b u32::from_be_bytes, $nam 4 $n); }; (BE $b:ident $nam:ident i32 $n:expr) => { - rd_1!($b i32::from_be_bytes, $nam 4 $n); + _durandal_read_impl!($b i32::from_be_bytes, $nam 4 $n); }; (BE $b:ident $nam:ident as usize u16 $n:expr) => { - rd_1!($b u16::from_be_bytes, $nam 2 $n); + _durandal_read_impl!($b u16::from_be_bytes, $nam 2 $n); let $nam = $nam as usize; }; (BE $b:ident $nam:ident as usize u32 $n:expr) => { - rd_1!($b u32::from_be_bytes, $nam 4 $n); + _durandal_read_impl!($b u32::from_be_bytes, $nam 4 $n); let $nam = $nam as usize; }; - (BE $b:ident $nam:ident Angle $n:expr) => { - rd_1!($b u16::from_be_bytes, $nam 2 $n); - let $nam = Angle::from_bits($nam); - }; - (BE $b:ident $nam:ident Fixed $n:expr) => { - rd_1!($b u32::from_be_bytes, $nam 4 $n); - let $nam = Fixed::from_bits($nam); - }; - (BE $b:ident $nam:ident Unit $n:expr) => { - rd_1!($b u16::from_be_bytes, $nam 2 $n); - let $nam = Unit::from_bits($nam); - }; - (BE $b:ident $nam:ident OptU16 $n:expr) => { - rd_1!($b u16::from_be_bytes, $nam 2 $n); - let $nam = OptU16::from_repr($nam); - }; // little endian (LE $b:ident $nam:ident u16 $n:expr) => { - rd_1!($b u16::from_le_bytes $nam 2 $n); + _durandal_read_impl!($b u16::from_le_bytes $nam 2 $n); }; (LE $b:ident $nam:ident i16 $n:expr) => { - rd_1!($b i16::from_le_bytes $nam 2 $n); + _durandal_read_impl!($b i16::from_le_bytes $nam 2 $n); }; (LE $b:ident $nam:ident u32 $n:expr) => { - rd_1!($b u32::from_le_bytes $nam 4 $n); + _durandal_read_impl!($b u32::from_le_bytes $nam 4 $n); }; (LE $b:ident $nam:ident i32 $n:expr) => { - rd_1!($b i32::from_le_bytes $nam 4 $n); + _durandal_read_impl!($b i32::from_le_bytes $nam 4 $n); }; (LE $b:ident $nam:ident as usize u16 $n:expr) => { - rd_1!($b u16::from_le_bytes $nam 2 $n); + _durandal_read_impl!($b u16::from_le_bytes $nam 2 $n); let $nam = $nam as usize; }; (LE $b:ident $nam:ident as usize u32 $n:expr) => { - rd_1!($b u32::from_le_bytes $nam 4 $n); + _durandal_read_impl!($b u32::from_le_bytes $nam 4 $n); let $nam = $nam as usize; }; + // either endianness + ($e:ident $b:ident $nam:ident Angle $n:expr) => { + _durandal_read_impl!($e $b $nam u16 $n); + let $nam = Angle::from_bits($nam); + }; + ($e:ident $b:ident $nam:ident Fixed $n:expr) => { + _durandal_read_impl!($e $b $nam u32 $n); + let $nam = Fixed::from_bits($nam); + }; + ($e:ident $b:ident $nam:ident Unit $n:expr) => { + _durandal_read_impl!($e $b $nam u16 $n); + let $nam = Unit::from_bits($nam); + }; + ($e:ident $b:ident $nam:ident OptU16 $n:expr) => { + _durandal_read_impl!($e $b $nam u16 $n); + let $nam = OptU16::from_repr($nam); + }; + // generic endianness ($_:ident $b:ident $nam:ident u8 $n:expr) => { let $nam = $b[$n]; @@ -76,7 +79,7 @@ macro_rules! rd_1 { ($_:ident $b:ident $nam:ident i8 $n:expr) => { let $nam = $b[$n] as i8; }; - ($_:ident $b:ident $nam:ident iden $n:expr) => { + ($_:ident $b:ident $nam:ident Ident $n:expr) => { let $nam = [$b[$n], $b[$n + 1], $b[$n + 2], $b[$n + 3]]; }; ($_:ident $b:ident $nam:ident $f:ident $n:expr) => { @@ -95,6 +98,48 @@ macro_rules! rd_1 { }; } +/// Reads structured data from a byte array. +/// +/// First start by specifying the endianness, size and source using the syntax +/// `endian, size in source =>` where: +/// +/// - `endian` is `BE` or `LE` for big- or little-endian respectively. +/// - `size` is an expression specifying the last index that should be used by +/// this macro in `source`. +/// - `source` is a `u8` slice to read data from. +/// +/// After the initializer line, all lines have the syntax +/// `name = type[place] opts;` where: +/// +/// - `name` is the binding to put the resulting data in. +/// - `type` is one of: +/// - `u8` or `i8`: one byte will be read at `place`. +/// - `u16` or `i16`: two bytes will be read at `place` with `from_*_bytes`. +/// - `u32` or `i32`: four bytes will be read at `place` with `from_*_bytes`. +/// - `Ident`: four bytes will be read at `place` into an array, disregarding +/// endianness, creating an `Ident` object. +/// - `Angle`: same as `u16`, but the result is passed to +/// `fixed::Angle::from_bits`, resulting in a `fixed::Angle` object. +/// - `Fixed`: same as `u32`, but the result is passed to +/// `fixed::Fixed::from_bits`, resulting in a `fixed::Fixed` object. +/// - `Unit`: same as `u16`, but the result is passed to +/// `fixed::Unit::from_bits`, resulting in a `fixed::Unit` object. +/// - `OptU16`: same as `u16`, but the result is passed to +/// `OptU16::from_repr`, resulting in an `OptU16` object. +/// - The name of a function, which is passed `&source[place]` as its only +/// argument. The function's result has the `?` operator applied to it. +/// - `opts` may be one of: +/// - `array` when `type` is `u8`: `place` is a range specifying a `u8` slice +/// to be taken from `source`. +/// - `as usize` when `type` is `u16` or `u32`: converts the resulting +/// integer to `usize` by primitive cast. +/// - `nt` when `type` is a function name: does not use the `?` operator on +/// the resulting function call +/// - Nothing at all. +/// - `place` is either an integer literal which must be representable as +/// `usize`, or a range, which may only be used when `type` is a function +/// name. +#[macro_export] macro_rules! read_data { ( $sz:expr , $ty:ident in $b:ident => @@ -104,16 +149,41 @@ macro_rules! read_data { bail!("not enough data"); } - $(rd_1!($ty $b $nam $($ex)* $t $n);)* + $($crate::_durandal_read_impl!($ty $b $nam $($ex)* $t $n);)* }; } +/// Creates an `Ident` from a slice. +/// +/// `b` must be at least 4 bytes, or a panic will occur. pub fn ident(b: &[u8]) -> Ident {[b[0], b[1], b[2], b[3]]} + +/// Applies `u32::from_be_bytes` to a slice. +/// +/// `b` must be at least 4 bytes, or a panic will occur. pub fn u32b(b: &[u8]) -> u32 {u32::from_be_bytes([b[0], b[1], b[2], b[3]])} + +/// Applies `u16::from_be_bytes` to a slice. +/// +/// `b` must be at least 2 bytes, or a panic will occur. pub fn u16b(b: &[u8]) -> u16 {u16::from_be_bytes([b[0], b[1]])} + +/// Applies `i32::from_be_bytes` to a slice. +/// +/// `b` must be at least 4 bytes, or a panic will occur. pub fn i32b(b: &[u8]) -> i32 {i32::from_be_bytes([b[0], b[1], b[2], b[3]])} + +/// Applies `i16::from_be_bytes` to a slice. +/// +/// `b` must be at least 2 bytes, or a panic will occur. pub fn i16b(b: &[u8]) -> i16 {i16::from_be_bytes([b[0], b[1]])} +/// Applies a read function over a slice. +/// +/// Applies `read` over `b`, resulting in a vector of its return values. Each +/// iteration will pass a slice of `b` to `read` for it to read from, and then +/// increments the slice index by the second return value. When there is no +/// data left in `b`, the function returns. pub fn rd_array(b: &[u8], read: F) -> ResultS> where T: Sized, F: Fn(&[u8]) -> ResultS<(T, usize)> @@ -130,6 +200,13 @@ pub fn rd_array(b: &[u8], read: F) -> ResultS> Ok(v) } +/// Applies a read function over a slice with an offset table. +/// +/// Applies `read` over each offset in `b`, of which there are `num` amount of +/// starting at `p`, resulting in a vector of its return values. Each iteration +/// reads a 32-bit big endian offset from `b`, and then passes a slice of `b` +/// to `read` starting at that offset. When all offsets have been read, the +/// function returns. pub fn rd_ofstable(b: &[u8], mut p: usize, num: usize, @@ -141,7 +218,7 @@ pub fn rd_ofstable(b: &[u8], let mut v = Vec::with_capacity(num); for _ in 0..num { - let ofs = u32b(&b[p..]) as usize; + let ofs = u32b(&b[p..p + 4]) as usize; if ofs >= b.len() { bail!("not enough data"); @@ -166,7 +243,7 @@ impl OptU16 } } - /// Returns the `u16` representation of an `OptU16`. + /// Returns the `u16` representation. pub fn get_repr(&self) -> u16 { match self.0 { @@ -175,7 +252,7 @@ impl OptU16 } } - /// Returns the `Option` representation of an `OptU16`. + /// Returns the `Option` representation. pub fn get(&self) -> Option { match self.0 { @@ -200,7 +277,7 @@ impl fmt::Debug for OptU16 pub type Ident = [u8; 4]; /// An object identified by a `u16` which may be `u16::max_value()` to -/// represent None. +/// represent a nulled value. #[derive(Serialize)] pub struct OptU16(Option); diff --git a/src/durandal/cenum.rs b/src/durandal/cenum.rs index 9ffc1d2..8904dcf 100644 --- a/src/durandal/cenum.rs +++ b/src/durandal/cenum.rs @@ -1,7 +1,13 @@ -//! C representation enumerations. +#![doc(hidden)] /// Creates an enumeration and function for converting a representation into /// the enumeration type. +/// +/// The syntax is similar to the `bitflags` macro, but each value has the +/// syntax `value => enumeration`. `enum` is used instead of `struct`. +/// +/// This will generate an `enum E` as well as a function `E::from_repr` which +/// will return `Result`. #[macro_export] macro_rules! c_enum { @@ -20,11 +26,12 @@ macro_rules! c_enum impl $E { - $V fn from_repr(n: $T) -> Result<$E, ReprError> + /// Returns, if representable, the variant of `Self` from `n`. + $V fn from_repr(n: $T) -> Result { match n { - $($value => Ok($E::$Enum),)+ - n => Err(ReprError(n.into())) + $($value => Ok($E::$Enum),)+ + n => Err(ReprError(n.into())) } } } diff --git a/src/durandal/crc.rs b/src/durandal/crc.rs index 30c5e4e..bde8c4f 100644 --- a/src/durandal/crc.rs +++ b/src/durandal/crc.rs @@ -18,6 +18,7 @@ fn crc_init() -> [u32; 256] t } +/// Creates a CRC-32 of all bytes in `b` with the starting sum `s`. pub fn crc32(b: &[u8], s: u32) -> u32 { let t = crc_init(); diff --git a/src/durandal/err.rs b/src/durandal/err.rs index 0d0e413..6657b80 100644 --- a/src/durandal/err.rs +++ b/src/durandal/err.rs @@ -28,6 +28,7 @@ macro_rules! bail { }; } +/// Returns an `Error` with a static string. pub fn err_msg(msg: &'static str) -> Error {Error::from(ErrMsg(msg))} impl Fail for ReprError {} @@ -62,11 +63,13 @@ impl fmt::Debug for ErrMsg } } +/// A representation error for an integer. #[derive(PartialEq)] pub struct ReprError(pub i64); struct ErrMsg(&'static str); +/// A generic `failure` based `Result` type. pub type ResultS = Result; // EOF diff --git a/src/durandal/file.rs b/src/durandal/file.rs index 36b30c8..1c3abe3 100644 --- a/src/durandal/file.rs +++ b/src/durandal/file.rs @@ -3,6 +3,7 @@ use crate::durandal::err::*; use std::fs; +/// Confirms that the path `p` is a folder. pub fn validate_folder_path(p: &str) -> ResultS<()> { let at = fs::metadata(p)?; diff --git a/src/durandal/fixed.rs b/src/durandal/fixed.rs index 9e83e4c..cf2de80 100644 --- a/src/durandal/fixed.rs +++ b/src/durandal/fixed.rs @@ -5,23 +5,55 @@ use std::{fmt::{self, Write}, ops}; macro_rules! define_fixed_type { - ($Type:ident : $IT:ident, $UT:ident, $LT:ident, $FracBits:expr) => { + ( + $(#[$outer:meta])* + struct $Type:ident ($IT:ident) : $UT:ident, $LT:ident, $FracBits:expr; + ) => { + $(#[$outer])* #[derive(Clone, PartialEq, Serialize)] pub struct $Type($IT); impl $Type { - const FRACBITS: $UT = $FracBits; - const FRACMASK: $UT = (1 << Self::FRACBITS) - 1; - const ONE: $IT = 1 << Self::FRACBITS; + /// The number of fractional bits in this type. + pub const FRACBITS: $UT = $FracBits; + /// The integer mask for the fractional bits. + pub const FRACMASK: $UT = (1 << Self::FRACBITS) - 1; + /// The representation of `1.0` in this type. + pub const ONE: $IT = 1 << Self::FRACBITS; - pub fn to_bits(&self) -> $UT {self.0 as $UT} - pub fn set_bits(&mut self, bits: $UT) {self.0 = bits as $IT} + /// Creates a value of this type with the bit pattern `bits`. + #[inline] pub const fn from_bits(bits: $UT) -> Self {$Type(bits as $IT)} + + /// Returns the raw bit pattern. + #[inline] + pub fn to_bits(&self) -> $UT {self.0 as $UT} + + /// Sets the raw bit pattern to `bits`. + #[inline] + pub fn set_bits(&mut self, bits: $UT) {self.0 = bits as $IT} + + /// Returns the integral portion. + #[inline] pub fn integ(&self) -> $LT {(self.0 >> Self::FRACBITS) as $LT} + + /// Returns the fractional portion. + /// + /// This is a value of `1` to `FRACMASK`. #[allow(trivial_numeric_casts)] pub fn fract(&self) -> u16 {(self.0 as $UT & Self::FRACMASK) as u16} + + /// Returns a multiplication by integer. + /// + /// Panics if the result overflows. + #[inline] pub fn mul_i(&self, n: $LT) -> Self {$Type(self.0 * $IT::from(n))} + + /// Returns a division by integer. + /// + /// Panics if `n` is `0`. + #[inline] pub fn div_i(&self, n: $LT) -> Self {$Type(self.0 / $IT::from(n))} #[inline] @@ -39,6 +71,7 @@ macro_rules! define_fixed_type { impl From<$LT> for $Type { + #[inline] fn from(n: $LT) -> Self {$Type($IT::from(n) << Self::FRACBITS)} } @@ -46,6 +79,7 @@ macro_rules! define_fixed_type { { type Output = Self; + #[inline] fn add(self, o: Self) -> Self {$Type(self.0 + o.0)} } @@ -53,6 +87,7 @@ macro_rules! define_fixed_type { { type Output = Self; + #[inline] fn sub(self, o: Self) -> Self {$Type(self.0 - o.0)} } @@ -60,6 +95,7 @@ macro_rules! define_fixed_type { { type Output = Self; + #[inline] fn mul(self, o: Self) -> Self {$Type(Self::fx_mul(self.0, o.0))} } @@ -67,6 +103,7 @@ macro_rules! define_fixed_type { { type Output = Self; + #[inline] fn div(self, o: Self) -> Self {$Type(Self::fx_div(self.0, o.0))} } @@ -74,6 +111,7 @@ macro_rules! define_fixed_type { { type Output = Self; + #[inline] fn neg(self) -> Self {$Type(-self.0)} } @@ -81,6 +119,7 @@ macro_rules! define_fixed_type { { type Output = Self; + #[inline] fn not(self) -> Self {$Type(!self.0)} } @@ -115,9 +154,27 @@ macro_rules! define_fixed_type { }; } -define_fixed_type!(Fixed: i32, u32, i16, 16); -define_fixed_type!(Unit: i16, u16, i8, 10); -define_fixed_type!(Angle: i16, u16, i8, 9); +define_fixed_type! { + /// A fixed point type representing an angle. + /// + /// The format of this type is `0.9s`, but because of the implementation, + /// the real format is `7.9s`. + struct Angle(i16) : u16, i8, 9; +} + +define_fixed_type! { + /// A fixed point type representing a world unit. + /// + /// The format of this type is `5.10s`. This has caused eternal suffering. + struct Unit(i16) : u16, i8, 10; +} + +define_fixed_type! { + /// A generic fixed point type. + /// + /// The format of this type is `15.16s`. + struct Fixed(i32) : u32, i16, 16; +} #[test] fn fixed_basic_ops() diff --git a/src/durandal/image.rs b/src/durandal/image.rs index 366d41f..960bef3 100644 --- a/src/durandal/image.rs +++ b/src/durandal/image.rs @@ -1,6 +1,7 @@ //! Image and color representations. use crate::durandal::err::*; +use serde::Serialize; use std::io; /// Creates a RGB8 color from a R5G5B5 format color. @@ -70,14 +71,25 @@ pub fn write_tga(out: &mut impl io::Write, im: &impl Image) -> ResultS<()> Ok(()) } +/// A generic color matrix image. pub trait Image { + /// The type of color this image uses for each pixel. type Output: Color; + /// Returns the width of the image. fn w(&self) -> usize; + + /// Returns the height of the image. fn h(&self) -> usize; + + /// Returns the color of the pixel at column `x` at row `y`. + /// + /// Panics if `x` is greater than the width of the image or `y` is greater + /// than the height of the image. fn index(&self, x: usize, y: usize) -> &Self::Output; + /// The same as `index`, but will not panic if out of bounds. fn get(&self, x: usize, y: usize) -> Option<&Self::Output> { if x < self.w() && y < self.h() { @@ -88,11 +100,19 @@ pub trait Image } } +/// Any color which may be represented as RGBA16. pub trait Color { + /// Returns the red component. fn r(&self) -> u16; + + /// Returns the green component. fn g(&self) -> u16; + + /// Returns the blue component. fn b(&self) -> u16; + + /// Returns the alpha component. fn a(&self) -> u16; } @@ -166,15 +186,16 @@ impl Color for Color8 fn a(&self) -> u16 {u16::max_value()} } -/// A RGB16 color. -#[derive(Clone, Debug, PartialEq)] +/// An RGB16 color. +#[derive(Clone, Debug, PartialEq, Serialize)] pub struct Color16(u16, u16, u16); -/// A RGB8 color. -#[derive(Clone, Debug, PartialEq)] +/// An RGB8 color. +#[derive(Clone, Debug, PartialEq, Serialize)] pub struct Color8(u8, u8, u8); -/// RGB16 image. +/// An RGB16 image. +#[derive(Debug, Serialize)] pub struct Image16 { w: usize, @@ -182,7 +203,8 @@ pub struct Image16 pub cr: Vec, } -/// RGB16 image. +/// An RGB8 image. +#[derive(Debug, Serialize)] pub struct Image8 { w: usize, diff --git a/src/durandal/mod.rs b/src/durandal/mod.rs index 2ede0df..0848bf3 100644 --- a/src/durandal/mod.rs +++ b/src/durandal/mod.rs @@ -1,4 +1,4 @@ -//! Library for various utilities. +//! Library for utilities. #[macro_use] pub mod err; diff --git a/src/durandal/sound.rs b/src/durandal/sound.rs index 3c247bd..9b0b802 100644 --- a/src/durandal/sound.rs +++ b/src/durandal/sound.rs @@ -3,6 +3,7 @@ use crate::durandal::err::*; use std::io; +/// Writes a WAVE file from a sound. pub fn write_wav(out: &mut impl io::Write, snd: &impl Sound) -> ResultS<()> { let rate = u32::from(snd.rate()); @@ -32,20 +33,34 @@ pub fn write_wav(out: &mut impl io::Write, snd: &impl Sound) -> ResultS<()> Ok(()) } +/// Any PCM stream which may be represented as a 16-bit PCM stream. pub trait Sound { + /// Returns the sample rate. fn rate(&self) -> u16; + + /// Returns the number of samples. fn len(&self) -> usize; - fn index(&self, p: usize) -> i16; + + /// Returns the `n`th sample. + /// + /// May panic if `n` exceeds the length of this sound. + fn index(&self, n: usize) -> i16; + + /// Returns the number of the first sample of the loop, or `0`. fn lp_beg(&self) -> usize; + + /// Returns the number of the last sample of the loop, or `0`. fn lp_end(&self) -> usize; + /// Returns `true` if there are no samples in this sound. fn is_empty(&self) -> bool {self.len() == 0} - fn get(&self, p: usize) -> Option + /// The same as `index`, but will not panic if out of bounds. + fn get(&self, n: usize) -> Option { - if p < self.len() { - Some(self.index(p)) + if n < self.len() { + Some(self.index(n)) } else { None } @@ -99,6 +114,7 @@ impl Sound for Sound16 fn lp_end(&self) -> usize {self.lp_end} } +/// A 16-bit PCM stream. pub struct Sound16 { rate: u16, diff --git a/src/marathon/map.rs b/src/marathon/map.rs index f54f666..3fe6e96 100644 --- a/src/marathon/map.rs +++ b/src/marathon/map.rs @@ -1,8 +1,11 @@ +//! Structures used by Marathon's Map format. + use crate::{durandal::{bin::*, err::*, fixed::*, text::mac_roman_conv}, marathon::xfer::TransferMode}; use bitflags::bitflags; use serde::Serialize; +/// Reads a `Minf` chunk. pub fn read_minf(b: &[u8]) -> ResultS { read_data! { @@ -23,6 +26,7 @@ pub fn read_minf(b: &[u8]) -> ResultS level_name}) } +/// Reads a `LightFunc` object. pub fn read_lightfunc(b: &[u8]) -> ResultS { read_data! { @@ -39,6 +43,7 @@ pub fn read_lightfunc(b: &[u8]) -> ResultS Ok(LightFunc{ftype, prd_nrm, prd_dta, val_nrm, val_dta}) } +/// Reads a `SideTex` object. pub fn read_sidetex(b: &[u8]) -> ResultS { read_data! { @@ -50,6 +55,7 @@ pub fn read_sidetex(b: &[u8]) -> ResultS Ok(SideTex{offs, tex_id}) } +/// Reads a `Point` object. pub fn read_point(b: &[u8]) -> ResultS { read_data! { @@ -61,6 +67,7 @@ pub fn read_point(b: &[u8]) -> ResultS Ok(Point{x, y}) } +/// Reads an `EPNT` chunk. pub fn read_epnt(b: &[u8]) -> ResultS<(Point, usize)> { read_data! { @@ -71,11 +78,13 @@ pub fn read_epnt(b: &[u8]) -> ResultS<(Point, usize)> Ok((pnt, 16)) } +/// Reads a `PNTS` chunk. pub fn read_pnts(b: &[u8]) -> ResultS<(Point, usize)> { Ok((read_point(b)?, 4)) } +/// Reads a `LINS` chunk. pub fn read_lins(b: &[u8]) -> ResultS<(Line, usize)> { read_data! { @@ -94,6 +103,7 @@ pub fn read_lins(b: &[u8]) -> ResultS<(Line, usize)> Ok((Line{flags, pnt_beg, pnt_end, side_fr, side_bk, poly_fr, poly_bk}, 32)) } +/// Reads a `SIDS` chunk. pub fn read_sids(b: &[u8]) -> ResultS<(Side, usize)> { read_data! { @@ -121,6 +131,7 @@ pub fn read_sids(b: &[u8]) -> ResultS<(Side, usize)> xfer_pri, xfer_sec, xfer_tra, shade}, 64)) } +/// Reads a `POLY` chunk. pub fn read_poly(b: &[u8]) -> ResultS<(Polygon, usize)> { read_data! { @@ -153,6 +164,7 @@ pub fn read_poly(b: &[u8]) -> ResultS<(Polygon, usize)> snd_ind, snd_amb, snd_rnd}, 128)) } +/// Reads a `LITE` chunk. pub fn read_lite(b: &[u8]) -> ResultS<(Light, usize)> { read_data! { @@ -176,6 +188,7 @@ pub fn read_lite(b: &[u8]) -> ResultS<(Light, usize)> ina_mid, tag}, 100)) } +/// Reads an `OBJS` chunk. pub fn read_objs(b: &[u8]) -> ResultS<(Object, usize)> { read_data! { @@ -198,6 +211,7 @@ pub fn read_objs(b: &[u8]) -> ResultS<(Object, usize)> Ok((Object{group, index, angle, poly, pos_x, pos_y, pos_z, flags, bias}, 16)) } +/// Reads a `plac` chunk. pub fn read_plac(b: &[u8]) -> ResultS<(ObjectFreq, usize)> { read_data! { @@ -215,6 +229,7 @@ pub fn read_plac(b: &[u8]) -> ResultS<(ObjectFreq, usize)> Ok((ObjectFreq{rnd_loc, cnt_ini, cnt_min, cnt_max, cnt_rnd, chance}, 12)) } +/// Reads an `ambi` chunk. pub fn read_ambi(b: &[u8]) -> ResultS<(SoundAmbi, usize)> { read_data! { @@ -226,6 +241,7 @@ pub fn read_ambi(b: &[u8]) -> ResultS<(SoundAmbi, usize)> Ok((SoundAmbi{index, volume}, 16)) } +/// Reads a `bonk` chunk. pub fn read_bonk(b: &[u8]) -> ResultS<(SoundRand, usize)> { read_data! { @@ -248,6 +264,7 @@ pub fn read_bonk(b: &[u8]) -> ResultS<(SoundRand, usize)> yaw_dta, pit_nrm, pit_dta}, 32)) } +/// Reads a `medi` chunk. pub fn read_medi(b: &[u8]) -> ResultS<(Media, usize)> { read_data! { @@ -274,6 +291,7 @@ pub fn read_medi(b: &[u8]) -> ResultS<(Media, usize)> min_lt, texture, xfer}, 32)) } +/// Reads a `plat` chunk. pub fn read_plat(b: &[u8]) -> ResultS<(Platform, usize)> { read_data! { @@ -293,6 +311,7 @@ pub fn read_plat(b: &[u8]) -> ResultS<(Platform, usize)> Ok((Platform{ptype, speed, delay, hei_min, hei_max, flags, index, tag}, 32)) } +/// A point in world-space. #[derive(Clone, PartialEq, Serialize)] pub struct Point { @@ -300,6 +319,7 @@ pub struct Point pub y: Unit, } +/// A line segment. #[derive(Debug, Serialize)] pub struct Line { @@ -312,6 +332,7 @@ pub struct Line pub poly_bk: OptU16, } +/// The texture of a side segment. #[derive(Debug, Serialize)] pub struct SideTex { @@ -319,6 +340,7 @@ pub struct SideTex pub tex_id: OptU16, } +/// One side of a line segment. #[derive(Debug, Serialize)] pub struct Side { @@ -335,6 +357,7 @@ pub struct Side pub shade: Fixed, } +/// A polygon segment. #[derive(Debug, Serialize)] pub struct Polygon { @@ -357,6 +380,7 @@ pub struct Polygon pub snd_rnd: OptU16, } +/// A light function. #[derive(Debug, Serialize)] pub struct LightFunc { @@ -367,6 +391,7 @@ pub struct LightFunc pub val_dta: u16, } +/// A dynamic polygon light. #[derive(Debug, Serialize)] pub struct Light { @@ -382,6 +407,7 @@ pub struct Light pub tag: u16, } +/// An object in the world. #[derive(Debug, Serialize)] pub struct Object { @@ -396,6 +422,7 @@ pub struct Object pub bias: u16, } +/// The difficulty definition for various object types. #[derive(Debug, Serialize)] pub struct ObjectFreq { @@ -407,6 +434,7 @@ pub struct ObjectFreq pub chance: u16, } +/// An ambient sound definition. #[derive(Debug, Serialize)] pub struct SoundAmbi { @@ -414,6 +442,7 @@ pub struct SoundAmbi pub volume: u16, } +/// A randomly played sound definition. #[derive(Debug, Serialize)] pub struct SoundRand { @@ -429,6 +458,7 @@ pub struct SoundRand pub pit_dta: Fixed, } +/// A media, as in a part of a polygon which goes up the middle of the wall. #[derive(Debug, Serialize)] pub struct Media { @@ -446,6 +476,7 @@ pub struct Media pub xfer: TransferMode, } +/// Extra information for polygons with platforms. #[derive(Debug, Serialize)] pub struct Platform { @@ -459,6 +490,7 @@ pub struct Platform pub tag: u16, } +/// Static map information. #[derive(Debug, PartialEq, Serialize)] pub struct Minf { @@ -472,6 +504,7 @@ pub struct Minf } bitflags! { + /// Flags for `Line`. #[derive(Serialize)] pub struct LineFlags: u16 { @@ -485,6 +518,7 @@ bitflags! { } bitflags! { + /// Flags for `Side`. #[derive(Serialize)] pub struct SideFlags: u16 { @@ -500,6 +534,7 @@ bitflags! { } bitflags! { + /// Static environment flags. #[derive(Serialize)] pub struct EnvFlags: u16 { @@ -520,6 +555,7 @@ bitflags! { } bitflags! { + /// Static entry point flags. #[derive(Serialize)] pub struct EntFlags: u32 { @@ -535,6 +571,7 @@ bitflags! { } bitflags! { + /// Static mission flags. #[derive(Serialize)] pub struct MsnFlags: u16 { @@ -547,6 +584,7 @@ bitflags! { } bitflags! { + /// Flags for `Polygon`. #[derive(Serialize)] pub struct PolyFlags: u16 { @@ -555,6 +593,7 @@ bitflags! { } bitflags! { + /// Flags for `Light`. #[derive(Serialize)] pub struct LightFlags: u16 { @@ -565,6 +604,7 @@ bitflags! { } bitflags! { + /// Flags for `Object`. #[derive(Serialize)] pub struct ObjectFlags: u16 { @@ -578,6 +618,7 @@ bitflags! { } bitflags! { + /// Flags for `Platform`. #[derive(Serialize)] pub struct PlatformFlags: u32 { @@ -612,6 +653,7 @@ bitflags! { } c_enum! { + /// The texture type of a `Side`. #[derive(Debug, Serialize)] pub enum SideType: u16 { @@ -624,6 +666,7 @@ c_enum! { } c_enum! { + /// The action type of a `Polygon`. #[derive(Debug, Serialize)] pub enum PolyType: u16 { @@ -650,6 +693,7 @@ c_enum! { } c_enum! { + /// The type of function for a `LightFunc`. #[derive(Debug, Serialize)] pub enum LightFuncType: u16 { @@ -661,6 +705,7 @@ c_enum! { } c_enum! { + /// The type of a `Light`. #[derive(Debug, Serialize)] pub enum LightType: u16 { @@ -671,6 +716,7 @@ c_enum! { } c_enum! { + /// The liquid type of a `Media`. #[derive(Debug, Serialize)] pub enum MediaType: u16 { diff --git a/src/marathon/mod.rs b/src/marathon/mod.rs index d2c173a..86fc790 100644 --- a/src/marathon/mod.rs +++ b/src/marathon/mod.rs @@ -1,4 +1,4 @@ -//! Library for file data formats. +//! Library for file format data readers. pub mod machdr; pub mod map; diff --git a/src/marathon/phy.rs b/src/marathon/phy.rs index 4d8d91b..05663ab 100644 --- a/src/marathon/phy.rs +++ b/src/marathon/phy.rs @@ -1,7 +1,10 @@ +//! Structures used by Marathon's Physics format. + use crate::{durandal::{bin::*, err::*, fixed::*}}; use bitflags::bitflags; use serde::Serialize; +/// Reads a `PXpx` chunk. pub fn read_pxpx(b: &[u8]) -> ResultS<(Physics, usize)> { read_data! { @@ -40,6 +43,7 @@ pub fn read_pxpx(b: &[u8]) -> ResultS<(Physics, usize)> vel_bkw, vel_fwd, vel_prp, vel_rec, vel_trm}, 104)) } +/// Reads a `FXpx` chunk. pub fn read_fxpx(b: &[u8]) -> ResultS<(Effect, usize)> { read_data! { @@ -57,6 +61,7 @@ pub fn read_fxpx(b: &[u8]) -> ResultS<(Effect, usize)> Ok((Effect{collection, shape, pitch, flags, delay, delay_snd}, 14)) } +/// Reads a `WPpx` chunk. pub fn read_wppx(b: &[u8]) -> ResultS<(Weapon, usize)> { read_data! { @@ -98,6 +103,7 @@ pub fn read_wppx(b: &[u8]) -> ResultS<(Weapon, usize)> typ_powerup, typ_weapon, wid_idle}, 134)) } +/// Reads a `PRpx` chunk. pub fn read_prpx(b: &[u8]) -> ResultS<(Projectile, usize)> { read_data! { @@ -128,6 +134,7 @@ pub fn read_prpx(b: &[u8]) -> ResultS<(Projectile, usize)> flags, speed, range, snd_pitch, snd_fly, snd_bounce}, 48)) } +/// Reads a `MNpx` chunk. pub fn read_mnpx(b: &[u8]) -> ResultS<(Monster, usize)> { read_data! { @@ -208,6 +215,7 @@ pub fn read_mnpx(b: &[u8]) -> ResultS<(Monster, usize)> atk_frequency, atk_melee, atk_range}, 156)) } +/// Reads a `Trigger` object. fn read_trigger(b: &[u8]) -> ResultS { read_data! { @@ -239,6 +247,7 @@ fn read_trigger(b: &[u8]) -> ResultS tic_recover, tic_round, typ_ammo, typ_casing, typ_proj}) } +/// Reads a `Damage` object. fn read_damage(b: &[u8]) -> ResultS { read_data! { @@ -256,6 +265,7 @@ fn read_damage(b: &[u8]) -> ResultS Ok(Damage{dtype, alien, dmg_base, dmg_rand, scale}) } +/// Reads an `Attack` object. fn read_attack(b: &[u8]) -> ResultS { read_data! { @@ -273,6 +283,7 @@ fn read_attack(b: &[u8]) -> ResultS Ok(Attack{ptype, rep, error, range, shape, ofs_x, ofs_y, ofs_z}) } +/// Static physics information. #[derive(Debug, Serialize)] pub struct Physics { @@ -304,6 +315,7 @@ pub struct Physics pub vel_trm: Fixed, } +/// An effect definition. #[derive(Debug, Serialize)] pub struct Effect { @@ -315,6 +327,7 @@ pub struct Effect pub delay_snd: OptU16, } +/// A weapon definition. #[derive(Debug, Serialize)] pub struct Weapon { @@ -345,6 +358,7 @@ pub struct Weapon pub wid_idle: Fixed, } +/// The definition of one of two triggers for a weapon. #[derive(Debug, Serialize)] pub struct Trigger { @@ -368,6 +382,7 @@ pub struct Trigger pub typ_proj: u16, } +/// A projectile definition. #[derive(Debug, Serialize)] pub struct Projectile { @@ -390,6 +405,7 @@ pub struct Projectile pub snd_bounce: OptU16, } +/// A monster definition. #[derive(Debug, Serialize)] pub struct Monster { @@ -446,6 +462,7 @@ pub struct Monster pub atk_range: Attack, } +/// A damage definition. #[derive(Debug, Serialize)] pub struct Damage { @@ -456,6 +473,7 @@ pub struct Damage pub scale: Fixed, } +/// The definition of a monster's attack. #[derive(Debug, Serialize)] pub struct Attack { @@ -470,6 +488,7 @@ pub struct Attack } bitflags! { + /// Flags for an effect. #[derive(Serialize)] pub struct EffectFlags: u16 { @@ -482,6 +501,7 @@ bitflags! { } bitflags! { + /// Flags for a weapon. #[derive(Serialize)] pub struct WeaponFlags: u16 { @@ -500,6 +520,7 @@ bitflags! { } bitflags! { + /// Flags for a projectile. #[derive(Serialize)] pub struct ProjectileFlags: u32 { @@ -528,6 +549,7 @@ bitflags! { } bitflags! { + /// Flags for a monster. #[derive(Serialize)] pub struct MonsterFlags: u32 { @@ -563,6 +585,7 @@ bitflags! { } bitflags! { + /// The composite type of a monster. #[derive(Serialize)] pub struct MonsterClass: u32 { @@ -586,6 +609,7 @@ bitflags! { } bitflags! { + /// The composite type of damage taken by something. #[derive(Serialize)] pub struct DamageTypeFlags: u32 { @@ -617,6 +641,7 @@ bitflags! { } c_enum! { + /// A bullet shell casing emitted by a weapon. #[derive(Debug, Serialize)] pub enum CasingType: u16 { @@ -630,6 +655,7 @@ c_enum! { } c_enum! { + /// The type of functionality a weapon provides. #[derive(Debug, Serialize)] pub enum WeaponType: u16 { @@ -642,6 +668,7 @@ c_enum! { } c_enum! { + /// A named type of damage taken by something. #[derive(Debug, Serialize)] pub enum DamageType: u16 { diff --git a/src/marathon/shp.rs b/src/marathon/shp.rs index f38d2fc..2ff54df 100644 --- a/src/marathon/shp.rs +++ b/src/marathon/shp.rs @@ -5,7 +5,8 @@ use crate::{durandal::{bin::*, err::*, fixed::*, image::*, text::*}, use bitflags::bitflags; use serde::Serialize; -fn color(b: &[u8], clut: &mut [ColorShp]) -> ResultS<()> +/// Reads a color from a color table into `clut`. +fn read_color(b: &[u8], clut: &mut [ColorShp]) -> ResultS<()> { read_data! { 8, BE in b => @@ -27,11 +28,12 @@ fn color(b: &[u8], clut: &mut [ColorShp]) -> ResultS<()> Ok(()) } -fn color_tables(b: &[u8], - tab_ofs: usize, - tab_num: usize, - clr_num: usize) - -> ResultS>> +/// Reads all color tables. +pub fn color_tables(b: &[u8], + tab_ofs: usize, + tab_num: usize, + clr_num: usize) + -> ResultS>> { let end = tab_num * clr_num * 8; @@ -42,7 +44,7 @@ fn color_tables(b: &[u8], for clut in v.iter_mut().take(tab_num) { for _ in 0..clr_num { - color(&b[p..p + 8], clut)?; + read_color(&b[p..p + 8], clut)?; p += 8; } } @@ -50,7 +52,8 @@ fn color_tables(b: &[u8], Ok(v) } -fn bitmap(b: &[u8]) -> ResultS +/// Reads a `Bitmap`. +pub fn read_bitmap(b: &[u8]) -> ResultS { read_data! { 26, BE in b => @@ -116,7 +119,8 @@ fn bitmap(b: &[u8]) -> ResultS Ok(bmp) } -fn frame(b: &[u8]) -> ResultS +/// Reads a `Frame`. +pub fn read_frame(b: &[u8]) -> ResultS { read_data! { 36, BE in b => @@ -136,7 +140,8 @@ fn frame(b: &[u8]) -> ResultS Ok(Frame{flags, min_lt, bmp_ind, wrl_l, wrl_r, wrl_t, wrl_b, wrl_x, wrl_y}) } -fn sequence(b: &[u8]) -> ResultS +/// Reads a `Sequence`. +pub fn read_sequence(b: &[u8]) -> ResultS { read_data! { 88, BE in b => @@ -161,7 +166,8 @@ fn sequence(b: &[u8]) -> ResultS snd_key, snd_end, loop_f}) } -fn collection(b: &[u8]) -> ResultS +/// Reads a `Collection`. +pub fn read_collection(b: &[u8]) -> ResultS { read_data! { 544, BE in b => @@ -185,13 +191,14 @@ fn collection(b: &[u8]) -> ResultS } let tabs = color_tables(b, tab_ofs, tab_num, clr_num)?; - let bmps = rd_ofstable(b, bmp_ofs, bmp_num, bitmap)?; - let frms = rd_ofstable(b, frm_ofs, frm_num, frame)?; - let seqs = rd_ofstable(b, seq_ofs, seq_num, sequence)?; + let bmps = rd_ofstable(b, bmp_ofs, bmp_num, read_bitmap)?; + let frms = rd_ofstable(b, frm_ofs, frm_num, read_frame)?; + let seqs = rd_ofstable(b, seq_ofs, seq_num, read_sequence)?; Ok(Collection{ctyp: cl_type, tabs, bmps, frms, seqs}) } +/// Read all of the collections in a Shapes file. pub fn read_shapes(b: &[u8]) -> ResultS> { let mut cl = Vec::with_capacity(32); @@ -209,13 +216,13 @@ pub fn read_shapes(b: &[u8]) -> ResultS> let c_lo = if lo_ofs == u32::max_value() as usize { None } else { - Some(collection(&b[lo_ofs..lo_ofs + lo_len])?) + Some(read_collection(&b[lo_ofs..lo_ofs + lo_len])?) }; let c_hi = if hi_ofs == u32::max_value() as usize { None } else { - Some(collection(&b[hi_ofs..hi_ofs + hi_len])?) + Some(read_collection(&b[hi_ofs..hi_ofs + hi_len])?) }; cl.push((c_lo, c_hi)); @@ -228,7 +235,8 @@ pub fn read_shapes(b: &[u8]) -> ResultS> impl Bitmap { - fn new(w: usize, h: usize, alpha: bool, cmajr: bool) -> Self + /// Creates an empty bitmap. + pub fn new(w: usize, h: usize, alpha: bool, cmajr: bool) -> Self { Self{w, h, alpha, cmajr, cr: Vec::with_capacity(w * h)} } @@ -236,6 +244,7 @@ impl Bitmap impl<'a, 'b> ImageShp<'a, 'b> { + /// Creates an `ImageShp` with the given bitmap. pub fn new(bmp: &'a Bitmap, clut: &'b [ColorShp]) -> Self { Self{bmp, clut} @@ -302,6 +311,7 @@ impl Color for ColorShp } } +/// A color in an `ImageShp`'s color table. #[derive(Clone, Debug, Serialize)] pub enum ColorShp { @@ -315,6 +325,7 @@ pub enum ColorShp }, } +/// An unpacked Shape bitmap. #[derive(Debug)] pub struct Bitmap { @@ -325,12 +336,15 @@ pub struct Bitmap cmajr: bool, } +/// An image from a Shape. This mainly just exists so that `Bitmap` can use the +/// `Image` trait. pub struct ImageShp<'a, 'b> { bmp: &'a Bitmap, clut: &'b [ColorShp], } +/// A frame, also known as a low level shape. #[derive(Debug, Serialize)] pub struct Frame { @@ -345,6 +359,7 @@ pub struct Frame wrl_y: Unit, } +/// A sequence, also known as a high level shape. #[derive(Debug, Serialize)] pub struct Sequence { @@ -361,6 +376,7 @@ pub struct Sequence loop_f: u16, } +/// A collection of color tables, bitmaps, frames and sequences. #[derive(Debug)] pub struct Collection { @@ -371,6 +387,7 @@ pub struct Collection pub seqs: Vec, } +/// A collection, which may have low- and high-definition variations, or none. pub type CollectionDef = (Option, Option); bitflags! { @@ -382,6 +399,7 @@ bitflags! { } bitflags! { + /// Flags for `Frame`. #[derive(Serialize)] pub struct FrameFlags: u16 { @@ -392,6 +410,7 @@ bitflags! { } c_enum! { + /// The type of a collection. #[derive(Debug, Serialize)] pub enum CollectionType: u16 { @@ -404,6 +423,7 @@ c_enum! { } c_enum! { + /// The type of or number of views for a sequence. #[derive(Debug, Serialize)] pub enum ViewType: u16 { diff --git a/src/marathon/snd.rs b/src/marathon/snd.rs index 3c7cf66..b613e32 100644 --- a/src/marathon/snd.rs +++ b/src/marathon/snd.rs @@ -3,9 +3,10 @@ use crate::durandal::{bin::*, err::*, fixed::*, sound::*}; use bitflags::bitflags; use serde::Serialize; -use std::collections::HashMap; +use std::collections::BTreeMap; -fn sound(b: &[u8]) -> ResultS +/// Reads a sound. +pub fn read_sound(b: &[u8]) -> ResultS { read_data! { 21, BE in b => @@ -44,7 +45,8 @@ fn sound(b: &[u8]) -> ResultS } } -fn sound_def(b: &[u8]) -> ResultS, u16, SoundDef)>> +/// Reads a sound definition. +pub fn read_sound_def(b: &[u8]) -> ResultS, u16, SoundDef)>> { read_data! { 64, BE in b => @@ -83,12 +85,13 @@ fn sound_def(b: &[u8]) -> ResultS, u16, SoundDef)>> Ok(Some((ofs, index, SoundDef{header, sounds}))) } +/// Reads all sounds from a Sound file. pub fn read_sounds(b: &[u8]) -> ResultS> { read_data! { 260, BE in b => version = u32[0]; - magic = iden[4]; + magic = Ident[4]; src_num = u16[8] as usize; snd_num = u16[10] as usize; } @@ -101,12 +104,12 @@ pub fn read_sounds(b: &[u8]) -> ResultS> let mut p = 260; for _ in 0..src_num { - let mut st = HashMap::with_capacity(snd_num); + let mut st = BTreeMap::new(); for _ in 0..snd_num { - if let Some((ofs, idx, mut def)) = sound_def(&b[p..p + 64])? { + if let Some((ofs, idx, mut def)) = read_sound_def(&b[p..p + 64])? { for &ofs in &ofs { - def.sounds.push(sound(&b[ofs..])?); + def.sounds.push(read_sound(&b[ofs..])?); } st.insert(idx, def); @@ -121,6 +124,7 @@ pub fn read_sounds(b: &[u8]) -> ResultS> Ok(sc) } +/// The header of a sound definition. #[derive(Debug, Serialize)] pub struct SoundHead { @@ -131,15 +135,18 @@ pub struct SoundHead pub pitch_hi: Fixed, } +/// A sound definition containing one, many or no sounds. pub struct SoundDef { pub header: SoundHead, pub sounds: Vec, } -pub type SoundTable = HashMap; +/// A table of sound definitions. +pub type SoundTable = BTreeMap; bitflags! { + /// Flags for `SoundHead`. #[derive(Serialize)] pub struct SoundFlags: u16 { @@ -154,6 +161,7 @@ bitflags! { } c_enum! { + /// The type of volume this sound has. #[derive(Debug, Serialize)] pub enum Volume: u16 { diff --git a/src/marathon/trm.rs b/src/marathon/trm.rs index 7c8bde5..072dfbe 100644 --- a/src/marathon/trm.rs +++ b/src/marathon/trm.rs @@ -1,9 +1,12 @@ +//! Structures used by Marathon's Map format's terminal definitions. + use crate::durandal::{err::*, text::*}; use bitflags::bitflags; use serde::Serialize; use std::fmt; -fn read_group(b: &[u8], text: &[u8]) -> ResultS +/// Reads a `Group`. +pub fn read_group(b: &[u8], text: &[u8]) -> ResultS { read_data! { 12, BE in b => @@ -22,7 +25,8 @@ fn read_group(b: &[u8], text: &[u8]) -> ResultS Ok(Group{flags, ttype, pdata, lines, text}) } -fn read_face(b: &[u8]) -> ResultS +/// Reads a `Face`. +pub fn read_face(b: &[u8]) -> ResultS { read_data! { 6, BE in b => @@ -34,6 +38,7 @@ fn read_face(b: &[u8]) -> ResultS Ok(Face{start, face, color}) } +/// Reads a `term` chunk. pub fn read_term(b: &[u8]) -> ResultS<(Terminal, usize)> { const SIZE_GROUP: usize = 12; @@ -76,6 +81,7 @@ pub fn read_term(b: &[u8]) -> ResultS<(Terminal, usize)> Ok((Terminal{lines, groups, faces}, end)) } +/// A terminal definition, with collections of groups and faces. #[derive(Debug, Serialize)] pub struct Terminal { @@ -84,6 +90,7 @@ pub struct Terminal faces: Vec, } +/// A text face. #[derive(Debug, Serialize)] pub struct Face { @@ -92,6 +99,7 @@ pub struct Face color: u16, } +/// A terminal command grouping. #[derive(Serialize)] pub struct Group { @@ -103,6 +111,7 @@ pub struct Group } bitflags! { + /// Flags for `Group`. #[derive(Serialize)] pub struct GroupFlags: u16 { @@ -112,6 +121,7 @@ bitflags! { } c_enum! { + /// The command of a `Group`. #[derive(Debug, Serialize)] pub enum GroupType: u16 { diff --git a/src/marathon/xfer.rs b/src/marathon/xfer.rs index ab71c4d..876ebf1 100644 --- a/src/marathon/xfer.rs +++ b/src/marathon/xfer.rs @@ -1,7 +1,10 @@ +//! Transfer Mode type. + use crate::durandal::err::*; use serde::Serialize; c_enum! { + /// A rendering style for many things. #[derive(Debug, Serialize)] pub enum TransferMode: u16 {