Compare commits
7 Commits
9c02fba968
...
7e92521e2e
Author | SHA1 | Date |
---|---|---|
an | 7e92521e2e | |
an | aa0f6cf537 | |
an | 708f2e106c | |
an | 7e5375f32c | |
an | b830718258 | |
an | ee35332b23 | |
an | 6ee6140ba8 |
|
@ -1,6 +1,6 @@
|
|||
/target
|
||||
/out
|
||||
*.res
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
||||
perf.data*
|
||||
*.bat
|
||||
|
|
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
Some of the data contained in tests/data and benches/data is
|
||||
Copyright © Bungie Software. I do not own them, but am permitted to
|
||||
redistribute them. Everything else is:
|
||||
redistribute them. Everything else is public domain, as stated:
|
||||
|
||||
To the extent possible under law, I, Alison Sanderson, have waived all
|
||||
copyright and related or neighboring rights to this Document as described by
|
||||
|
|
|
@ -5,75 +5,92 @@ use std::{fmt, num::NonZeroU16};
|
|||
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! _durandal_read_impl {
|
||||
macro_rules! _rd_impl {
|
||||
// big endian
|
||||
(BE $b:expr; $nam:ident u16 $n:expr) => {
|
||||
_durandal_read_impl!($b; u16::from_be_bytes, $nam 2 $n);
|
||||
(BIG $b:expr; $nam:ident u16 $n:expr; $at:expr) => {
|
||||
_rd_impl!($b; u16::from_be_bytes, $nam 2 $n + $at);
|
||||
};
|
||||
(BE $b:expr; $nam:ident i16 $n:expr) => {
|
||||
_durandal_read_impl!($b; i16::from_be_bytes, $nam 2 $n);
|
||||
(BIG $b:expr; $nam:ident i16 $n:expr; $at:expr) => {
|
||||
_rd_impl!($b; i16::from_be_bytes, $nam 2 $n + $at);
|
||||
};
|
||||
(BE $b:expr; $nam:ident u32 $n:expr) => {
|
||||
_durandal_read_impl!($b; u32::from_be_bytes, $nam 4 $n);
|
||||
(BIG $b:expr; $nam:ident u32 $n:expr; $at:expr) => {
|
||||
_rd_impl!($b; u32::from_be_bytes, $nam 4 $n + $at);
|
||||
};
|
||||
(BE $b:expr; $nam:ident i32 $n:expr) => {
|
||||
_durandal_read_impl!($b; i32::from_be_bytes, $nam 4 $n);
|
||||
(BIG $b:expr; $nam:ident i32 $n:expr; $at:expr) => {
|
||||
_rd_impl!($b; i32::from_be_bytes, $nam 4 $n + $at);
|
||||
};
|
||||
|
||||
// little endian
|
||||
(LE $b:expr; $nam:ident u16 $n:expr) => {
|
||||
_durandal_read_impl!($b; u16::from_le_bytes, $nam 2 $n);
|
||||
(LITTLE $b:expr; $nam:ident u16 $n:expr; $at:expr) => {
|
||||
_rd_impl!($b; u16::from_le_bytes, $nam 2 $n + $at);
|
||||
};
|
||||
(LE $b:expr; $nam:ident i16 $n:expr) => {
|
||||
_durandal_read_impl!($b; i16::from_le_bytes, $nam 2 $n);
|
||||
(LITTLE $b:expr; $nam:ident i16 $n:expr; $at:expr) => {
|
||||
_rd_impl!($b; i16::from_le_bytes, $nam 2 $n + $at);
|
||||
};
|
||||
(LE $b:expr; $nam:ident u32 $n:expr) => {
|
||||
_durandal_read_impl!($b; u32::from_le_bytes, $nam 4 $n);
|
||||
(LITTLE $b:expr; $nam:ident u32 $n:expr; $at:expr) => {
|
||||
_rd_impl!($b; u32::from_le_bytes, $nam 4 $n + $at);
|
||||
};
|
||||
(LE $b:expr; $nam:ident i32 $n:expr) => {
|
||||
_durandal_read_impl!($b; i32::from_le_bytes, $nam 4 $n);
|
||||
(LITTLE $b:expr; $nam:ident i32 $n:expr; $at:expr) => {
|
||||
_rd_impl!($b; i32::from_le_bytes, $nam 4 $n + $at);
|
||||
};
|
||||
|
||||
// either endianness
|
||||
($e:ident $b:expr; $nam:ident Angle $n:expr) => {
|
||||
_durandal_read_impl!($e $b; $nam u16 $n);
|
||||
($e:ident $b:expr; $nam:ident Angle $n:expr; $at:expr) => {
|
||||
_rd_impl!($e $b; $nam u16 $n; $at);
|
||||
let $nam = Angle::from_bits($nam);
|
||||
};
|
||||
($e:ident $b:expr; $nam:ident Fixed $n:expr) => {
|
||||
_durandal_read_impl!($e $b; $nam u32 $n);
|
||||
($e:ident $b:expr; $nam:ident Fixed $n:expr; $at:expr) => {
|
||||
_rd_impl!($e $b; $nam u32 $n; $at);
|
||||
let $nam = Fixed::from_bits($nam);
|
||||
};
|
||||
($e:ident $b:expr; $nam:ident Unit $n:expr) => {
|
||||
_durandal_read_impl!($e $b; $nam u16 $n);
|
||||
($e:ident $b:expr; $nam:ident Unit $n:expr; $at:expr) => {
|
||||
_rd_impl!($e $b; $nam u16 $n; $at);
|
||||
let $nam = Unit::from_bits($nam);
|
||||
};
|
||||
($e:ident $b:expr; $nam:ident OptU16 $n:expr) => {
|
||||
_durandal_read_impl!($e $b; $nam u16 $n);
|
||||
let $nam = OptU16::from_repr($nam);
|
||||
($e:ident $b:expr; $nam:ident OptU16 $n:expr; $at:expr) => {
|
||||
_rd_impl!($e $b; $nam u16 $n; $at);
|
||||
let $nam = OptU16::from($nam);
|
||||
};
|
||||
($e:ident $b:expr; $nam:ident usize u16 $n:expr) => {
|
||||
_durandal_read_impl!($e $b; $nam u16 $n);
|
||||
($e:ident $b:expr; $nam:ident usize u16 $n:expr; $at:expr) => {
|
||||
_rd_impl!($e $b; $nam u16 $n; $at);
|
||||
let $nam = usize::from($nam);
|
||||
};
|
||||
($e:ident $b:expr; $nam:ident usize u32 $n:expr) => {
|
||||
_durandal_read_impl!($e $b; $nam u32 $n);
|
||||
($e:ident $b:expr; $nam:ident usize u32 $n:expr; $at:expr) => {
|
||||
_rd_impl!($e $b; $nam u32 $n; $at);
|
||||
let $nam = usize_from_u32($nam);
|
||||
};
|
||||
(
|
||||
$e:ident $b:expr; $nam:ident enum $et:ident $t:ident $n:expr; $at:expr
|
||||
) => {
|
||||
_rd_impl!($e $b; $nam $t $n; $at);
|
||||
let $nam = $et::try_from($nam)?;
|
||||
};
|
||||
(
|
||||
$e:ident $b:expr; $nam:ident flag $ft:ident $t:ident $n:expr; $at:expr
|
||||
) => {
|
||||
_rd_impl!($e $b; $nam $t $n; $at);
|
||||
let $nam = flag_ok!($ft, $nam)?;
|
||||
};
|
||||
|
||||
// no endianness
|
||||
($_:ident $b:expr; $nam:ident u8 $n:expr) => {let $nam = $b[$n];};
|
||||
($_:ident $b:expr; $nam:ident slice u8 $n:expr) => {let $nam = &$b[$n];};
|
||||
($_:ident $b:expr; $nam:ident i8 $n:expr) => {
|
||||
let $nam = i8::from_ne_bytes([$b[$n]]);
|
||||
($_:ident $b:expr; $nam:ident u8 $n:expr; $at:expr) => {
|
||||
let $nam = $b[$n + $at];
|
||||
};
|
||||
($_:ident $b:expr; $nam:ident Ident $n:expr) => {
|
||||
let $nam = Ident([$b[$n], $b[$n + 1], $b[$n + 2], $b[$n + 3]]);
|
||||
($_:ident $b:expr; $nam:ident i8 $n:expr; $at:expr) => {
|
||||
let $nam = $b[$n + $at] as i8;
|
||||
};
|
||||
($_:ident $b:expr; $nam:ident $f:ident $n:expr) => {
|
||||
let $nam = $f(&$b[$n])?;
|
||||
($_:ident $b:expr; $nam:ident u8 $n:expr; $rn:expr; $at:expr) => {
|
||||
let $nam = &$b[$n + $at..$n + $at + $rn];
|
||||
};
|
||||
($_:ident $b:expr; $nam:ident no_try $f:ident $n:expr) => {
|
||||
let $nam = $f(&$b[$n]);
|
||||
($_:ident $b:expr; $nam:ident Ident $n:expr; $at:expr) => {
|
||||
_rd_impl!($b; Ident, $nam 4 $n + $at);
|
||||
};
|
||||
(
|
||||
$_:ident $b:expr; $nam:ident no_try $f:ident $n:expr; $rn:expr; $at:expr
|
||||
) => {
|
||||
let $nam = $f(&$b[$n + $at..$n + $at + $rn]);
|
||||
};
|
||||
($_:ident $b:expr; $nam:ident $f:ident $n:expr; $rn:expr; $at:expr) => {
|
||||
let $nam = $f(&$b[$n + $at..$n + $at + $rn])?;
|
||||
};
|
||||
|
||||
// worker - creates let statement
|
||||
|
@ -89,23 +106,31 @@ macro_rules! _durandal_read_impl {
|
|||
///
|
||||
/// # Syntax
|
||||
///
|
||||
/// First start by specifying the endianness, size and source using the syntax
|
||||
/// `endian, size in source =>` where:
|
||||
/// First start by specifying the basic information, using the syntax:
|
||||
/// `endian: ENDIAN, buf: BUFFER, size: SIZE, start: START,` 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.
|
||||
/// - `ENDIAN` is `BIG` or `LITTLE` for big- or little-endian respectively.
|
||||
/// - `BUFFER` is a `u8` slice to read data from. This expression will be
|
||||
/// evaluated many times, so be careful when specifying it.
|
||||
/// - `SIZE` is an expression specifying the last index that should be used by
|
||||
/// this macro in `BUFFER`.
|
||||
/// - `START` is an expression specifying the index to start at in `BUFFER`.
|
||||
/// All indices and sizes will have this added to them.
|
||||
///
|
||||
/// After the initializer line, all lines have the syntax
|
||||
/// `name = type[place] opts;` where:
|
||||
/// Following that is a block with the syntax `data { ... }`. All lines within
|
||||
/// this block have the syntax `let NAME = TYPE[INDEX] 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
|
||||
/// - `NAME` is the binding to put the resulting data in.
|
||||
/// - `TYPE` is one of:
|
||||
/// - `u8` or `i8`: one byte will be read at `INDEX`. If `INDEX` is a range,
|
||||
/// this will be a slice into `BUFFER` instead.
|
||||
/// - `u16` or `i16`: two bytes will be read at `INDEX` with `from_*_bytes`.
|
||||
/// If `OPTS` is `usize`, this converts the resulting number to `usize` by
|
||||
/// using `usize::from`.
|
||||
/// - `u32` or `i32`: four bytes will be read at `INDEX` with `from_*_bytes`.
|
||||
/// If `OPTS` is `usize`, this converts the resulting number to `usize` by
|
||||
/// using `usize_from_u32`.
|
||||
/// - `Ident`: four bytes will be read at `INDEX` 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.
|
||||
|
@ -114,25 +139,21 @@ macro_rules! _durandal_read_impl {
|
|||
/// - `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:
|
||||
/// - `slice` when `type` is `u8`: `place` is a range specifying a `u8` slice
|
||||
/// to be taken from `source`.
|
||||
/// - `usize` when `type` is `u16` or `u32`: converts the resulting integer to
|
||||
/// `usize` by `usize_to_u32` for `u32` or by `from` for `u16`.
|
||||
/// - `no_try` 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.
|
||||
/// `OptU16::from`, resulting in an `OptU16` object.
|
||||
/// - The name of a function, which is passed the index range as its only
|
||||
/// argument. The function's result has the `?` operator applied to it,
|
||||
/// unless `OPTS` is `no_try`.
|
||||
/// - `OPT`, if not one of the things listed above, may be `enum TYPE` to apply
|
||||
/// an enumeration made by `c_enum!`, or `flag TYPE` to apply a bitfield made
|
||||
/// by `bitflags!`.
|
||||
/// - `INDEX` is either an integer literal which must be representable as
|
||||
/// `usize`, or a range with the syntax `INDEX; SIZE` denoting the beginning
|
||||
/// and size of the range.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This macro will not panic unless any index expression used exceeds or
|
||||
/// equals `size`.
|
||||
/// equals `SIZE + START`, or a function passed to it panics.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -144,35 +165,37 @@ macro_rules! _durandal_read_impl {
|
|||
/// let buffer = &[4, 0, 2, 0, 0, 0, 6];
|
||||
///
|
||||
/// read_data! {
|
||||
/// 7, LE in buffer =>
|
||||
/// four = u16[0];
|
||||
/// two = u32[2];
|
||||
/// six = u8 [6];
|
||||
/// endian: LITTLE, buf: buffer, size: 7, start: 0, data {
|
||||
/// let four = u16[0];
|
||||
/// let two = u32[2];
|
||||
/// let six = u8[6];
|
||||
/// let byte = u8[2; 4];
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(four, 4_u16);
|
||||
/// assert_eq!(two, 2_u32);
|
||||
/// assert_eq!(six, 6_u8);
|
||||
/// assert_eq!(byte, &[2, 0, 0, 0]);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! read_data {
|
||||
(
|
||||
$sz:expr , $ty:ident in $b:expr =>
|
||||
$( $nam:ident = $t:ident [ $n:expr ] $( $ex:ident )* ; )*
|
||||
endian: $ty:ident, buf: $b:expr, size: $sz:expr, start: $at:expr, data {
|
||||
$(let $nam:ident = $t:ident[$n:expr $(; $rn:expr)?] $($ex:ident)*;)*
|
||||
}
|
||||
) => {
|
||||
$crate::check_data!($sz, $b);
|
||||
$($crate::_durandal_read_impl!($ty $b; $nam $($ex)* $t $n);)*
|
||||
$crate::check_data!($at + $sz, $b);
|
||||
$($crate::_rd_impl!($ty $b; $nam $($ex)* $t ($n); $(($rn);)? ($at));)*
|
||||
};
|
||||
}
|
||||
|
||||
/// Checks if there is enough data in `b`.
|
||||
#[macro_export]
|
||||
macro_rules! check_data {
|
||||
(
|
||||
$sz:expr , $b:expr
|
||||
) => {
|
||||
($sz:expr, $b:expr) => {
|
||||
if $b.len() < $sz {
|
||||
return Err(err_msg("not enough data"));
|
||||
}
|
||||
|
@ -220,6 +243,7 @@ pub const fn ident(b: &[u8]) -> Ident {Ident([b[0], b[1], b[2], b[3]])}
|
|||
///
|
||||
/// assert_eq!(u32b(&[0x00, 0x0B, 0xDE, 0x31]), 777_777u32);
|
||||
/// ```
|
||||
#[inline]
|
||||
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.
|
||||
|
@ -235,6 +259,7 @@ pub fn u32b(b: &[u8]) -> u32 {u32::from_be_bytes([b[0], b[1], b[2], b[3]])}
|
|||
///
|
||||
/// assert_eq!(u16b(&[0x1E, 0x61]), 7_777u16);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn u16b(b: &[u8]) -> u16 {u16::from_be_bytes([b[0], b[1]])}
|
||||
|
||||
/// Applies `i32::from_be_bytes` to a slice.
|
||||
|
@ -250,6 +275,7 @@ pub fn u16b(b: &[u8]) -> u16 {u16::from_be_bytes([b[0], b[1]])}
|
|||
///
|
||||
/// assert_eq!(i32b(&[0xFF, 0x89, 0x52, 0x0F]), -7_777_777i32);
|
||||
/// ```
|
||||
#[inline]
|
||||
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.
|
||||
|
@ -265,6 +291,7 @@ pub fn i32b(b: &[u8]) -> i32 {i32::from_be_bytes([b[0], b[1], b[2], b[3]])}
|
|||
///
|
||||
/// assert_eq!(i16b(&[0xE1, 0x9F]), -7_777i16);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn i16b(b: &[u8]) -> i16 {i16::from_be_bytes([b[0], b[1]])}
|
||||
|
||||
/// Applies a read function over a slice.
|
||||
|
@ -376,6 +403,46 @@ pub fn rd_ofstable<T, F>(b: &[u8],
|
|||
Ok(v)
|
||||
}
|
||||
|
||||
impl From<u16> for OptU16
|
||||
{
|
||||
#[inline]
|
||||
fn from(n: u16) -> Self
|
||||
{
|
||||
if n == u16::max_value() {
|
||||
Self(None)
|
||||
} else {
|
||||
Self(NonZeroU16::new(n + 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<u16> for OptU16
|
||||
{
|
||||
/// Returns the `u16` representation.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use maraiah::durandal::bin::OptU16;
|
||||
///
|
||||
/// let u16_max = u16::max_value();
|
||||
///
|
||||
/// // These type annotations are necessary.
|
||||
///
|
||||
/// assert_eq!(<OptU16 as Into<u16>>::into(OptU16::from(500u16)), 500u16);
|
||||
/// assert_eq!(<OptU16 as Into<u16>>::into(OptU16::from(u16_max)), u16_max);
|
||||
/// assert_eq!(<OptU16 as Into<u16>>::into(OptU16::from(0u16)), 0u16);
|
||||
/// ```
|
||||
#[inline]
|
||||
fn into(self) -> u16
|
||||
{
|
||||
match self.0 {
|
||||
None => u16::max_value(),
|
||||
Some(n) => n.get() - 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl OptU16
|
||||
{
|
||||
/// Creates an `OptU16` representing `None`.
|
||||
|
@ -385,41 +452,11 @@ impl OptU16
|
|||
/// ```
|
||||
/// use maraiah::durandal::bin::OptU16;
|
||||
///
|
||||
/// assert_eq!(OptU16::none(), OptU16::from_repr(u16::max_value()));
|
||||
/// assert_eq!(OptU16::none(), OptU16::from(u16::max_value()));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub const fn none() -> Self {Self(None)}
|
||||
|
||||
/// Creates an `OptU16` from a `u16`.
|
||||
pub fn from_repr(n: u16) -> Self
|
||||
{
|
||||
if n == u16::max_value() {
|
||||
Self(None)
|
||||
} else {
|
||||
Self(NonZeroU16::new(n + 1))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the `u16` representation.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use maraiah::durandal::bin::OptU16;
|
||||
///
|
||||
/// let u16max = u16::max_value();
|
||||
///
|
||||
/// assert_eq!(OptU16::from_repr(500u16).get_repr(), 500u16);
|
||||
/// assert_eq!(OptU16::from_repr(u16max).get_repr(), u16max);
|
||||
/// assert_eq!(OptU16::from_repr(0u16).get_repr(), 0u16);
|
||||
/// ```
|
||||
pub fn get_repr(self) -> u16
|
||||
{
|
||||
match self.0 {
|
||||
None => u16::max_value(),
|
||||
Some(n) => n.get() - 1,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the `Option` representation.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -427,10 +464,11 @@ impl OptU16
|
|||
/// ```
|
||||
/// use maraiah::durandal::bin::OptU16;
|
||||
///
|
||||
/// assert_eq!(OptU16::from_repr(500u16).get(), Some(500u16));
|
||||
/// assert_eq!(OptU16::from_repr(u16::max_value()).get(), None);
|
||||
/// assert_eq!(OptU16::from_repr(0u16).get(), Some(0u16));
|
||||
/// assert_eq!(OptU16::from(500u16).get(), Some(500u16));
|
||||
/// assert_eq!(OptU16::from(u16::max_value()).get(), None);
|
||||
/// assert_eq!(OptU16::from(0u16).get(), Some(0u16));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn get(self) -> Option<u16>
|
||||
{
|
||||
match self.0 {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/// 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 $t` as well as a function `$t::from_repr` which
|
||||
/// This will generate an `enum $t` as well as a function `$t::try_from` which
|
||||
/// will return `Result<$t, ReprError>`.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -18,43 +18,44 @@
|
|||
/// #[derive(Debug)]
|
||||
/// enum MyEnum: u16
|
||||
/// {
|
||||
/// 0 => Zero,
|
||||
/// 1 => One,
|
||||
/// 2 => Two,
|
||||
/// Zero = 0,
|
||||
/// One = 1,
|
||||
/// Two = 2
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(MyEnum::from_repr(0), Ok(MyEnum::Zero));
|
||||
/// assert_eq!(MyEnum::from_repr(1), Ok(MyEnum::One));
|
||||
/// assert_eq!(MyEnum::from_repr(2), Ok(MyEnum::Two));
|
||||
/// assert_eq!(MyEnum::from_repr(3), Err(ReprError::new(3)));
|
||||
/// assert_eq!(MyEnum::from_repr(4), Err(ReprError::new(4)));
|
||||
/// assert_eq!(MyEnum::from_repr(5), Err(ReprError::new(5)));
|
||||
/// assert_eq!(MyEnum::try_from(0), Ok(MyEnum::Zero));
|
||||
/// assert_eq!(MyEnum::try_from(1), Ok(MyEnum::One));
|
||||
/// assert_eq!(MyEnum::try_from(2), Ok(MyEnum::Two));
|
||||
/// assert_eq!(MyEnum::try_from(3), Err(ReprError::new(3)));
|
||||
/// assert_eq!(MyEnum::try_from(4), Err(ReprError::new(4)));
|
||||
/// assert_eq!(MyEnum::try_from(5), Err(ReprError::new(5)));
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! c_enum
|
||||
{
|
||||
(
|
||||
$(#[$outer:meta])*
|
||||
$vi:vis enum $t:ident: $ti:ty
|
||||
$vi:vis enum $t:ident: $ti:ident
|
||||
{
|
||||
$($(#[$inner:meta])* $va:expr => $en:ident,)+
|
||||
$($en:ident = $va:expr),+ $(,)?
|
||||
}
|
||||
) => {
|
||||
$(#[$outer])*
|
||||
#[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd)]
|
||||
#[repr($ti)]
|
||||
$vi enum $t
|
||||
{
|
||||
$($en,)+
|
||||
$($en = $va,)+
|
||||
}
|
||||
|
||||
impl $t
|
||||
{
|
||||
/// Returns, if representable, the variant of `Self` from `n`.
|
||||
$vi fn from_repr(n: $ti) -> Result<Self, ReprError>
|
||||
$vi fn try_from(n: $ti) -> Result<Self, ReprError>
|
||||
{
|
||||
match n {
|
||||
$($(#[$inner])* $va => Ok($t::$en),)+
|
||||
$($va => Ok($t::$en),)+
|
||||
n => Err(ReprError::new(n))
|
||||
}
|
||||
}
|
||||
|
@ -71,26 +72,26 @@ mod test
|
|||
#[derive(Debug)]
|
||||
enum TestEnum: u16
|
||||
{
|
||||
0 => Zero,
|
||||
1 => One,
|
||||
2 => Two,
|
||||
Zero = 0,
|
||||
One = 1,
|
||||
Two = 2,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn c_enum_should_be_ok()
|
||||
{
|
||||
assert_eq!(TestEnum::from_repr(0), Ok(TestEnum::Zero));
|
||||
assert_eq!(TestEnum::from_repr(1), Ok(TestEnum::One));
|
||||
assert_eq!(TestEnum::from_repr(2), Ok(TestEnum::Two));
|
||||
assert_eq!(TestEnum::from_repr(3), Err(ReprError::new(3)));
|
||||
assert_eq!(TestEnum::from_repr(4), Err(ReprError::new(4)));
|
||||
assert_eq!(TestEnum::from_repr(5), Err(ReprError::new(5)));
|
||||
assert_eq!(TestEnum::try_from(0), Ok(TestEnum::Zero));
|
||||
assert_eq!(TestEnum::try_from(1), Ok(TestEnum::One));
|
||||
assert_eq!(TestEnum::try_from(2), Ok(TestEnum::Two));
|
||||
assert_eq!(TestEnum::try_from(3), Err(ReprError::new(3)));
|
||||
assert_eq!(TestEnum::try_from(4), Err(ReprError::new(4)));
|
||||
assert_eq!(TestEnum::try_from(5), Err(ReprError::new(5)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn c_enum_should_error() {TestEnum::from_repr(3).unwrap();}
|
||||
fn c_enum_should_error() {TestEnum::try_from(3).unwrap();}
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -11,10 +11,11 @@ pub fn load_zlib_header(b: &[u8]) -> ResultS<usize>
|
|||
const FDICT: u8 = 0b0010_0000;
|
||||
|
||||
read_data! {
|
||||
2, BE in b =>
|
||||
fcheck = u16[0];
|
||||
cmf = u8[0];
|
||||
flg = u8[1];
|
||||
endian: BIG, buf: b, size: 2, start: 0, data {
|
||||
let fcheck = u16[0];
|
||||
let cmf = u8[0];
|
||||
let flg = u8[1];
|
||||
}
|
||||
}
|
||||
|
||||
let cm = cmf & CM;
|
||||
|
@ -49,10 +50,11 @@ pub fn load_gzip_header(b: &[u8]) -> ResultS<usize>
|
|||
const FRESERVED: u8 = 0xE0;
|
||||
|
||||
read_data! {
|
||||
10, LE in b =>
|
||||
id = u16[0];
|
||||
cm = u8[2];
|
||||
fl = u8[3];
|
||||
endian: LITTLE, buf: b, size: 10, start: 0, data {
|
||||
let id = u16[0];
|
||||
let cm = u8[2];
|
||||
let fl = u8[3];
|
||||
}
|
||||
}
|
||||
|
||||
if id != 0x8B1F || cm != 8 {
|
||||
|
@ -66,10 +68,15 @@ pub fn load_gzip_header(b: &[u8]) -> ResultS<usize>
|
|||
}
|
||||
|
||||
if fl & FEXTRA != 0 {
|
||||
read_data!(p + 2, LE in b => xlen = u16[p] usize;);
|
||||
check_data!(p + 2 + xlen, b);
|
||||
read_data! {
|
||||
endian: LITTLE, buf: b, size: 2, start: p, data {
|
||||
let xlen = u16[0] usize;
|
||||
}
|
||||
}
|
||||
|
||||
p += xlen;
|
||||
p += 2 + xlen;
|
||||
|
||||
check_data!(p, b);
|
||||
}
|
||||
|
||||
if fl & FNAME != 0 {
|
||||
|
@ -81,9 +88,9 @@ pub fn load_gzip_header(b: &[u8]) -> ResultS<usize>
|
|||
}
|
||||
|
||||
if fl & FHCRC != 0 {
|
||||
check_data!(p + 2, b);
|
||||
|
||||
p += 2;
|
||||
|
||||
check_data!(p, b);
|
||||
}
|
||||
|
||||
Ok(p)
|
||||
|
@ -189,8 +196,9 @@ fn stream_literal(v: &mut Vec<u8>, b: &[u8], p: usize) -> ResultS<usize>
|
|||
let mut p = p / 8 + 1;
|
||||
|
||||
read_data! {
|
||||
p + 4, LE in b =>
|
||||
len = u16[p] usize;
|
||||
endian: LITTLE, buf: b, size: 4, start: p, data {
|
||||
let len = u16[0] usize;
|
||||
}
|
||||
}
|
||||
|
||||
p += 4;
|
||||
|
|
|
@ -8,16 +8,15 @@ use bitflags::bitflags;
|
|||
pub fn read_lightfunc(b: &[u8]) -> ResultS<LightFunc>
|
||||
{
|
||||
read_data! {
|
||||
14, BE in b =>
|
||||
ftype = u16[0];
|
||||
prd_nrm = u16[2];
|
||||
prd_dta = u16[4];
|
||||
val_nrm = Fixed[6];
|
||||
val_dta = Fixed[10];
|
||||
endian: BIG, buf: b, size: 14, start: 0, data {
|
||||
let ftype = u16[0] enum LightFuncType;
|
||||
let prd_nrm = u16[2];
|
||||
let prd_dta = u16[4];
|
||||
let val_nrm = Fixed[6];
|
||||
let val_dta = Fixed[10];
|
||||
}
|
||||
}
|
||||
|
||||
let ftype = LightFuncType::from_repr(ftype)?;
|
||||
|
||||
Ok(LightFunc{ftype, prd_nrm, prd_dta, val_nrm, val_dta})
|
||||
}
|
||||
|
||||
|
@ -25,9 +24,10 @@ pub fn read_lightfunc(b: &[u8]) -> ResultS<LightFunc>
|
|||
pub fn read_sidetex(b: &[u8]) -> ResultS<SideTex>
|
||||
{
|
||||
read_data! {
|
||||
6, BE in b =>
|
||||
offs = read_point[0..4];
|
||||
tex_id = OptU16[4];
|
||||
endian: BIG, buf: b, size: 6, start: 0, data {
|
||||
let offs = read_point[0; 4];
|
||||
let tex_id = OptU16[4];
|
||||
}
|
||||
}
|
||||
|
||||
Ok(SideTex{offs, tex_id})
|
||||
|
@ -37,9 +37,10 @@ pub fn read_sidetex(b: &[u8]) -> ResultS<SideTex>
|
|||
pub fn read_point(b: &[u8]) -> ResultS<Point>
|
||||
{
|
||||
read_data! {
|
||||
4, BE in b =>
|
||||
x = Unit[0];
|
||||
y = Unit[2];
|
||||
endian: BIG, buf: b, size: 4, start: 0, data {
|
||||
let x = Unit[0];
|
||||
let y = Unit[2];
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Point{x, y})
|
||||
|
@ -49,20 +50,17 @@ pub fn read_point(b: &[u8]) -> ResultS<Point>
|
|||
pub fn read_minf(b: &[u8]) -> ResultS<Minf>
|
||||
{
|
||||
read_data! {
|
||||
88, BE in b =>
|
||||
texture_id = u16[0];
|
||||
physics_id = u16[2];
|
||||
skypict_id = u16[4];
|
||||
miss_flags = u16[6];
|
||||
envi_flags = u16[8];
|
||||
level_name = mac_roman_cstr[18..84] no_try;
|
||||
entr_flags = u32[84];
|
||||
endian: BIG, buf: b, size: 88, start: 0, data {
|
||||
let texture_id = u16[0];
|
||||
let physics_id = u16[2];
|
||||
let skypict_id = u16[4];
|
||||
let miss_flags = u16[6] flag MsnFlags;
|
||||
let envi_flags = u16[8] flag EnvFlags;
|
||||
let level_name = mac_roman_cstr[18; 66] no_try;
|
||||
let entr_flags = u32[84] flag EntFlags;
|
||||
}
|
||||
}
|
||||
|
||||
let miss_flags = flag_ok!(MsnFlags, miss_flags)?;
|
||||
let envi_flags = flag_ok!(EnvFlags, envi_flags)?;
|
||||
let entr_flags = flag_ok!(EntFlags, entr_flags)?;
|
||||
|
||||
Ok(Minf{texture_id, physics_id, skypict_id, miss_flags, envi_flags,
|
||||
entr_flags, level_name})
|
||||
}
|
||||
|
@ -97,8 +95,9 @@ pub fn read_iidx(b: &[u8]) -> ResultS<(u16, usize)>
|
|||
pub fn read_epnt(b: &[u8]) -> ResultS<(Point, usize)>
|
||||
{
|
||||
read_data! {
|
||||
16, BE in b =>
|
||||
pnt = read_point[6..10];
|
||||
endian: BIG, buf: b, size: 16, start: 0, data {
|
||||
let pnt = read_point[6; 4];
|
||||
}
|
||||
}
|
||||
|
||||
Ok((pnt, 16))
|
||||
|
@ -114,18 +113,17 @@ pub fn read_pnts(b: &[u8]) -> ResultS<(Point, usize)>
|
|||
pub fn read_lins(b: &[u8]) -> ResultS<(Line, usize)>
|
||||
{
|
||||
read_data! {
|
||||
32, BE in b =>
|
||||
pnt_beg = u16[0];
|
||||
pnt_end = u16[2];
|
||||
flags = u16[4];
|
||||
side_fr = OptU16[12];
|
||||
side_bk = OptU16[14];
|
||||
poly_fr = OptU16[16];
|
||||
poly_bk = OptU16[18];
|
||||
endian: BIG, buf: b, size: 32, start: 0, data {
|
||||
let pnt_beg = u16[0];
|
||||
let pnt_end = u16[2];
|
||||
let flags = u16[4] flag LineFlags;
|
||||
let side_fr = OptU16[12];
|
||||
let side_bk = OptU16[14];
|
||||
let poly_fr = OptU16[16];
|
||||
let poly_bk = OptU16[18];
|
||||
}
|
||||
}
|
||||
|
||||
let flags = flag_ok!(LineFlags, flags)?;
|
||||
|
||||
Ok((Line{flags, pnt_beg, pnt_end, side_fr, side_bk, poly_fr, poly_bk}, 32))
|
||||
}
|
||||
|
||||
|
@ -133,26 +131,21 @@ pub fn read_lins(b: &[u8]) -> ResultS<(Line, usize)>
|
|||
pub fn read_sids(b: &[u8]) -> ResultS<(Side, usize)>
|
||||
{
|
||||
read_data! {
|
||||
64, BE in b =>
|
||||
stype = u16[0];
|
||||
flags = u16[2];
|
||||
tex_pri = read_sidetex[4..10];
|
||||
tex_sec = read_sidetex[10..16];
|
||||
tex_tra = read_sidetex[16..22];
|
||||
paneltyp = u16[38];
|
||||
paneldat = i16[40];
|
||||
xfer_pri = u16[42];
|
||||
xfer_sec = u16[44];
|
||||
xfer_tra = u16[46];
|
||||
shade = Fixed[48];
|
||||
endian: BIG, buf: b, size: 64, start: 0, data {
|
||||
let stype = u16[0] enum SideType;
|
||||
let flags = u16[2] flag SideFlags;
|
||||
let tex_pri = read_sidetex[4; 6];
|
||||
let tex_sec = read_sidetex[10; 6];
|
||||
let tex_tra = read_sidetex[16; 6];
|
||||
let paneltyp = u16[38];
|
||||
let paneldat = i16[40];
|
||||
let xfer_pri = u16[42] enum TransferMode;
|
||||
let xfer_sec = u16[44] enum TransferMode;
|
||||
let xfer_tra = u16[46] enum TransferMode;
|
||||
let shade = Fixed[48];
|
||||
}
|
||||
}
|
||||
|
||||
let flags = flag_ok!(SideFlags, flags)?;
|
||||
let xfer_pri = TransferMode::from_repr(xfer_pri)?;
|
||||
let xfer_sec = TransferMode::from_repr(xfer_sec)?;
|
||||
let xfer_tra = TransferMode::from_repr(xfer_tra)?;
|
||||
let stype = SideType::from_repr(stype)?;
|
||||
|
||||
Ok((Side{stype, flags, tex_pri, tex_sec, tex_tra, paneltyp, paneldat,
|
||||
xfer_pri, xfer_sec, xfer_tra, shade}, 64))
|
||||
}
|
||||
|
@ -172,20 +165,18 @@ pub fn read_old_sids(b: &[u8]) -> ResultS<(Side, usize)>
|
|||
fn read_poly_inter(b: &[u8]) -> ResultS<Polygon>
|
||||
{
|
||||
read_data! {
|
||||
128, BE in b =>
|
||||
tex_flr = OptU16[40];
|
||||
tex_cei = OptU16[42];
|
||||
hei_flr = Unit[44];
|
||||
hei_cei = Unit[46];
|
||||
lit_flr = u16[48];
|
||||
lit_cei = u16[50];
|
||||
xfr_flr = u16[64];
|
||||
xfr_cei = u16[66];
|
||||
endian: BIG, buf: b, size: 128, start: 0, data {
|
||||
let tex_flr = OptU16[40];
|
||||
let tex_cei = OptU16[42];
|
||||
let hei_flr = Unit[44];
|
||||
let hei_cei = Unit[46];
|
||||
let lit_flr = u16[48];
|
||||
let lit_cei = u16[50];
|
||||
let xfr_flr = u16[64] enum TransferMode;
|
||||
let xfr_cei = u16[66] enum TransferMode;
|
||||
}
|
||||
}
|
||||
|
||||
let xfr_flr = TransferMode::from_repr(xfr_flr)?;
|
||||
let xfr_cei = TransferMode::from_repr(xfr_cei)?;
|
||||
|
||||
Ok(Polygon{tex_flr, tex_cei, hei_flr, hei_cei, lit_flr, lit_cei, xfr_flr,
|
||||
xfr_cei, ..Default::default()})
|
||||
}
|
||||
|
@ -194,16 +185,17 @@ fn read_poly_inter(b: &[u8]) -> ResultS<Polygon>
|
|||
pub fn read_poly(b: &[u8]) -> ResultS<(Polygon, usize)>
|
||||
{
|
||||
read_data! {
|
||||
128, BE in b =>
|
||||
ptype = u16[0];
|
||||
pdata = u16[4];
|
||||
ori_flr = read_point[108..112];
|
||||
ori_cei = read_point[112..116];
|
||||
med_ind = OptU16[116];
|
||||
med_ctl = u16[118];
|
||||
snd_amb = OptU16[122];
|
||||
snd_ind = u16[120];
|
||||
snd_rnd = OptU16[124];
|
||||
endian: BIG, buf: b, size: 128, start: 0, data {
|
||||
let ptype = u16[0];
|
||||
let pdata = u16[4];
|
||||
let ori_flr = read_point[108; 4];
|
||||
let ori_cei = read_point[112; 4];
|
||||
let med_ind = OptU16[116];
|
||||
let med_ctl = u16[118];
|
||||
let snd_amb = OptU16[122];
|
||||
let snd_ind = u16[120];
|
||||
let snd_rnd = OptU16[124];
|
||||
}
|
||||
}
|
||||
|
||||
let poly = read_poly_inter(b)?;
|
||||
|
@ -217,9 +209,10 @@ pub fn read_poly(b: &[u8]) -> ResultS<(Polygon, usize)>
|
|||
pub fn read_old_poly(b: &[u8]) -> ResultS<(Polygon, usize)>
|
||||
{
|
||||
read_data! {
|
||||
128, BE in b =>
|
||||
ptype = u16[0];
|
||||
pdata = u16[4];
|
||||
endian: BIG, buf: b, size: 128, start: 0, data {
|
||||
let ptype = u16[0];
|
||||
let pdata = u16[4];
|
||||
}
|
||||
}
|
||||
|
||||
let poly = read_poly_inter(b)?;
|
||||
|
@ -232,22 +225,20 @@ pub fn read_old_poly(b: &[u8]) -> ResultS<(Polygon, usize)>
|
|||
pub fn read_lite(b: &[u8]) -> ResultS<(Light, usize)>
|
||||
{
|
||||
read_data! {
|
||||
100, BE in b =>
|
||||
ltype = u16[0];
|
||||
flags = u16[2];
|
||||
phase = i16[4];
|
||||
act_pri = read_lightfunc[6..20];
|
||||
act_sec = read_lightfunc[20..34];
|
||||
act_mid = read_lightfunc[34..48];
|
||||
ina_pri = read_lightfunc[48..62];
|
||||
ina_sec = read_lightfunc[62..76];
|
||||
ina_mid = read_lightfunc[76..90];
|
||||
tag = u16[90];
|
||||
endian: BIG, buf: b, size: 100, start: 0, data {
|
||||
let ltype = u16[0] enum LightType;
|
||||
let flags = u16[2] flag LightFlags;
|
||||
let phase = i16[4];
|
||||
let act_pri = read_lightfunc[6; 14];
|
||||
let act_sec = read_lightfunc[20; 14];
|
||||
let act_mid = read_lightfunc[34; 14];
|
||||
let ina_pri = read_lightfunc[48; 14];
|
||||
let ina_sec = read_lightfunc[62; 14];
|
||||
let ina_mid = read_lightfunc[76; 14];
|
||||
let tag = u16[90];
|
||||
}
|
||||
}
|
||||
|
||||
let flags = flag_ok!(LightFlags, flags)?;
|
||||
let ltype = LightType::from_repr(ltype)?;
|
||||
|
||||
Ok((Light{ltype, flags, phase, act_pri, act_sec, act_mid, ina_pri, ina_sec,
|
||||
ina_mid, tag}, 100))
|
||||
}
|
||||
|
@ -256,13 +247,14 @@ pub fn read_lite(b: &[u8]) -> ResultS<(Light, usize)>
|
|||
pub fn read_old_lite(b: &[u8]) -> ResultS<(Light, usize)>
|
||||
{
|
||||
read_data! {
|
||||
32, BE in b =>
|
||||
ltype = u16[2] usize;
|
||||
mode = u16[4];
|
||||
phase = i16[6];
|
||||
min = Fixed[8];
|
||||
max = Fixed[12];
|
||||
prd = u16[16];
|
||||
endian: BIG, buf: b, size: 32, start: 0, data {
|
||||
let ltype = u16[2] usize;
|
||||
let mode = u16[4];
|
||||
let phase = i16[6];
|
||||
let min = Fixed[8];
|
||||
let max = Fixed[12];
|
||||
let prd = u16[16];
|
||||
}
|
||||
}
|
||||
|
||||
if OLD_LIGHT_DEFINITIONS.len() < ltype {
|
||||
|
@ -299,15 +291,16 @@ pub fn read_old_lite(b: &[u8]) -> ResultS<(Light, usize)>
|
|||
pub fn read_objs(b: &[u8]) -> ResultS<(Object, usize)>
|
||||
{
|
||||
read_data! {
|
||||
16, BE in b =>
|
||||
group = u16[0];
|
||||
index = u16[2];
|
||||
angle = Angle[4];
|
||||
poly = u16[6];
|
||||
pos_x = Unit[8];
|
||||
pos_y = Unit[10];
|
||||
pos_z = Unit[12];
|
||||
flags = u16[14];
|
||||
endian: BIG, buf: b, size: 16, start: 0, data {
|
||||
let group = u16[0];
|
||||
let index = u16[2];
|
||||
let angle = Angle[4];
|
||||
let poly = u16[6];
|
||||
let pos_x = Unit[8];
|
||||
let pos_y = Unit[10];
|
||||
let pos_z = Unit[12];
|
||||
let flags = u16[14];
|
||||
}
|
||||
}
|
||||
|
||||
let bias = flags & 0xF0_00;
|
||||
|
@ -322,13 +315,14 @@ pub fn read_objs(b: &[u8]) -> ResultS<(Object, usize)>
|
|||
pub fn read_plac(b: &[u8]) -> ResultS<(ObjectFreq, usize)>
|
||||
{
|
||||
read_data! {
|
||||
12, BE in b =>
|
||||
flags = u16[0];
|
||||
cnt_ini = u16[2];
|
||||
cnt_min = u16[4];
|
||||
cnt_max = u16[6];
|
||||
cnt_rnd = u16[8];
|
||||
chance = u16[10];
|
||||
endian: BIG, buf: b, size: 12, start: 0, data {
|
||||
let flags = u16[0];
|
||||
let cnt_ini = u16[2];
|
||||
let cnt_min = u16[4];
|
||||
let cnt_max = u16[6];
|
||||
let cnt_rnd = u16[8];
|
||||
let chance = u16[10];
|
||||
}
|
||||
}
|
||||
|
||||
let rnd_loc = flags != 0;
|
||||
|
@ -340,9 +334,10 @@ pub fn read_plac(b: &[u8]) -> ResultS<(ObjectFreq, usize)>
|
|||
pub fn read_ambi(b: &[u8]) -> ResultS<(SoundAmbi, usize)>
|
||||
{
|
||||
read_data! {
|
||||
16, BE in b =>
|
||||
index = u16[2];
|
||||
volume = u16[4];
|
||||
endian: BIG, buf: b, size: 16, start: 0, data {
|
||||
let index = u16[2];
|
||||
let volume = u16[4];
|
||||
}
|
||||
}
|
||||
|
||||
Ok((SoundAmbi{index, volume}, 16))
|
||||
|
@ -352,17 +347,18 @@ pub fn read_ambi(b: &[u8]) -> ResultS<(SoundAmbi, usize)>
|
|||
pub fn read_bonk(b: &[u8]) -> ResultS<(SoundRand, usize)>
|
||||
{
|
||||
read_data! {
|
||||
32, BE in b =>
|
||||
flags = u16[0];
|
||||
index = u16[2];
|
||||
vol_nrm = u16[4];
|
||||
vol_dta = u16[6];
|
||||
prd_nrm = u16[8];
|
||||
prd_dta = u16[10];
|
||||
yaw_nrm = Angle[12];
|
||||
yaw_dta = Angle[14];
|
||||
pit_nrm = Fixed[16];
|
||||
pit_dta = Fixed[20];
|
||||
endian: BIG, buf: b, size: 32, start: 0, data {
|
||||
let flags = u16[0];
|
||||
let index = u16[2];
|
||||
let vol_nrm = u16[4];
|
||||
let vol_dta = u16[6];
|
||||
let prd_nrm = u16[8];
|
||||
let prd_dta = u16[10];
|
||||
let yaw_nrm = Angle[12];
|
||||
let yaw_dta = Angle[14];
|
||||
let pit_nrm = Fixed[16];
|
||||
let pit_dta = Fixed[20];
|
||||
}
|
||||
}
|
||||
|
||||
let no_dir = flags != 0;
|
||||
|
@ -375,23 +371,22 @@ pub fn read_bonk(b: &[u8]) -> ResultS<(SoundRand, usize)>
|
|||
pub fn read_medi(b: &[u8]) -> ResultS<(Media, usize)>
|
||||
{
|
||||
read_data! {
|
||||
32, BE in b =>
|
||||
mtype = u16[0];
|
||||
flags = u16[2];
|
||||
control = u16[4];
|
||||
dir = Angle[6];
|
||||
mag = Unit[8];
|
||||
hei_lo = Unit[10];
|
||||
hei_hi = Unit[12];
|
||||
orig = read_point[14..18];
|
||||
hei_nrm = Unit[18];
|
||||
min_lt = Fixed[20];
|
||||
texture = OptU16[24];
|
||||
xfer = u16[26];
|
||||
endian: BIG, buf: b, size: 32, start: 0, data {
|
||||
let mtype = u16[0] enum MediaType;
|
||||
let flags = u16[2];
|
||||
let control = u16[4];
|
||||
let dir = Angle[6];
|
||||
let mag = Unit[8];
|
||||
let hei_lo = Unit[10];
|
||||
let hei_hi = Unit[12];
|
||||
let orig = read_point[14; 4];
|
||||
let hei_nrm = Unit[18];
|
||||
let min_lt = Fixed[20];
|
||||
let texture = OptU16[24];
|
||||
let xfer = u16[26] enum TransferMode;
|
||||
}
|
||||
}
|
||||
|
||||
let mtype = MediaType::from_repr(mtype)?;
|
||||
let xfer = TransferMode::from_repr(xfer)?;
|
||||
let flr_obs = flags != 0;
|
||||
|
||||
Ok((Media{mtype, flr_obs, control, dir, mag, hei_lo, hei_hi, orig, hei_nrm,
|
||||
|
@ -402,19 +397,18 @@ pub fn read_medi(b: &[u8]) -> ResultS<(Media, usize)>
|
|||
pub fn read_plat(b: &[u8]) -> ResultS<(Platform, usize)>
|
||||
{
|
||||
read_data! {
|
||||
32, BE in b =>
|
||||
ptype = u16[0];
|
||||
speed = u16[2];
|
||||
delay = u16[4];
|
||||
hei_max = Unit[6];
|
||||
hei_min = Unit[8];
|
||||
flags = u32[10];
|
||||
index = u16[14];
|
||||
tag = u16[16];
|
||||
endian: BIG, buf: b, size: 32, start: 0, data {
|
||||
let ptype = u16[0];
|
||||
let speed = u16[2];
|
||||
let delay = u16[4];
|
||||
let hei_max = Unit[6];
|
||||
let hei_min = Unit[8];
|
||||
let flags = u32[10] flag PlatformFlags;
|
||||
let index = u16[14];
|
||||
let tag = u16[16];
|
||||
}
|
||||
}
|
||||
|
||||
let flags = flag_ok!(PlatformFlags, flags)?;
|
||||
|
||||
Ok((Platform{ptype, speed, delay, hei_min, hei_max, flags, index, tag}, 32))
|
||||
}
|
||||
|
||||
|
@ -422,10 +416,11 @@ pub fn read_plat(b: &[u8]) -> ResultS<(Platform, usize)>
|
|||
pub fn read_note(b: &[u8]) -> ResultS<(Note, usize)>
|
||||
{
|
||||
read_data! {
|
||||
72, BE in b =>
|
||||
pos = read_point[2..6];
|
||||
poly = u16[6];
|
||||
text = mac_roman_cstr[8..72] no_try;
|
||||
endian: BIG, buf: b, size: 72, start: 0, data {
|
||||
let pos = read_point[2; 4];
|
||||
let poly = u16[6];
|
||||
let text = mac_roman_cstr[8; 64] no_try;
|
||||
}
|
||||
}
|
||||
|
||||
Ok((Note{pos, poly, text}, 72))
|
||||
|
@ -908,11 +903,11 @@ c_enum! {
|
|||
#[derive(Debug)]
|
||||
pub enum SideType: u16
|
||||
{
|
||||
0 => Full,
|
||||
1 => High,
|
||||
2 => Low,
|
||||
3 => Composite,
|
||||
4 => Split,
|
||||
Full = 0,
|
||||
High = 1,
|
||||
Low = 2,
|
||||
Composite = 3,
|
||||
Split = 4,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -922,12 +917,12 @@ c_enum! {
|
|||
#[derive(Debug)]
|
||||
pub enum LightFuncType: u16
|
||||
{
|
||||
0 => Constant,
|
||||
1 => Linear,
|
||||
2 => Smooth,
|
||||
3 => Flicker,
|
||||
4 => Random,
|
||||
5 => Fluorescent,
|
||||
Constant = 0,
|
||||
Linear = 1,
|
||||
Smooth = 2,
|
||||
Flicker = 3,
|
||||
Random = 4,
|
||||
Fluorescent = 5,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -937,9 +932,9 @@ c_enum! {
|
|||
#[derive(Debug)]
|
||||
pub enum LightType: u16
|
||||
{
|
||||
0 => Normal,
|
||||
1 => Strobe,
|
||||
2 => Media,
|
||||
Normal = 0,
|
||||
Strobe = 1,
|
||||
Media = 2,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -949,10 +944,10 @@ c_enum! {
|
|||
#[derive(Debug)]
|
||||
pub enum MediaType: u16
|
||||
{
|
||||
0 => Water,
|
||||
1 => Lava,
|
||||
2 => Goo,
|
||||
3 => Sewage,
|
||||
Water = 0,
|
||||
Lava = 1,
|
||||
Goo = 2,
|
||||
Sewage = 3,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,33 +7,34 @@ use bitflags::bitflags;
|
|||
pub fn read_pxpx(b: &[u8]) -> ResultS<(Physics, usize)>
|
||||
{
|
||||
read_data! {
|
||||
104, BE in b =>
|
||||
vel_fwd = Fixed[0];
|
||||
vel_bkw = Fixed[4];
|
||||
vel_prp = Fixed[8];
|
||||
acc_nrm = Fixed[12];
|
||||
dec_nrm = Fixed[16];
|
||||
dec_air = Fixed[20];
|
||||
acc_grv = Fixed[24];
|
||||
acc_cli = Fixed[28];
|
||||
vel_trm = Fixed[32];
|
||||
dec_ext = Fixed[36];
|
||||
acc_ang = Fixed[40];
|
||||
dec_ang = Fixed[44];
|
||||
vel_ang = Fixed[48];
|
||||
vel_rec = Fixed[52];
|
||||
fng_vel = Fixed[56];
|
||||
fng_max = Fixed[60];
|
||||
ele_max = Fixed[64];
|
||||
dec_xng = Fixed[68];
|
||||
stp_dta = Fixed[72];
|
||||
stp_amp = Fixed[76];
|
||||
ply_rad = Fixed[80];
|
||||
ply_hei = Fixed[84];
|
||||
ply_dhi = Fixed[88];
|
||||
ply_cam = Fixed[92];
|
||||
ply_spl = Fixed[96];
|
||||
ply_hcm = Fixed[100];
|
||||
endian: BIG, buf: b, size: 104, start: 0, data {
|
||||
let vel_fwd = Fixed[0];
|
||||
let vel_bkw = Fixed[4];
|
||||
let vel_prp = Fixed[8];
|
||||
let acc_nrm = Fixed[12];
|
||||
let dec_nrm = Fixed[16];
|
||||
let dec_air = Fixed[20];
|
||||
let acc_grv = Fixed[24];
|
||||
let acc_cli = Fixed[28];
|
||||
let vel_trm = Fixed[32];
|
||||
let dec_ext = Fixed[36];
|
||||
let acc_ang = Fixed[40];
|
||||
let dec_ang = Fixed[44];
|
||||
let vel_ang = Fixed[48];
|
||||
let vel_rec = Fixed[52];
|
||||
let fng_vel = Fixed[56];
|
||||
let fng_max = Fixed[60];
|
||||
let ele_max = Fixed[64];
|
||||
let dec_xng = Fixed[68];
|
||||
let stp_dta = Fixed[72];
|
||||
let stp_amp = Fixed[76];
|
||||
let ply_rad = Fixed[80];
|
||||
let ply_hei = Fixed[84];
|
||||
let ply_dhi = Fixed[88];
|
||||
let ply_cam = Fixed[92];
|
||||
let ply_spl = Fixed[96];
|
||||
let ply_hcm = Fixed[100];
|
||||
}
|
||||
}
|
||||
|
||||
Ok((Physics{acc_ang, acc_cli, acc_grv, acc_nrm, dec_air, dec_ang, dec_ext,
|
||||
|
@ -46,17 +47,16 @@ pub fn read_pxpx(b: &[u8]) -> ResultS<(Physics, usize)>
|
|||
pub fn read_fxpx(b: &[u8]) -> ResultS<(Effect, usize)>
|
||||
{
|
||||
read_data! {
|
||||
14, BE in b =>
|
||||
collection = u16[0];
|
||||
shape = u16[2];
|
||||
pitch = Fixed[4];
|
||||
flags = u16[8];
|
||||
delay = OptU16[10];
|
||||
delay_snd = OptU16[12];
|
||||
endian: BIG, buf: b, size: 14, start: 0, data {
|
||||
let collection = u16[0];
|
||||
let shape = u16[2];
|
||||
let pitch = Fixed[4];
|
||||
let flags = u16[8] flag EffectFlags;
|
||||
let delay = OptU16[10];
|
||||
let delay_snd = OptU16[12];
|
||||
}
|
||||
}
|
||||
|
||||
let flags = flag_ok!(EffectFlags, flags)?;
|
||||
|
||||
Ok((Effect{collection, shape, pitch, flags, delay, delay_snd}, 14))
|
||||
}
|
||||
|
||||
|
@ -64,37 +64,35 @@ pub fn read_fxpx(b: &[u8]) -> ResultS<(Effect, usize)>
|
|||
pub fn read_wppx(b: &[u8]) -> ResultS<(Weapon, usize)>
|
||||
{
|
||||
read_data! {
|
||||
134, BE in b =>
|
||||
typ_item = u16[0];
|
||||
typ_powerup = OptU16[2];
|
||||
typ_weapon = u16[4];
|
||||
flags = u16[6];
|
||||
lit_value = Fixed[8];
|
||||
lit_decay = u16[12];
|
||||
hei_idle = Fixed[14];
|
||||
amp_bob = Fixed[18];
|
||||
hei_kick = Fixed[22];
|
||||
hei_reload = Fixed[26];
|
||||
wid_idle = Fixed[30];
|
||||
amp_horz = Fixed[34];
|
||||
collection = u16[38];
|
||||
frm_idle = u16[40];
|
||||
frm_firing = u16[42];
|
||||
frm_reload = OptU16[44];
|
||||
frm_charge = OptU16[48];
|
||||
frm_charged = OptU16[50];
|
||||
tic_ready = u16[52];
|
||||
tic_load_beg = u16[54];
|
||||
tic_load_mid = u16[56];
|
||||
tic_load_end = u16[58];
|
||||
tic_powerup = u16[60];
|
||||
trig_pri = read_trigger[62..98];
|
||||
trig_sec = read_trigger[98..134];
|
||||
endian: BIG, buf: b, size: 134, start: 0, data {
|
||||
let typ_item = u16[0];
|
||||
let typ_powerup = OptU16[2];
|
||||
let typ_weapon = u16[4] enum WeaponType;
|
||||
let flags = u16[6] flag WeaponFlags;
|
||||
let lit_value = Fixed[8];
|
||||
let lit_decay = u16[12];
|
||||
let hei_idle = Fixed[14];
|
||||
let amp_bob = Fixed[18];
|
||||
let hei_kick = Fixed[22];
|
||||
let hei_reload = Fixed[26];
|
||||
let wid_idle = Fixed[30];
|
||||
let amp_horz = Fixed[34];
|
||||
let collection = u16[38];
|
||||
let frm_idle = u16[40];
|
||||
let frm_firing = u16[42];
|
||||
let frm_reload = OptU16[44];
|
||||
let frm_charge = OptU16[48];
|
||||
let frm_charged = OptU16[50];
|
||||
let tic_ready = u16[52];
|
||||
let tic_load_beg = u16[54];
|
||||
let tic_load_mid = u16[56];
|
||||
let tic_load_end = u16[58];
|
||||
let tic_powerup = u16[60];
|
||||
let trig_pri = read_trigger[62; 36];
|
||||
let trig_sec = read_trigger[98; 36];
|
||||
}
|
||||
}
|
||||
|
||||
let typ_weapon = WeaponType::from_repr(typ_weapon)?;
|
||||
let flags = flag_ok!(WeaponFlags, flags)?;
|
||||
|
||||
Ok((Weapon{amp_bob, amp_horz, collection, flags, frm_charge, frm_charged,
|
||||
frm_firing, frm_idle, frm_reload, hei_idle, hei_kick, hei_reload,
|
||||
lit_decay, lit_value, tic_load_beg, tic_load_end, tic_load_mid,
|
||||
|
@ -106,28 +104,27 @@ pub fn read_wppx(b: &[u8]) -> ResultS<(Weapon, usize)>
|
|||
pub fn read_prpx(b: &[u8]) -> ResultS<(Projectile, usize)>
|
||||
{
|
||||
read_data! {
|
||||
48, BE in b =>
|
||||
collection = OptU16[0];
|
||||
shape = u16[2];
|
||||
fxt_explode = OptU16[4];
|
||||
fxt_exp_media = OptU16[6];
|
||||
fxt_trail = OptU16[8];
|
||||
tic_trail = u16[10];
|
||||
max_trail = OptU16[12];
|
||||
typ_media = OptU16[14];
|
||||
radius = Unit[16];
|
||||
dmg_rad = Unit[18];
|
||||
dmg_def = read_damage[20..32];
|
||||
flags = u32[32];
|
||||
speed = Unit[36];
|
||||
range = Unit[38];
|
||||
snd_pitch = Fixed[40];
|
||||
snd_fly = OptU16[44];
|
||||
snd_bounce = OptU16[46];
|
||||
endian: BIG, buf: b, size: 48, start: 0, data {
|
||||
let collection = OptU16[0];
|
||||
let shape = u16[2];
|
||||
let fxt_explode = OptU16[4];
|
||||
let fxt_exp_media = OptU16[6];
|
||||
let fxt_trail = OptU16[8];
|
||||
let tic_trail = u16[10];
|
||||
let max_trail = OptU16[12];
|
||||
let typ_media = OptU16[14];
|
||||
let radius = Unit[16];
|
||||
let dmg_rad = Unit[18];
|
||||
let dmg_def = read_damage[20; 12];
|
||||
let flags = u32[32] flag ProjectileFlags;
|
||||
let speed = Unit[36];
|
||||
let range = Unit[38];
|
||||
let snd_pitch = Fixed[40];
|
||||
let snd_fly = OptU16[44];
|
||||
let snd_bounce = OptU16[46];
|
||||
}
|
||||
}
|
||||
|
||||
let flags = flag_ok!(ProjectileFlags, flags)?;
|
||||
|
||||
Ok((Projectile{collection, shape, fxt_explode, fxt_exp_media, fxt_trail,
|
||||
tic_trail, max_trail, typ_media, radius, dmg_rad, dmg_def,
|
||||
flags, speed, range, snd_pitch, snd_fly, snd_bounce}, 48))
|
||||
|
@ -137,67 +134,64 @@ pub fn read_prpx(b: &[u8]) -> ResultS<(Projectile, usize)>
|
|||
pub fn read_mnpx(b: &[u8]) -> ResultS<(Monster, usize)>
|
||||
{
|
||||
read_data! {
|
||||
156, BE in b =>
|
||||
collection = u16[0];
|
||||
vitality = u16[2];
|
||||
dty_immune = u32[4];
|
||||
dty_weak = u32[8];
|
||||
flags = u32[12];
|
||||
cls_self = u32[16];
|
||||
cls_friend = u32[20];
|
||||
cls_enemy = u32[24];
|
||||
snd_pitch = Fixed[28];
|
||||
snd_see_enemy = OptU16[32];
|
||||
snd_see_friend = OptU16[34];
|
||||
snd_seeclear = OptU16[36];
|
||||
snd_kill = OptU16[38];
|
||||
snd_apologize = OptU16[40];
|
||||
snd_amicide = OptU16[42];
|
||||
snd_flaming = OptU16[44];
|
||||
snd_active = OptU16[46];
|
||||
snd_active_mask = u16[48];
|
||||
typ_item = OptU16[50];
|
||||
radius = Unit[52];
|
||||
height = Unit[54];
|
||||
height_hover = Unit[56];
|
||||
ledge_min = Unit[58];
|
||||
ledge_max = Unit[60];
|
||||
ext_vel_scale = Fixed[62];
|
||||
fxt_impact = OptU16[66];
|
||||
fxt_impact_melee = OptU16[68];
|
||||
fxt_trail = OptU16[70];
|
||||
half_fov_horz = u16[72];
|
||||
half_fov_vert = u16[74];
|
||||
view_range = Unit[76];
|
||||
view_range_dark = Unit[78];
|
||||
intelligence = u16[80];
|
||||
speed = u16[82];
|
||||
gravity = u16[84];
|
||||
vel_terminal = u16[86];
|
||||
door_try_mask = u16[88];
|
||||
expl_radius = OptU16[90];
|
||||
expl_damage = read_damage[92..104];
|
||||
seq_hit = OptU16[104];
|
||||
seq_dying_hard = OptU16[106];
|
||||
seq_dying_soft = OptU16[108];
|
||||
seq_dead_hard = OptU16[110];
|
||||
seq_dead_soft = OptU16[112];
|
||||
seq_standing = u16[114];
|
||||
seq_moving = u16[116];
|
||||
seq_tele_in = OptU16[118];
|
||||
seq_tele_out = OptU16[120];
|
||||
atk_frequency = u16[122];
|
||||
atk_melee = read_attack[124..140];
|
||||
atk_range = read_attack[140..156];
|
||||
endian: BIG, buf: b, size: 156, start: 0, data {
|
||||
let collection = u16[0];
|
||||
let vitality = u16[2];
|
||||
let dty_immune = u32[4] flag DamageTypeFlags;
|
||||
let dty_weak = u32[8] flag DamageTypeFlags;
|
||||
let flags = u32[12] flag MonsterFlags;
|
||||
let cls_self = u32[16] flag MonsterClass;
|
||||
let cls_friend = u32[20];
|
||||
let cls_enemy = u32[24];
|
||||
let snd_pitch = Fixed[28];
|
||||
let snd_see_enemy = OptU16[32];
|
||||
let snd_see_friend = OptU16[34];
|
||||
let snd_seeclear = OptU16[36];
|
||||
let snd_kill = OptU16[38];
|
||||
let snd_apologize = OptU16[40];
|
||||
let snd_amicide = OptU16[42];
|
||||
let snd_flaming = OptU16[44];
|
||||
let snd_active = OptU16[46];
|
||||
let snd_active_mask = u16[48];
|
||||
let typ_item = OptU16[50];
|
||||
let radius = Unit[52];
|
||||
let height = Unit[54];
|
||||
let height_hover = Unit[56];
|
||||
let ledge_min = Unit[58];
|
||||
let ledge_max = Unit[60];
|
||||
let ext_vel_scale = Fixed[62];
|
||||
let fxt_impact = OptU16[66];
|
||||
let fxt_impact_melee = OptU16[68];
|
||||
let fxt_trail = OptU16[70];
|
||||
let half_fov_horz = u16[72];
|
||||
let half_fov_vert = u16[74];
|
||||
let view_range = Unit[76];
|
||||
let view_range_dark = Unit[78];
|
||||
let intelligence = u16[80];
|
||||
let speed = u16[82];
|
||||
let gravity = u16[84];
|
||||
let vel_terminal = u16[86];
|
||||
let door_try_mask = u16[88];
|
||||
let expl_radius = OptU16[90];
|
||||
let expl_damage = read_damage[92; 12];
|
||||
let seq_hit = OptU16[104];
|
||||
let seq_dying_hard = OptU16[106];
|
||||
let seq_dying_soft = OptU16[108];
|
||||
let seq_dead_hard = OptU16[110];
|
||||
let seq_dead_soft = OptU16[112];
|
||||
let seq_standing = u16[114];
|
||||
let seq_moving = u16[116];
|
||||
let seq_tele_in = OptU16[118];
|
||||
let seq_tele_out = OptU16[120];
|
||||
let atk_frequency = u16[122];
|
||||
let atk_melee = read_attack[124; 16];
|
||||
let atk_range = read_attack[140; 16];
|
||||
}
|
||||
}
|
||||
|
||||
// friend and enemy fields MUST truncate because the original source code
|
||||
// used `-1` to represent "all classes" which should be invalid normally
|
||||
|
||||
let dty_immune = flag_ok!(DamageTypeFlags, dty_immune)?;
|
||||
let dty_weak = flag_ok!(DamageTypeFlags, dty_weak)?;
|
||||
let flags = flag_ok!(MonsterFlags, flags)?;
|
||||
let cls_self = flag_ok!(MonsterClass, cls_self)?;
|
||||
let cls_friend = MonsterClass::from_bits_truncate(cls_friend);
|
||||
let cls_enemy = MonsterClass::from_bits_truncate(cls_enemy);
|
||||
|
||||
|
@ -218,29 +212,28 @@ pub fn read_mnpx(b: &[u8]) -> ResultS<(Monster, usize)>
|
|||
fn read_trigger(b: &[u8]) -> ResultS<Trigger>
|
||||
{
|
||||
read_data! {
|
||||
36, BE in b =>
|
||||
magazine = u16[0];
|
||||
typ_ammo = OptU16[2];
|
||||
tic_round = OptU16[4];
|
||||
tic_recover = u16[6];
|
||||
tic_charge = u16[8];
|
||||
recoil = Unit[10];
|
||||
snd_fire = OptU16[12];
|
||||
snd_click = OptU16[14];
|
||||
snd_charge = OptU16[16];
|
||||
snd_casing = OptU16[18];
|
||||
snd_reload = OptU16[20];
|
||||
snd_charged = OptU16[22];
|
||||
typ_proj = u16[24];
|
||||
theta = u16[26];
|
||||
dx = i16[28];
|
||||
dz = i16[30];
|
||||
typ_casing = u16[32];
|
||||
burst = u16[34];
|
||||
endian: BIG, buf: b, size: 36, start: 0, data {
|
||||
let magazine = u16[0];
|
||||
let typ_ammo = OptU16[2];
|
||||
let tic_round = OptU16[4];
|
||||
let tic_recover = u16[6];
|
||||
let tic_charge = u16[8];
|
||||
let recoil = Unit[10];
|
||||
let snd_fire = OptU16[12];
|
||||
let snd_click = OptU16[14];
|
||||
let snd_charge = OptU16[16];
|
||||
let snd_casing = OptU16[18];
|
||||
let snd_reload = OptU16[20];
|
||||
let snd_charged = OptU16[22];
|
||||
let typ_proj = u16[24];
|
||||
let theta = u16[26];
|
||||
let dx = i16[28];
|
||||
let dz = i16[30];
|
||||
let typ_casing = u16[32] enum CasingType;
|
||||
let burst = u16[34];
|
||||
}
|
||||
}
|
||||
|
||||
let typ_casing = CasingType::from_repr(typ_casing)?;
|
||||
|
||||
Ok(Trigger{burst, dx, dz, magazine, recoil, snd_casing, snd_charge,
|
||||
snd_charged, snd_click, snd_fire, snd_reload, theta, tic_charge,
|
||||
tic_recover, tic_round, typ_ammo, typ_casing, typ_proj})
|
||||
|
@ -250,15 +243,15 @@ fn read_trigger(b: &[u8]) -> ResultS<Trigger>
|
|||
fn read_damage(b: &[u8]) -> ResultS<Damage>
|
||||
{
|
||||
read_data! {
|
||||
12, BE in b =>
|
||||
dtype = u16[0];
|
||||
flags = u16[2];
|
||||
dmg_base = u16[4];
|
||||
dmg_rand = u16[6];
|
||||
scale = Fixed[8];
|
||||
endian: BIG, buf: b, size: 12, start: 0, data {
|
||||
let dtype = u16[0] enum DamageType;
|
||||
let flags = u16[2];
|
||||
let dmg_base = u16[4];
|
||||
let dmg_rand = u16[6];
|
||||
let scale = Fixed[8];
|
||||
}
|
||||
}
|
||||
|
||||
let dtype = DamageType::from_repr(dtype)?;
|
||||
let alien = flags != 0;
|
||||
|
||||
Ok(Damage{dtype, alien, dmg_base, dmg_rand, scale})
|
||||
|
@ -268,15 +261,16 @@ fn read_damage(b: &[u8]) -> ResultS<Damage>
|
|||
fn read_attack(b: &[u8]) -> ResultS<Attack>
|
||||
{
|
||||
read_data! {
|
||||
16, BE in b =>
|
||||
ptype = OptU16[0];
|
||||
rep = u16[2];
|
||||
error = Angle[4];
|
||||
range = Unit[6];
|
||||
shape = u16[8];
|
||||
ofs_x = Unit[10];
|
||||
ofs_y = Unit[12];
|
||||
ofs_z = Unit[14];
|
||||
endian: BIG, buf: b, size: 16, start: 0, data {
|
||||
let ptype = OptU16[0];
|
||||
let rep = u16[2];
|
||||
let error = Angle[4];
|
||||
let range = Unit[6];
|
||||
let shape = u16[8];
|
||||
let ofs_x = Unit[10];
|
||||
let ofs_y = Unit[12];
|
||||
let ofs_z = Unit[14];
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Attack{ptype, rep, error, range, shape, ofs_x, ofs_y, ofs_z})
|
||||
|
@ -653,12 +647,12 @@ c_enum! {
|
|||
#[derive(Debug)]
|
||||
pub enum CasingType: u16
|
||||
{
|
||||
0 => Rifle,
|
||||
1 => Pistol,
|
||||
2 => PistolLeft,
|
||||
3 => PistolRight,
|
||||
4 => SMG,
|
||||
0xFFFF => None,
|
||||
Rifle = 0,
|
||||
Pistol = 1,
|
||||
PistolLeft = 2,
|
||||
PistolRight = 3,
|
||||
SMG = 4,
|
||||
None = 0xFFFF,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -668,11 +662,11 @@ c_enum! {
|
|||
#[derive(Debug)]
|
||||
pub enum WeaponType: u16
|
||||
{
|
||||
0 => Melee,
|
||||
1 => Normal,
|
||||
2 => DualFunc,
|
||||
3 => DualPistol,
|
||||
4 => Multipurpose,
|
||||
Melee = 0,
|
||||
Normal = 1,
|
||||
DualFunc = 2,
|
||||
DualPistol = 3,
|
||||
Multipurpose = 4,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -682,31 +676,31 @@ c_enum! {
|
|||
#[derive(Debug)]
|
||||
pub enum DamageType: u16
|
||||
{
|
||||
0 => Explosion,
|
||||
1 => ElectricalStaff,
|
||||
2 => Projectile,
|
||||
3 => Absorbed,
|
||||
4 => Flame,
|
||||
5 => HoundClaws,
|
||||
6 => AlienProjectile,
|
||||
7 => HulkSlap,
|
||||
8 => CompilerBolt,
|
||||
9 => FusionBolt,
|
||||
10 => HunterBolt,
|
||||
11 => Fist,
|
||||
12 => Teleporter,
|
||||
13 => Defender,
|
||||
14 => YetiClaws,
|
||||
15 => YetiProjectile,
|
||||
16 => Crushing,
|
||||
17 => Lava,
|
||||
18 => Suffocation,
|
||||
19 => Goo,
|
||||
20 => EnergyDrain,
|
||||
21 => OxygenDrain,
|
||||
22 => HummerBolt,
|
||||
23 => ShotgunProjectile,
|
||||
0xFFFF => None,
|
||||
Explosion = 0,
|
||||
ElectricalStaff = 1,
|
||||
Projectile = 2,
|
||||
Absorbed = 3,
|
||||
Flame = 4,
|
||||
HoundClaws = 5,
|
||||
AlienProjectile = 6,
|
||||
HulkSlap = 7,
|
||||
CompilerBolt = 8,
|
||||
FusionBolt = 9,
|
||||
HunterBolt = 10,
|
||||
Fist = 11,
|
||||
Teleporter = 12,
|
||||
Defender = 13,
|
||||
YetiClaws = 14,
|
||||
YetiProjectile = 15,
|
||||
Crushing = 16,
|
||||
Lava = 17,
|
||||
Suffocation = 18,
|
||||
Goo = 19,
|
||||
EnergyDrain = 20,
|
||||
OxygenDrain = 21,
|
||||
HummerBolt = 22,
|
||||
ShotgunProjectile = 23,
|
||||
None = 0xFFFF,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,19 +10,17 @@ fn read_pm_header<'a>(b: &'a [u8],
|
|||
-> ResultS<(&'a [u8], Header)>
|
||||
{
|
||||
read_data! {
|
||||
36, BE in b =>
|
||||
pt_fl = u16[0];
|
||||
top = u16[2] usize;
|
||||
left = u16[4] usize;
|
||||
bottom = u16[6] usize;
|
||||
right = u16[8] usize;
|
||||
pack_t = u16[12];
|
||||
depth = u16[28];
|
||||
endian: BIG, buf: b, size: 36, start: 0, data {
|
||||
let pt_fl = u16[0];
|
||||
let top = u16[2] usize;
|
||||
let left = u16[4] usize;
|
||||
let bottom = u16[6] usize;
|
||||
let right = u16[8] usize;
|
||||
let pack_t = u16[12] enum PackType;
|
||||
let depth = u16[28] enum Depth;
|
||||
}
|
||||
}
|
||||
|
||||
let pack_t = PackType::from_repr(pack_t)?;
|
||||
let depth = Depth::from_repr(depth)?;
|
||||
|
||||
if pt_fl & 0x8000 == 0 {
|
||||
bail!("PICT1 not supported");
|
||||
}
|
||||
|
@ -153,10 +151,11 @@ fn read_pm_32(mut im: Image8, b: &[u8], hdr: Header) -> ResultS<Image8>
|
|||
}
|
||||
|
||||
read_data! {
|
||||
p + 3, BE in b =>
|
||||
r = u8[p];
|
||||
g = u8[p + 1];
|
||||
b = u8[p + 2];
|
||||
endian: BIG, buf: b, size: 3, start: p, data {
|
||||
let r = u8[0];
|
||||
let g = u8[1];
|
||||
let b = u8[2];
|
||||
}
|
||||
}
|
||||
|
||||
im.cr.push(Color8::new(r, g, b));
|
||||
|
@ -209,9 +208,10 @@ fn read_pm_area(im: Image8, b: &[u8], pack: bool, clip: bool)
|
|||
pub fn load_pict(b: &[u8]) -> ResultS<Image8>
|
||||
{
|
||||
read_data! {
|
||||
10, BE in b =>
|
||||
h = u16[6] usize;
|
||||
w = u16[8] usize;
|
||||
endian: BIG, buf: b, size: 10, start: 0, data {
|
||||
let h = u16[6] usize;
|
||||
let w = u16[8] usize;
|
||||
}
|
||||
}
|
||||
|
||||
if w * h > 16_000_000 {
|
||||
|
@ -224,8 +224,9 @@ pub fn load_pict(b: &[u8]) -> ResultS<Image8>
|
|||
|
||||
while p < b.len() {
|
||||
read_data! {
|
||||
p + 2, BE in b =>
|
||||
op = u16[p];
|
||||
endian: BIG, buf: b, size: 2, start: p, data {
|
||||
let op = u16[0];
|
||||
}
|
||||
}
|
||||
|
||||
p += 2;
|
||||
|
@ -315,9 +316,10 @@ pub fn load_pict(b: &[u8]) -> ResultS<Image8>
|
|||
pub fn get_clut(b: &[u8]) -> ResultS<(Vec<Color8>, usize)>
|
||||
{
|
||||
read_data! {
|
||||
8, BE in b =>
|
||||
dev = u16[4];
|
||||
num = u16[6] usize;
|
||||
endian: BIG, buf: b, size: 8, start: 0, data {
|
||||
let dev = u16[4];
|
||||
let num = u16[6] usize;
|
||||
}
|
||||
}
|
||||
|
||||
let dev = dev & 0x8000 != 0;
|
||||
|
@ -328,11 +330,12 @@ pub fn get_clut(b: &[u8]) -> ResultS<(Vec<Color8>, usize)>
|
|||
|
||||
for i in 0..num {
|
||||
read_data! {
|
||||
p + 8, BE in b =>
|
||||
n = u16[p] usize;
|
||||
r = u8[p + 2];
|
||||
g = u8[p + 4];
|
||||
b = u8[p + 6];
|
||||
endian: BIG, buf: b, size: 8, start: p, data {
|
||||
let n = u16[0] usize;
|
||||
let r = u8[2];
|
||||
let g = u8[4];
|
||||
let b = u8[6];
|
||||
}
|
||||
}
|
||||
|
||||
// with device mapping, we ignore the index entirely
|
||||
|
@ -481,23 +484,23 @@ struct Header
|
|||
c_enum! {
|
||||
enum Depth: u16
|
||||
{
|
||||
1 => Bits1,
|
||||
2 => Bits2,
|
||||
4 => Bits4,
|
||||
8 => Bits8,
|
||||
16 => Bits16,
|
||||
32 => Bits32,
|
||||
Bits1 = 1,
|
||||
Bits2 = 2,
|
||||
Bits4 = 4,
|
||||
Bits8 = 8,
|
||||
Bits16 = 16,
|
||||
Bits32 = 32,
|
||||
}
|
||||
}
|
||||
|
||||
c_enum! {
|
||||
enum PackType: u16
|
||||
{
|
||||
0 => Default,
|
||||
1 => None,
|
||||
2 => NoPad,
|
||||
3 => Rle16,
|
||||
4 => Rle32,
|
||||
Default = 0,
|
||||
None = 1,
|
||||
NoPad = 2,
|
||||
Rle16 = 3,
|
||||
Rle32 = 4,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,12 +8,13 @@ use bitflags::bitflags;
|
|||
fn read_color(b: &[u8], clut: &mut [ColorShp]) -> ResultS<()>
|
||||
{
|
||||
read_data! {
|
||||
8, BE in b =>
|
||||
flag = u8[0];
|
||||
ind = u8[1];
|
||||
r = u16[2];
|
||||
g = u16[4];
|
||||
b = u16[6];
|
||||
endian: BIG, buf: b, size: 8, start: 0, data {
|
||||
let flag = u8[0];
|
||||
let ind = u8[1];
|
||||
let r = u16[2];
|
||||
let g = u16[4];
|
||||
let b = u16[6];
|
||||
}
|
||||
}
|
||||
|
||||
let cr = ok!(clut.get_mut(usize::from(ind)), "bad index")?;
|
||||
|
@ -57,16 +58,16 @@ fn color_tables(b: &[u8],
|
|||
pub fn read_bitmap(b: &[u8]) -> ResultS<Bitmap>
|
||||
{
|
||||
read_data! {
|
||||
26, BE in b =>
|
||||
width = u16[0] usize;
|
||||
height = u16[2] usize;
|
||||
compr = u16[4];
|
||||
flags = u16[6];
|
||||
depth = u16[8];
|
||||
endian: BIG, buf: b, size: 26, start: 0, data {
|
||||
let width = u16[0] usize;
|
||||
let height = u16[2] usize;
|
||||
let compr = u16[4];
|
||||
let flags = u16[6] flag BmpFlags;
|
||||
let depth = u16[8];
|
||||
}
|
||||
}
|
||||
|
||||
let compr = compr == u16::max_value();
|
||||
let flags = flag_ok!(BmpFlags, flags)?;
|
||||
let alpha = flags.contains(BmpFlags::TRANSPARENT);
|
||||
let cmajr = flags.contains(BmpFlags::COLUMN_MAJOR);
|
||||
|
||||
|
@ -84,9 +85,10 @@ pub fn read_bitmap(b: &[u8]) -> ResultS<Bitmap>
|
|||
// compressed scanlines (transparency RLE)
|
||||
for _ in 0..scanlines {
|
||||
read_data! {
|
||||
p + 4, BE in b =>
|
||||
fst = u16[p] usize;
|
||||
lst = u16[p + 2] usize;
|
||||
endian: BIG, buf: b, size: 4, start: p, data {
|
||||
let fst = u16[0] usize;
|
||||
let lst = u16[2] usize;
|
||||
}
|
||||
}
|
||||
|
||||
let end = lst - fst;
|
||||
|
@ -122,20 +124,19 @@ pub fn read_bitmap(b: &[u8]) -> ResultS<Bitmap>
|
|||
pub fn read_frame(b: &[u8]) -> ResultS<Frame>
|
||||
{
|
||||
read_data! {
|
||||
36, BE in b =>
|
||||
flags = u16[0];
|
||||
min_lt = Fixed[2];
|
||||
bmp_ind = u16[6] usize;
|
||||
wrl_l = Unit[16];
|
||||
wrl_r = Unit[18];
|
||||
wrl_t = Unit[20];
|
||||
wrl_b = Unit[22];
|
||||
wrl_x = Unit[24];
|
||||
wrl_y = Unit[26];
|
||||
endian: BIG, buf: b, size: 36, start: 0, data {
|
||||
let flags = u16[0] flag FrameFlags;
|
||||
let min_lt = Fixed[2];
|
||||
let bmp_ind = u16[6] usize;
|
||||
let wrl_l = Unit[16];
|
||||
let wrl_r = Unit[18];
|
||||
let wrl_t = Unit[20];
|
||||
let wrl_b = Unit[22];
|
||||
let wrl_x = Unit[24];
|
||||
let wrl_y = Unit[26];
|
||||
}
|
||||
}
|
||||
|
||||
let flags = flag_ok!(FrameFlags, flags)?;
|
||||
|
||||
Ok(Frame{flags, min_lt, bmp_ind, wrl_l, wrl_r, wrl_t, wrl_b, wrl_x, wrl_y})
|
||||
}
|
||||
|
||||
|
@ -143,23 +144,22 @@ pub fn read_frame(b: &[u8]) -> ResultS<Frame>
|
|||
pub fn read_sequence(b: &[u8]) -> ResultS<Sequence>
|
||||
{
|
||||
read_data! {
|
||||
88, BE in b =>
|
||||
name = u8[4..38] slice;
|
||||
v_type = u16[38];
|
||||
frames = u16[40];
|
||||
ticks = u16[42];
|
||||
key = u16[44];
|
||||
xfer = u16[46];
|
||||
xfer_pd = u16[48];
|
||||
snd_beg = OptU16[50];
|
||||
snd_key = OptU16[52];
|
||||
snd_end = OptU16[54];
|
||||
loop_f = u16[58];
|
||||
endian: BIG, buf: b, size: 88, start: 0, data {
|
||||
let name = u8[4; 34];
|
||||
let v_type = u16[38] enum ViewType;
|
||||
let frames = u16[40];
|
||||
let ticks = u16[42];
|
||||
let key = u16[44];
|
||||
let xfer = u16[46] enum TransferMode;
|
||||
let xfer_pd = u16[48];
|
||||
let snd_beg = OptU16[50];
|
||||
let snd_key = OptU16[52];
|
||||
let snd_end = OptU16[54];
|
||||
let loop_f = u16[58];
|
||||
}
|
||||
}
|
||||
|
||||
let name = mac_roman_conv(ok!(pascal_str(name), "bad string")?);
|
||||
let xfer = TransferMode::from_repr(xfer)?;
|
||||
let v_type = ViewType::from_repr(v_type)?;
|
||||
let name = mac_roman_conv(ok!(pascal_str(name), "bad string")?);
|
||||
|
||||
Ok(Sequence{name, v_type, frames, ticks, key, xfer, xfer_pd, snd_beg,
|
||||
snd_key, snd_end, loop_f})
|
||||
|
@ -169,22 +169,21 @@ pub fn read_sequence(b: &[u8]) -> ResultS<Sequence>
|
|||
pub fn read_collection(b: &[u8]) -> ResultS<Collection>
|
||||
{
|
||||
read_data! {
|
||||
544, BE in b =>
|
||||
version = u16[0];
|
||||
cl_type = u16[2];
|
||||
clr_num = u16[6] usize;
|
||||
tab_num = u16[8] usize;
|
||||
tab_ofs = u32[10] usize;
|
||||
seq_num = u16[14] usize;
|
||||
seq_ofs = u32[16] usize;
|
||||
frm_num = u16[20] usize;
|
||||
frm_ofs = u32[22] usize;
|
||||
bmp_num = u16[26] usize;
|
||||
bmp_ofs = u32[28] usize;
|
||||
endian: BIG, buf: b, size: 544, start: 0, data {
|
||||
let version = u16[0];
|
||||
let cl_type = u16[2] enum CollectionType;
|
||||
let clr_num = u16[6] usize;
|
||||
let tab_num = u16[8] usize;
|
||||
let tab_ofs = u32[10] usize;
|
||||
let seq_num = u16[14] usize;
|
||||
let seq_ofs = u32[16] usize;
|
||||
let frm_num = u16[20] usize;
|
||||
let frm_ofs = u32[22] usize;
|
||||
let bmp_num = u16[26] usize;
|
||||
let bmp_ofs = u32[28] usize;
|
||||
}
|
||||
}
|
||||
|
||||
let cl_type = CollectionType::from_repr(cl_type)?;
|
||||
|
||||
if version != 3 {
|
||||
bail!("invalid collection definition");
|
||||
}
|
||||
|
@ -205,11 +204,12 @@ pub fn read_shapes(b: &[u8]) -> ResultS<Vec<CollectionDef>>
|
|||
|
||||
for _ in 0..32 {
|
||||
read_data! {
|
||||
p + 32, BE in b =>
|
||||
lo_ofs = u32[p + 4] usize;
|
||||
lo_len = u32[p + 8] usize;
|
||||
hi_ofs = u32[p + 12] usize;
|
||||
hi_len = u32[p + 16] usize;
|
||||
endian: BIG, buf: b, size: 32, start: p, data {
|
||||
let lo_ofs = u32[4] usize;
|
||||
let lo_len = u32[8] usize;
|
||||
let hi_ofs = u32[12] usize;
|
||||
let hi_len = u32[16] usize;
|
||||
}
|
||||
}
|
||||
|
||||
let c_lo = if lo_ofs == usize_from_u32(u32::max_value()) {
|
||||
|
@ -478,11 +478,11 @@ c_enum! {
|
|||
#[derive(Debug)]
|
||||
pub enum CollectionType: u16
|
||||
{
|
||||
0 => Unused,
|
||||
1 => Wall,
|
||||
2 => Object,
|
||||
3 => Interface,
|
||||
4 => Scenery,
|
||||
Unused = 0,
|
||||
Wall = 1,
|
||||
Object = 2,
|
||||
Interface = 3,
|
||||
Scenery = 4,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -492,15 +492,15 @@ c_enum! {
|
|||
#[derive(Debug)]
|
||||
pub enum ViewType: u16
|
||||
{
|
||||
1 => Anim,
|
||||
2 => Anim8from2,
|
||||
3 => Anim4from3,
|
||||
4 => Anim4,
|
||||
5 => Anim8from5,
|
||||
8 => Anim8,
|
||||
9 => Anim5from3,
|
||||
10 => Still,
|
||||
11 => Anim5,
|
||||
Anim = 1,
|
||||
Anim8from2 = 2,
|
||||
Anim4from3 = 3,
|
||||
Anim4 = 4,
|
||||
Anim8from5 = 5,
|
||||
Anim8 = 8,
|
||||
Anim5from3 = 9,
|
||||
Still = 10,
|
||||
Anim5 = 11,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,12 +8,13 @@ use std::collections::BTreeMap;
|
|||
pub fn read_sound(b: &[u8]) -> ResultS<Sound16>
|
||||
{
|
||||
read_data! {
|
||||
21, BE in b =>
|
||||
len = u32[4] usize;
|
||||
rate = u16[8];
|
||||
lp_beg = u32[12] usize;
|
||||
lp_end = u32[16] usize;
|
||||
magic = u8[20];
|
||||
endian: BIG, buf: b, size: 21, start: 0, data {
|
||||
let len = u32[4] usize;
|
||||
let rate = u16[8];
|
||||
let lp_beg = u32[12] usize;
|
||||
let lp_end = u32[16] usize;
|
||||
let magic = u8[20];
|
||||
}
|
||||
}
|
||||
|
||||
match magic {
|
||||
|
@ -23,9 +24,10 @@ pub fn read_sound(b: &[u8]) -> ResultS<Sound16>
|
|||
}
|
||||
0xFF => {
|
||||
read_data! {
|
||||
63, BE in b =>
|
||||
len = u32[22] usize;
|
||||
bps = u16[48];
|
||||
endian: BIG, buf: b, size: 42, start: 22, data {
|
||||
let len = u32[0] usize;
|
||||
let bps = u16[26];
|
||||
}
|
||||
}
|
||||
|
||||
match bps {
|
||||
|
@ -48,20 +50,18 @@ pub fn read_sound(b: &[u8]) -> ResultS<Sound16>
|
|||
pub fn read_sound_def(b: &[u8]) -> ResultS<Option<(Vec<usize>, u16, SoundDef)>>
|
||||
{
|
||||
read_data! {
|
||||
64, BE in b =>
|
||||
index = u16[0];
|
||||
volume = u16[2];
|
||||
flags = u16[4];
|
||||
chance = u16[6];
|
||||
pitch_lo = Fixed[8];
|
||||
pitch_hi = Fixed[12];
|
||||
n_sounds = u16[16] usize;
|
||||
grp_ofs = u32[20] usize;
|
||||
endian: BIG, buf: b, size: 64, start: 0, data {
|
||||
let index = u16[0];
|
||||
let volume = u16[2] enum Volume;
|
||||
let flags = u16[4] flag SoundFlags;
|
||||
let chance = u16[6];
|
||||
let pitch_lo = Fixed[8];
|
||||
let pitch_hi = Fixed[12];
|
||||
let n_sounds = u16[16] usize;
|
||||
let grp_ofs = u32[20] usize;
|
||||
}
|
||||
}
|
||||
|
||||
let flags = flag_ok!(SoundFlags, flags)?;
|
||||
let volume = Volume::from_repr(volume)?;
|
||||
|
||||
if index == u16::max_value() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
@ -88,11 +88,12 @@ pub fn read_sound_def(b: &[u8]) -> ResultS<Option<(Vec<usize>, u16, SoundDef)>>
|
|||
pub fn read_sounds(b: &[u8]) -> ResultS<Vec<SoundTable>>
|
||||
{
|
||||
read_data! {
|
||||
260, BE in b =>
|
||||
version = u32[0];
|
||||
magic = u8[4..8] slice;
|
||||
src_num = u16[8] usize;
|
||||
snd_num = u16[10] usize;
|
||||
endian: BIG, buf: b, size: 260, start: 0, data {
|
||||
let version = u32[0];
|
||||
let magic = Ident[4];
|
||||
let src_num = u16[8] usize;
|
||||
let snd_num = u16[10] usize;
|
||||
}
|
||||
}
|
||||
|
||||
if version != 1 || magic != b"snd2" {
|
||||
|
@ -177,9 +178,9 @@ c_enum! {
|
|||
#[derive(Debug)]
|
||||
pub enum Volume: u16
|
||||
{
|
||||
0 => Quiet,
|
||||
1 => Normal,
|
||||
2 => Loud,
|
||||
Quiet = 0,
|
||||
Normal = 1,
|
||||
Loud = 2,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,16 +7,16 @@ use bitflags::bitflags;
|
|||
pub fn read_group(b: &[u8]) -> ResultS<(InterGroup, usize)>
|
||||
{
|
||||
read_data! {
|
||||
12, BE in b =>
|
||||
flags = u16[0];
|
||||
ttype = u16[2];
|
||||
pdata = u16[4];
|
||||
beg = u16[6] usize;
|
||||
len = u16[8] usize;
|
||||
lines = u16[10];
|
||||
endian: BIG, buf: b, size: 12, start: 0, data {
|
||||
let flags = u16[0] flag GroupFlags;
|
||||
let ttype = u16[2];
|
||||
let pdata = u16[4];
|
||||
let beg = u16[6] usize;
|
||||
let len = u16[8] usize;
|
||||
let lines = u16[10];
|
||||
}
|
||||
}
|
||||
|
||||
let flags = flag_ok!(GroupFlags, flags)?;
|
||||
let ttype = match ttype {
|
||||
0 => GroupType::Logon(pdata),
|
||||
1 => GroupType::Unfinished,
|
||||
|
@ -45,10 +45,11 @@ pub fn read_group(b: &[u8]) -> ResultS<(InterGroup, usize)>
|
|||
pub fn read_face(b: &[u8]) -> ResultS<(Face, usize)>
|
||||
{
|
||||
read_data! {
|
||||
6, BE in b =>
|
||||
start = u16[0] usize;
|
||||
face = u16[2];
|
||||
color = u16[4];
|
||||
endian: BIG, buf: b, size: 6, start: 0, data {
|
||||
let start = u16[0] usize;
|
||||
let face = u16[2];
|
||||
let color = u16[4];
|
||||
}
|
||||
}
|
||||
|
||||
Ok((Face{start, face, color}, 6))
|
||||
|
@ -58,12 +59,13 @@ pub fn read_face(b: &[u8]) -> ResultS<(Face, usize)>
|
|||
pub fn read_term(b: &[u8]) -> ResultS<(Terminal, usize)>
|
||||
{
|
||||
read_data! {
|
||||
10, BE in b =>
|
||||
end = u16[0] usize;
|
||||
encoded = u16[2];
|
||||
lines = u16[4];
|
||||
group_n = u16[6] usize;
|
||||
face_n = u16[8] usize;
|
||||
endian: BIG, buf: b, size: 10, start: 0, data {
|
||||
let end = u16[0] usize;
|
||||
let encoded = u16[2];
|
||||
let lines = u16[4];
|
||||
let group_n = u16[6] usize;
|
||||
let face_n = u16[8] usize;
|
||||
}
|
||||
}
|
||||
|
||||
let encoded = encoded != 0;
|
||||
|
|
|
@ -18,9 +18,10 @@ pub fn read_chunks(b: &[u8], old_dat: bool, siz_cnk: usize)
|
|||
|
||||
while p < b.len() {
|
||||
read_data! {
|
||||
p + siz_cnk, BE in b =>
|
||||
iden = Ident[p];
|
||||
size = u32[p + 8] usize;
|
||||
endian: BIG, buf: b, size: siz_cnk, start: p, data {
|
||||
let iden = Ident[0];
|
||||
let size = u32[8] usize;
|
||||
}
|
||||
}
|
||||
|
||||
let beg = p + siz_cnk;
|
||||
|
@ -69,9 +70,10 @@ pub fn read_entries(b: &[u8],
|
|||
-> ResultS<BTreeMap<u16, Entry>>
|
||||
{
|
||||
read_data! {
|
||||
128, BE in b =>
|
||||
dirofs = u32[72] usize;
|
||||
numents = u16[76] usize;
|
||||
endian: BIG, buf: b, size: 128, start: 0, data {
|
||||
let dirofs = u32[72] usize;
|
||||
let numents = u16[76] usize;
|
||||
}
|
||||
}
|
||||
|
||||
let mut entries = BTreeMap::new();
|
||||
|
@ -79,10 +81,11 @@ pub fn read_entries(b: &[u8],
|
|||
|
||||
for i in 0..numents {
|
||||
read_data! {
|
||||
p + siz_ent, BE in b =>
|
||||
offset = u32[p] usize;
|
||||
size = u32[p + 4] usize;
|
||||
index = u16[p + 8];
|
||||
endian: BIG, buf: b, size: siz_ent, start: p, data {
|
||||
let offset = u32[0] usize;
|
||||
let size = u32[4] usize;
|
||||
let index = u16[8];
|
||||
}
|
||||
}
|
||||
|
||||
let index = if old_wad {i as u16} else {index};
|
||||
|
@ -102,17 +105,18 @@ pub fn read_entries(b: &[u8],
|
|||
pub fn read_wad(b: &[u8]) -> ResultS<Wad>
|
||||
{
|
||||
read_data! {
|
||||
128, BE in b =>
|
||||
ver_wad = u16[0];
|
||||
ver_dat = u16[2];
|
||||
name = mac_roman_cstr[4..68] no_try;
|
||||
siz_app = u16[78] usize;
|
||||
siz_wcnk = u16[80] usize;
|
||||
siz_went = u16[82] usize;
|
||||
endian: BIG, buf: b, size: 128, start: 0, data {
|
||||
let ver_wad = u16[0] enum Ver;
|
||||
let ver_dat = u16[2];
|
||||
let name = mac_roman_cstr[4; 64] no_try;
|
||||
let siz_app = u16[78] usize;
|
||||
let siz_wcnk = u16[80] usize;
|
||||
let siz_went = u16[82] usize;
|
||||
}
|
||||
}
|
||||
|
||||
let old_dat = ver_dat == 0;
|
||||
let old_wad = match Ver::from_repr(ver_wad)? {
|
||||
let old_wad = match ver_wad {
|
||||
Ver::Base => true,
|
||||
_ => false,
|
||||
};
|
||||
|
@ -217,10 +221,10 @@ c_enum! {
|
|||
#[derive(Debug)]
|
||||
enum Ver: u16
|
||||
{
|
||||
0 => Base,
|
||||
1 => Dir,
|
||||
2 => Over,
|
||||
4 => Inf,
|
||||
Base = 0,
|
||||
Dir = 1,
|
||||
Over = 2,
|
||||
Inf = 4,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,28 +13,28 @@ c_enum! {
|
|||
#[derive(Debug)]
|
||||
pub enum TransferMode: u16
|
||||
{
|
||||
0 => Normal,
|
||||
1 => FadeBlack,
|
||||
2 => Invisibility,
|
||||
3 => Invisibility2,
|
||||
4 => Pulsate,
|
||||
5 => Wobble,
|
||||
6 => Wobble2,
|
||||
7 => Static,
|
||||
8 => Static2,
|
||||
9 => Sky,
|
||||
10 => Smear,
|
||||
11 => StaticFade,
|
||||
12 => StaticPulse,
|
||||
13 => FoldIn,
|
||||
14 => FoldOut,
|
||||
15 => SlideHorz,
|
||||
16 => SlideHorz2,
|
||||
17 => SlideVert,
|
||||
18 => SlideVert2,
|
||||
19 => Wander,
|
||||
20 => Wander2,
|
||||
21 => BigSky,
|
||||
Normal = 0,
|
||||
FadeBlack = 1,
|
||||
Invisibility = 2,
|
||||
Invisibility2 = 3,
|
||||
Pulsate = 4,
|
||||
Wobble = 5,
|
||||
Wobble2 = 6,
|
||||
Static = 7,
|
||||
Static2 = 8,
|
||||
Sky = 9,
|
||||
Smear = 10,
|
||||
StaticFade = 11,
|
||||
StaticPulse = 12,
|
||||
FoldIn = 13,
|
||||
FoldOut = 14,
|
||||
SlideHorz = 15,
|
||||
SlideHorz2 = 16,
|
||||
SlideVert = 17,
|
||||
SlideVert2 = 18,
|
||||
Wander = 19,
|
||||
Wander2 = 20,
|
||||
BigSky = 21,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
use std::process::Command;
|
||||
|
||||
fn main()
|
||||
fn main() -> std::io::Result<()>
|
||||
{
|
||||
let out_file = std::env::var("OUT_DIR").unwrap();
|
||||
let out_file = format!("--target={}/resources", out_file);
|
||||
|
||||
println!("cargo:rerun-if-changed=data");
|
||||
|
||||
Command::new("glib-compile-resources").arg("data/tycho_res.xml")
|
||||
.arg("--target=data/tycho.res")
|
||||
.status()
|
||||
.unwrap();
|
||||
let o = Command::new("glib-compile-resources").arg("data/resources.xml")
|
||||
.arg(out_file)
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
if !o.status.success() {
|
||||
dbg!(o);
|
||||
Err(std::io::Error::new(std::io::ErrorKind::Other, "failed to compile resources"))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.2 KiB |
|
@ -0,0 +1,15 @@
|
|||
[Icon Theme]
|
||||
Name=hicolor
|
||||
Inherits=HighContrast
|
||||
DisplayDepth=32
|
||||
Directories=48x48/actions,48x48/apps
|
||||
|
||||
[48x48/actions]
|
||||
Size=48
|
||||
Context=Actions
|
||||
Type=Fixed
|
||||
|
||||
[48x48/apps]
|
||||
Size=48
|
||||
Context=Applications
|
||||
Type=Fixed
|
Before Width: | Height: | Size: 226 B |
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 538 B |
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<!-- Toplevel namespace. Contains UI and helpers. -->
|
||||
<gresource prefix="/net/greyserv/maraiah/tycho">
|
||||
<file compressed="true" alias="tycho1.png">data/misc/tycho1.png</file>
|
||||
<file compressed="true" alias="tycho2.png">data/misc/tycho2.png</file>
|
||||
<file compressed="true" alias="css">data/styles.css</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks" alias="ui">data/ui.xml</file>
|
||||
</gresource>
|
||||
<!-- Icons, color. We can't make highcolor yet. -->
|
||||
<gresource prefix="/net/greyserv/maraiah/tycho/icons/48x48/actions">
|
||||
<file compressed="true" alias="tycho-polys.png">data/color/polygons.png</file>
|
||||
<file compressed="true" alias="tycho-lines.png">data/color/lines.png</file>
|
||||
<file compressed="true" alias="tycho-points.png">data/color/points.png</file>
|
||||
</gresource>
|
||||
<gresource prefix="/net/greyserv/maraiah/tycho/icons/48x48/apps">
|
||||
<file compressed="true" alias="tycho-map.png">data/color/map.png</file>
|
||||
</gresource>
|
||||
</gresources>
|
|
@ -0,0 +1 @@
|
|||
/* EOF */
|
|
@ -1,5 +0,0 @@
|
|||
.first-start-window {
|
||||
background-color: #000000;
|
||||
color: #AAAAAA;
|
||||
font: 16px "FixedSys", "Monospace";
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/net/greyserv/maraiah/tycho">
|
||||
<file compressed="true" alias="tycho1">data/tycho1.png</file>
|
||||
<file compressed="true" alias="tycho2">data/tycho2.png</file>
|
||||
<file compressed="true" alias="polys">data/polys.png</file>
|
||||
<file compressed="true" alias="lines">data/lines.png</file>
|
||||
<file compressed="true" alias="points">data/points.png</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks" alias="ui">data/tycho.xml</file>
|
||||
<file compressed="true" alias="css">data/tycho.css</file>
|
||||
</gresource>
|
||||
</gresources>
|
|
@ -98,7 +98,6 @@ Author: Alison Sanderson
|
|||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">The name of the map. Unicode symbols that are supported by the Mac OS Roman encoding are converted automatically when saved.</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
|
@ -110,6 +109,7 @@ Author: Alison Sanderson
|
|||
<object class="GtkEntry" id="ent-map-name">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">The name of the map. Unicode symbols that are supported by the Mac OS Roman encoding are converted automatically when saved.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -144,7 +144,6 @@ Author: Alison Sanderson
|
|||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">The texture collection to use for the map. This is one of five bitmap collections stored in the Shapes file.</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
|
@ -159,6 +158,7 @@ Author: Alison Sanderson
|
|||
<object class="GtkComboBoxText">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">The texture collection to use for the map. This is one of five bitmap collections stored in the Shapes file.</property>
|
||||
<property name="active">0</property>
|
||||
<items>
|
||||
<item translatable="yes">Water</item>
|
||||
|
@ -189,7 +189,6 @@ Author: Alison Sanderson
|
|||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">The sky to display on sides which are marked as "Landscape." This is the sole bitmap of one of four collections in the Shapes file.</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
|
@ -204,6 +203,7 @@ Author: Alison Sanderson
|
|||
<object class="GtkComboBoxText">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">The sky to display on sides which are marked as "Landscape." This is the sole bitmap of one of four collections in the Shapes file.</property>
|
||||
<property name="active">0</property>
|
||||
<items>
|
||||
<item translatable="yes">Lh'owon Day</item>
|
||||
|
@ -627,96 +627,41 @@ Author: Alison Sanderson
|
|||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<object class="GtkAlignment">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="xscale">0</property>
|
||||
<property name="yscale">0</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<object class="GtkAlignment">
|
||||
<object class="GtkSpinButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="xscale">0</property>
|
||||
<property name="yscale">0</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<object class="GtkSpinButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">This field is unused and must be either 0 or 1. It used to be used to give different physics to the map editor and low gravity before it was made into an environment flag.</property>
|
||||
<property name="text" translatable="yes">0</property>
|
||||
<property name="truncate_multiline">True</property>
|
||||
<property name="adjustment">adj-phys-id</property>
|
||||
<property name="snap_to_ticks">True</property>
|
||||
<property name="numeric">True</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Physics ID</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">This field is unused and must be either 0 or 1. It used to be used to give different physics to the map editor and low gravity before it was made into an environment flag.</property>
|
||||
<property name="text" translatable="yes">0</property>
|
||||
<property name="truncate_multiline">True</property>
|
||||
<property name="adjustment">adj-phys-id</property>
|
||||
<property name="snap_to_ticks">True</property>
|
||||
<property name="numeric">True</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">This field overrides the Landscape value, since Marathon 1 used that field for the music number.</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<object class="GtkAlignment">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="xscale">0</property>
|
||||
<property name="yscale">0</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<object class="GtkSpinButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="text" translatable="yes">0</property>
|
||||
<property name="truncate_multiline">True</property>
|
||||
<property name="adjustment">adj-phys-id</property>
|
||||
<property name="snap_to_ticks">True</property>
|
||||
<property name="numeric">True</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Song ID</property>
|
||||
</object>
|
||||
</child>
|
||||
<property name="label" translatable="yes">Physics ID</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
|
@ -734,6 +679,7 @@ Author: Alison Sanderson
|
|||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">These flags were added by Aleph One but are hidden and probably not meant to be used.</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
|
@ -799,7 +745,7 @@ Author: Alison Sanderson
|
|||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Aleph Mission Flags</property>
|
||||
<property name="label" translatable="yes">Hidden Mission Flags</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -813,6 +759,7 @@ Author: Alison Sanderson
|
|||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">These flags were added by Aleph One but are hidden and probably not meant to be used.</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
|
@ -938,7 +885,7 @@ Author: Alison Sanderson
|
|||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Aleph Environment Flags</property>
|
||||
<property name="label" translatable="yes">Hidden Environment Flags</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -979,17 +926,20 @@ Author: Alison Sanderson
|
|||
<object class="GtkImage" id="img-lines">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="resource">/net/greyserv/maraiah/tycho/lines</property>
|
||||
<property name="pixel_size">24</property>
|
||||
<property name="icon_name">tycho-lines</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="img-points">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="resource">/net/greyserv/maraiah/tycho/points</property>
|
||||
<property name="pixel_size">24</property>
|
||||
<property name="icon_name">tycho-points</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="img-polys">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="resource">/net/greyserv/maraiah/tycho/polys</property>
|
||||
<property name="pixel_size">24</property>
|
||||
<property name="icon_name">tycho-polys</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="win-map-tools">
|
||||
<property name="can_focus">False</property>
|
||||
|
@ -1095,11 +1045,137 @@ Author: Alison Sanderson
|
|||
<property name="modal">True</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="program_name">Tycho Map Editor</property>
|
||||
<property name="copyright" translatable="yes">Copyright © 2018-2019 Alison Sanderson</property>
|
||||
<property name="copyright" translatable="yes">By Alison Sanderson. Public domain.</property>
|
||||
<property name="comments" translatable="yes">greetigs i am tico the of superior ai to durdumbal go shoot my soldiers because its funny or ill put you in space</property>
|
||||
<property name="website_label" translatable="yes">Home Page</property>
|
||||
<property name="license" translatable="yes">To the extent possible under law, I, Alison Sanderson, have waived all
|
||||
copyright and related or neighboring rights to this Document as described by
|
||||
the Creative Commons Zero license as follows:
|
||||
|
||||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
||||
</property>
|
||||
<property name="logo_icon_name">image-loading</property>
|
||||
<property name="license_type">mit-x11</property>
|
||||
<property name="license_type">custom</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
|
@ -1132,44 +1208,6 @@ Author: Alison Sanderson
|
|||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkWindow" id="win-first-start">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">First Startup</property>
|
||||
<property name="resizable">False</property>
|
||||
<child>
|
||||
<object class="GtkAlignment">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="top_padding">10</property>
|
||||
<property name="bottom_padding">10</property>
|
||||
<property name="left_padding">10</property>
|
||||
<property name="right_padding">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">II. A word from the Programmer:
|
||||
|
||||
This entire program was written in Vim. Emacs users beware,
|
||||
IDEs beware, all beware! For I have the power of Vim! Hahahaha
|
||||
hahahahahaha! Anyway, hopefully you enjoy the program. It's
|
||||
my first serious effort at writing a GUI program. This toolset
|
||||
is made to encourage people to try out Marathon and hopefully
|
||||
start making stuff. Modding should be a fun journey for
|
||||
every one just as it has helped me to further my abilities at
|
||||
many things, including programming.
|
||||
|
||||
Also, 3 space tabs win. --- Alison Sanderson
|
||||
Programmer of Maraiah</property>
|
||||
<property name="angle">4</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="first-start-window"/>
|
||||
</style>
|
||||
</object>
|
||||
<object class="GtkWindow" id="win-main">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Tycho</property>
|
|
@ -22,7 +22,7 @@ fn mk_draw_area(b: >k::Builder)
|
|||
let ax: gtk::Adjustment = get_obj(b, "adj-map-horz");
|
||||
let ay: gtk::Adjustment = get_obj(b, "adj-map-vert");
|
||||
|
||||
let im = CairoPixbuf(load_img("/net/greyserv/maraiah/tycho/tycho1"));
|
||||
let im = CairoPixbuf(load_img("/net/greyserv/maraiah/tycho/tycho1.png"));
|
||||
|
||||
area.connect_draw(move |area, cr| {
|
||||
let w = f64::from(area.get_allocated_width());
|
||||
|
@ -44,8 +44,6 @@ fn mk_draw_area(b: >k::Builder)
|
|||
|
||||
fn run_app(app: >k::Application)
|
||||
{
|
||||
let b = >k::Builder::new_from_resource("/net/greyserv/maraiah/tycho/ui");
|
||||
|
||||
let prv = gtk::CssProvider::new();
|
||||
prv.load_from_resource("/net/greyserv/maraiah/tycho/css");
|
||||
|
||||
|
@ -53,6 +51,9 @@ fn run_app(app: >k::Application)
|
|||
let pri = gtk::STYLE_PROVIDER_PRIORITY_APPLICATION;
|
||||
gtk::StyleContext::add_provider_for_screen(&scr, &prv, pri);
|
||||
|
||||
let b = >k::Builder::new_from_resource("/net/greyserv/maraiah/tycho/ui");
|
||||
|
||||
// TODO: signal quit instead of quitting directly to not add a ref here
|
||||
let app_ = app.downgrade();
|
||||
let btn: gtk::MenuItem = get_obj(b, "btn-quit");
|
||||
btn.connect_activate(move |_| {
|
||||
|
@ -86,10 +87,7 @@ fn run_app(app: >k::Application)
|
|||
win.set_authors(&env!("CARGO_PKG_AUTHORS").split(';').collect::<Vec<_>>());
|
||||
win.set_version(env!("CARGO_PKG_VERSION"));
|
||||
win.set_website(env!("CARGO_PKG_HOMEPAGE"));
|
||||
win.set_logo(&load_img("/net/greyserv/maraiah/tycho/tycho2"));
|
||||
|
||||
let win: gtk::Window = get_obj(b, "win-first-start");
|
||||
win.show_all();
|
||||
win.set_logo(&load_img("/net/greyserv/maraiah/tycho/tycho2.png"));
|
||||
|
||||
let win: gtk::Window = get_obj(b, "win-main");
|
||||
win.set_application(app);
|
||||
|
@ -110,7 +108,8 @@ fn get_obj<T>(b: >k::Builder, name: &str) -> T
|
|||
fn main() -> ResultS<()>
|
||||
{
|
||||
// get jacked, punk. opaque data structures are for nerds.
|
||||
const RESOURCE_DATA: &[u8] = include_bytes!("data/tycho.res");
|
||||
const RESOURCE_DATA: &[u8] =
|
||||
include_bytes!(concat!(env!("OUT_DIR"), "/resources"));
|
||||
|
||||
// first we create the static resource header, which is really simple
|
||||
let mut static_resource =
|
||||
|
|