documentation
parent
152d8a0b60
commit
b5dfcf3ee2
|
@ -466,7 +466,7 @@ impl fmt::Debug for Ident
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Clone, Copy, Default, PartialEq)]
|
#[derive(Clone, Copy, Default, PartialEq)]
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
pub struct Ident(pub [u8; 4]);
|
pub struct Ident(/** The individual bytes of this identifier. */ pub [u8; 4]);
|
||||||
|
|
||||||
/// An object identified by a `u16` which may be `u16::max_value()` to
|
/// An object identified by a `u16` which may be `u16::max_value()` to
|
||||||
/// represent a nulled value.
|
/// represent a nulled value.
|
||||||
|
|
|
@ -38,7 +38,7 @@ macro_rules! c_enum
|
||||||
$(#[$outer:meta])*
|
$(#[$outer:meta])*
|
||||||
$vi:vis enum $t:ident: $ti:ty
|
$vi:vis enum $t:ident: $ti:ty
|
||||||
{
|
{
|
||||||
$($va:expr => $en:ident,)+
|
$($(#[$inner:meta])* $va:expr => $en:ident,)+
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
$(#[$outer])*
|
$(#[$outer])*
|
||||||
|
@ -54,7 +54,7 @@ macro_rules! c_enum
|
||||||
$vi fn from_repr(n: $ti) -> Result<Self, ReprError>
|
$vi fn from_repr(n: $ti) -> Result<Self, ReprError>
|
||||||
{
|
{
|
||||||
match n {
|
match n {
|
||||||
$($va => Ok($t::$en),)+
|
$($(#[$inner])* $va => Ok($t::$en),)+
|
||||||
n => Err(ReprError::new(n))
|
n => Err(ReprError::new(n))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,7 @@ fn crc_init() -> [u32; 256]
|
||||||
pub fn crc32(b: &[u8], s: u32) -> u32
|
pub fn crc32(b: &[u8], s: u32) -> u32
|
||||||
{
|
{
|
||||||
let t = crc_init();
|
let t = crc_init();
|
||||||
!b.iter()
|
!b.iter().fold(s, |a, &o| a >> 8 ^ t[usize::from(a as u8 ^ o)])
|
||||||
.fold(s, |a, &o| a >> 8 ^ t[usize::from(a as u8 ^ o)])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -239,6 +239,8 @@ pub struct Image16
|
||||||
{
|
{
|
||||||
w: usize,
|
w: usize,
|
||||||
h: usize,
|
h: usize,
|
||||||
|
|
||||||
|
/// The raw color data for this image.
|
||||||
pub cr: Vec<Color16>,
|
pub cr: Vec<Color16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,6 +250,8 @@ pub struct Image8
|
||||||
{
|
{
|
||||||
w: usize,
|
w: usize,
|
||||||
h: usize,
|
h: usize,
|
||||||
|
|
||||||
|
/// The raw color data for this image.
|
||||||
pub cr: Vec<Color8>,
|
pub cr: Vec<Color8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,8 @@ pub struct Sound16
|
||||||
rate: u16,
|
rate: u16,
|
||||||
lp_beg: usize,
|
lp_beg: usize,
|
||||||
lp_end: usize,
|
lp_end: usize,
|
||||||
|
|
||||||
|
/// The raw signed PCM data of this sound.
|
||||||
pub data: Vec<i16>,
|
pub data: Vec<i16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,12 +32,8 @@ fn process_wad(opt: &Options, b: &[u8]) -> ResultS<()>
|
||||||
{
|
{
|
||||||
let wad = wad::read_wad(b)?;
|
let wad = wad::read_wad(b)?;
|
||||||
|
|
||||||
if opt.wad_header {
|
|
||||||
make_yaml(opt, &wad.head)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if opt.wad_wrt_all {
|
if opt.wad_wrt_all {
|
||||||
make_yaml(opt, &wad.entries)?;
|
make_yaml(opt, &wad)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -106,22 +102,10 @@ fn dump_sounds(opt: &Options, st: &snd::SoundTable, c: usize) -> ResultS<()>
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_sounds(opt: &Options, st: &snd::SoundTable) -> ResultS<()>
|
|
||||||
{
|
|
||||||
if opt.snd_write {
|
|
||||||
for sd in st.values() {
|
|
||||||
make_yaml(opt, &sd.header)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn process_snd(opt: &Options, b: &[u8]) -> ResultS<()>
|
fn process_snd(opt: &Options, b: &[u8]) -> ResultS<()>
|
||||||
{
|
{
|
||||||
for (c, st) in snd::read_sounds(b)?.iter().enumerate() {
|
for (c, st) in snd::read_sounds(b)?.iter().enumerate() {
|
||||||
dump_sounds(opt, st, c)?;
|
dump_sounds(opt, st, c)?;
|
||||||
write_sounds(opt, st)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -178,11 +162,6 @@ fn main() -> ResultS<()>
|
||||||
StoreTrue,
|
StoreTrue,
|
||||||
"shp: Dump all sequences as YAML to standard output");
|
"shp: Dump all sequences as YAML to standard output");
|
||||||
|
|
||||||
arg!("--snd-write",
|
|
||||||
opt.snd_write,
|
|
||||||
StoreTrue,
|
|
||||||
"snd: Dump all sound headers as YAML to standard output");
|
|
||||||
|
|
||||||
arg!("--snd-dump",
|
arg!("--snd-dump",
|
||||||
opt.snd_dump,
|
opt.snd_dump,
|
||||||
StoreTrue,
|
StoreTrue,
|
||||||
|
@ -193,11 +172,6 @@ fn main() -> ResultS<()>
|
||||||
StoreTrue,
|
StoreTrue,
|
||||||
"wad: Dump all known chunks");
|
"wad: Dump all known chunks");
|
||||||
|
|
||||||
arg!("--wad-write-header",
|
|
||||||
opt.wad_header,
|
|
||||||
StoreTrue,
|
|
||||||
"wad: Dump header info as YAML to standard output");
|
|
||||||
|
|
||||||
arg!("--out-dir",
|
arg!("--out-dir",
|
||||||
opt.out_dir,
|
opt.out_dir,
|
||||||
Store,
|
Store,
|
||||||
|
@ -255,9 +229,7 @@ struct Options
|
||||||
shp_frm: bool,
|
shp_frm: bool,
|
||||||
shp_seq: bool,
|
shp_seq: bool,
|
||||||
snd_dump: bool,
|
snd_dump: bool,
|
||||||
snd_write: bool,
|
|
||||||
wad_wrt_all: bool,
|
wad_wrt_all: bool,
|
||||||
wad_header: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#![deny(anonymous_parameters)]
|
#![deny(anonymous_parameters)]
|
||||||
#![deny(bare_trait_objects)]
|
#![deny(bare_trait_objects)]
|
||||||
#![deny(elided_lifetimes_in_paths)]
|
#![deny(elided_lifetimes_in_paths)]
|
||||||
|
#![deny(unreachable_pub)]
|
||||||
#![warn(trivial_casts)]
|
#![warn(trivial_casts)]
|
||||||
#![warn(trivial_numeric_casts)]
|
#![warn(trivial_numeric_casts)]
|
||||||
#![deny(unreachable_pub)]
|
|
||||||
#![warn(unused_import_braces)]
|
#![warn(unused_import_braces)]
|
||||||
#![warn(unused_qualifications)]
|
#![warn(unused_qualifications)]
|
||||||
#![deny(clippy::all)]
|
#![deny(clippy::all)]
|
||||||
|
@ -19,7 +19,6 @@
|
||||||
#![deny(clippy::filter_map)]
|
#![deny(clippy::filter_map)]
|
||||||
#![deny(clippy::float_arithmetic)]
|
#![deny(clippy::float_arithmetic)]
|
||||||
#![deny(clippy::float_cmp_const)]
|
#![deny(clippy::float_cmp_const)]
|
||||||
#![deny(clippy::if_not_else)]
|
|
||||||
#![deny(clippy::invalid_upcast_comparisons)]
|
#![deny(clippy::invalid_upcast_comparisons)]
|
||||||
#![deny(clippy::items_after_statements)]
|
#![deny(clippy::items_after_statements)]
|
||||||
#![deny(clippy::large_digit_groups)]
|
#![deny(clippy::large_digit_groups)]
|
||||||
|
|
|
@ -936,6 +936,7 @@ c_enum! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The number of game ticks per second.
|
||||||
pub const TICKS_PER_SECOND: u16 = 30;
|
pub const TICKS_PER_SECOND: u16 = 30;
|
||||||
|
|
||||||
const OLD_LIGHT_DEFINITIONS: [Light; 8] = [
|
const OLD_LIGHT_DEFINITIONS: [Light; 8] = [
|
||||||
|
|
|
@ -9,21 +9,23 @@ fn read_color(b: &[u8], clut: &mut [ColorShp]) -> ResultS<()>
|
||||||
{
|
{
|
||||||
read_data! {
|
read_data! {
|
||||||
8, BE in b =>
|
8, BE in b =>
|
||||||
l = u8[0];
|
flag = u8[0];
|
||||||
i = u8[1];
|
ind = u8[1];
|
||||||
r = u16[2];
|
r = u16[2];
|
||||||
g = u16[4];
|
g = u16[4];
|
||||||
b = u16[6];
|
b = u16[6];
|
||||||
}
|
}
|
||||||
|
|
||||||
let l = match l {
|
let cr = ok!(clut.get_mut(usize::from(ind)), "bad index")?;
|
||||||
128 => Ok(true),
|
|
||||||
0 => Ok(false),
|
*cr = match flag {
|
||||||
_ => Err(err_msg("invalid flag in color")),
|
128 => ColorShp::Lit {r, g, b},
|
||||||
}?;
|
0 => ColorShp::Opaque{r, g, b},
|
||||||
|
_ => {
|
||||||
|
return Err(err_msg("invalid flag in color"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let cr = ColorShp::Opaque{r, g, b, l};
|
|
||||||
*ok!(clut.get_mut(usize::from(i)), "bad index")? = cr;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,6 +287,7 @@ impl Color for ColorShp
|
||||||
match *self {
|
match *self {
|
||||||
ColorShp::Translucent => 0,
|
ColorShp::Translucent => 0,
|
||||||
ColorShp::Opaque{r, ..} => r,
|
ColorShp::Opaque{r, ..} => r,
|
||||||
|
ColorShp::Lit {r, ..} => r,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,6 +296,7 @@ impl Color for ColorShp
|
||||||
match *self {
|
match *self {
|
||||||
ColorShp::Translucent => 0,
|
ColorShp::Translucent => 0,
|
||||||
ColorShp::Opaque{g, ..} => g,
|
ColorShp::Opaque{g, ..} => g,
|
||||||
|
ColorShp::Lit {g, ..} => g,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,6 +305,7 @@ impl Color for ColorShp
|
||||||
match *self {
|
match *self {
|
||||||
ColorShp::Translucent => 0,
|
ColorShp::Translucent => 0,
|
||||||
ColorShp::Opaque{b, ..} => b,
|
ColorShp::Opaque{b, ..} => b,
|
||||||
|
ColorShp::Lit {b, ..} => b,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,6 +314,7 @@ impl Color for ColorShp
|
||||||
match *self {
|
match *self {
|
||||||
ColorShp::Translucent => 0,
|
ColorShp::Translucent => 0,
|
||||||
ColorShp::Opaque{..} => u16::max_value(),
|
ColorShp::Opaque{..} => u16::max_value(),
|
||||||
|
ColorShp::Lit {..} => u16::max_value(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -317,14 +323,18 @@ impl Color for ColorShp
|
||||||
#[derive(Copy, Clone, Debug, serde::Serialize)]
|
#[derive(Copy, Clone, Debug, serde::Serialize)]
|
||||||
pub enum ColorShp
|
pub enum ColorShp
|
||||||
{
|
{
|
||||||
|
/// A completely translucent color.
|
||||||
Translucent,
|
Translucent,
|
||||||
Opaque
|
|
||||||
{
|
/// An opaque color which may be shaded.
|
||||||
r: u16,
|
Opaque{/** The red component. */ r: u16,
|
||||||
g: u16,
|
/** The green component. */ g: u16,
|
||||||
b: u16,
|
/** The blue component. */ b: u16},
|
||||||
l: bool,
|
|
||||||
},
|
/// An opaque color which may not be shaded.
|
||||||
|
Lit{/** The red component. */ r: u16,
|
||||||
|
/** The green component. */ g: u16,
|
||||||
|
/** The blue component. */ b: u16},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An unpacked Shape bitmap.
|
/// An unpacked Shape bitmap.
|
||||||
|
@ -350,42 +360,89 @@ pub struct ImageShp<'a, 'b>
|
||||||
#[derive(Debug, serde::Serialize)]
|
#[derive(Debug, serde::Serialize)]
|
||||||
pub struct Frame
|
pub struct Frame
|
||||||
{
|
{
|
||||||
flags: FrameFlags,
|
/// The flags for this frame.
|
||||||
min_lt: Fixed,
|
pub flags: FrameFlags,
|
||||||
bmp_ind: usize,
|
|
||||||
wrl_l: Unit,
|
/// The minimum light level for this frame.
|
||||||
wrl_r: Unit,
|
pub min_lt: Fixed,
|
||||||
wrl_t: Unit,
|
|
||||||
wrl_b: Unit,
|
/// The index of the bitmap this frame uses.
|
||||||
wrl_x: Unit,
|
pub bmp_ind: usize,
|
||||||
wrl_y: Unit,
|
|
||||||
|
/// The left translation for this frame.
|
||||||
|
pub wrl_l: Unit,
|
||||||
|
|
||||||
|
/// The right translation for this frame.
|
||||||
|
pub wrl_r: Unit,
|
||||||
|
|
||||||
|
/// The top translation for this frame.
|
||||||
|
pub wrl_t: Unit,
|
||||||
|
|
||||||
|
/// The bottom translation for this frame.
|
||||||
|
pub wrl_b: Unit,
|
||||||
|
|
||||||
|
/// The X translation for this frame.
|
||||||
|
pub wrl_x: Unit,
|
||||||
|
|
||||||
|
/// The Y translation for this frame.
|
||||||
|
pub wrl_y: Unit,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A sequence, also known as a high level shape.
|
/// A sequence, also known as a high level shape.
|
||||||
#[derive(Debug, serde::Serialize)]
|
#[derive(Debug, serde::Serialize)]
|
||||||
pub struct Sequence
|
pub struct Sequence
|
||||||
{
|
{
|
||||||
name: String,
|
/// The display name for this sequence.
|
||||||
v_type: ViewType,
|
pub name: String,
|
||||||
frames: u16,
|
|
||||||
ticks: u16,
|
/// The view type for each frame in this sequence.
|
||||||
key: u16,
|
pub v_type: ViewType,
|
||||||
xfer: TransferMode,
|
|
||||||
xfer_pd: u16,
|
/// The number of frames in this sequence.
|
||||||
snd_beg: OptU16,
|
pub frames: u16,
|
||||||
snd_key: OptU16,
|
|
||||||
snd_end: OptU16,
|
/// The number of ticks each frame in this sequence takes.
|
||||||
loop_f: u16,
|
pub ticks: u16,
|
||||||
|
|
||||||
|
/// The key frame index for this sequence.
|
||||||
|
pub key: u16,
|
||||||
|
|
||||||
|
/// The transfer mode to play over this sequence.
|
||||||
|
pub xfer: TransferMode,
|
||||||
|
|
||||||
|
/// The period in game ticks the transfer mode plays over.
|
||||||
|
pub xfer_pd: u16,
|
||||||
|
|
||||||
|
/// The sound to play at the beginning of this sequence.
|
||||||
|
pub snd_beg: OptU16,
|
||||||
|
|
||||||
|
/// The sound to play at the key frame of this sequence.
|
||||||
|
pub snd_key: OptU16,
|
||||||
|
|
||||||
|
/// The sound to play at the end of this sequence.
|
||||||
|
pub snd_end: OptU16,
|
||||||
|
|
||||||
|
/// Which frame to loop on.
|
||||||
|
pub loop_f: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A collection of color tables, bitmaps, frames and sequences.
|
/// A collection of color tables, bitmaps, frames and sequences.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Collection
|
pub struct Collection
|
||||||
{
|
{
|
||||||
|
/// The type of collection this is.
|
||||||
pub ctyp: CollectionType,
|
pub ctyp: CollectionType,
|
||||||
|
|
||||||
|
/// All of the color tables in this collection.
|
||||||
pub tabs: Vec<Vec<ColorShp>>,
|
pub tabs: Vec<Vec<ColorShp>>,
|
||||||
|
|
||||||
|
/// All of the bitmaps in this collection.
|
||||||
pub bmps: Vec<Bitmap>,
|
pub bmps: Vec<Bitmap>,
|
||||||
|
|
||||||
|
/// All of the frames in this collection.
|
||||||
pub frms: Vec<Frame>,
|
pub frms: Vec<Frame>,
|
||||||
|
|
||||||
|
/// All of the sequences in this collection.
|
||||||
pub seqs: Vec<Sequence>,
|
pub seqs: Vec<Sequence>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,8 +462,11 @@ bitflags! {
|
||||||
#[derive(serde::Serialize)]
|
#[derive(serde::Serialize)]
|
||||||
pub struct FrameFlags: u16
|
pub struct FrameFlags: u16
|
||||||
{
|
{
|
||||||
|
/// The player's torso will obscure the player's legs.
|
||||||
const OBSCURE = 1 << 13;
|
const OBSCURE = 1 << 13;
|
||||||
|
/// The bitmap will be flipped on the vertical axis.
|
||||||
const FLIP_Y = 1 << 14;
|
const FLIP_Y = 1 << 14;
|
||||||
|
/// The bitmap will be flipped on the horizontal axis.
|
||||||
const FLIP_X = 1 << 15;
|
const FLIP_X = 1 << 15;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,10 +78,10 @@ pub fn read_sound_def(b: &[u8]) -> ResultS<Option<(Vec<usize>, u16, SoundDef)>>
|
||||||
p += 4;
|
p += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
let header = SoundHead{volume, flags, chance, pitch_lo, pitch_hi};
|
|
||||||
let sounds = Vec::with_capacity(n_sounds);
|
let sounds = Vec::with_capacity(n_sounds);
|
||||||
|
|
||||||
Ok(Some((ofs, index, SoundDef{header, sounds})))
|
Ok(Some((ofs, index,
|
||||||
|
SoundDef{volume, flags, chance, pitch_lo, pitch_hi, sounds})))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads all sounds from a Sound file.
|
/// Reads all sounds from a Sound file.
|
||||||
|
@ -123,21 +123,25 @@ pub fn read_sounds(b: &[u8]) -> ResultS<Vec<SoundTable>>
|
||||||
Ok(sc)
|
Ok(sc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The header of a sound definition.
|
|
||||||
#[derive(Debug, serde::Serialize)]
|
|
||||||
pub struct SoundHead
|
|
||||||
{
|
|
||||||
pub volume: Volume,
|
|
||||||
pub flags: SoundFlags,
|
|
||||||
pub chance: u16,
|
|
||||||
pub pitch_lo: Fixed,
|
|
||||||
pub pitch_hi: Fixed,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A sound definition containing one, many or no sounds.
|
/// A sound definition containing one, many or no sounds.
|
||||||
pub struct SoundDef
|
pub struct SoundDef
|
||||||
{
|
{
|
||||||
pub header: SoundHead,
|
/// The volume type for this sound.
|
||||||
|
pub volume: Volume,
|
||||||
|
|
||||||
|
/// The flags for this sound.
|
||||||
|
pub flags: SoundFlags,
|
||||||
|
|
||||||
|
/// The chance out of `u16::max_value()` that this sound will not play.
|
||||||
|
pub chance: u16,
|
||||||
|
|
||||||
|
/// The low random pitch bound.
|
||||||
|
pub pitch_lo: Fixed,
|
||||||
|
|
||||||
|
/// The high random pitch bound.
|
||||||
|
pub pitch_hi: Fixed,
|
||||||
|
|
||||||
|
/// All of the sounds in this collection.
|
||||||
pub sounds: Vec<Sound16>,
|
pub sounds: Vec<Sound16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,16 +149,23 @@ pub struct SoundDef
|
||||||
pub type SoundTable = BTreeMap<u16, SoundDef>;
|
pub type SoundTable = BTreeMap<u16, SoundDef>;
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for `SoundHead`.
|
/// Flags for `SoundDef`.
|
||||||
#[derive(serde::Serialize)]
|
#[derive(serde::Serialize)]
|
||||||
pub struct SoundFlags: u16
|
pub struct SoundFlags: u16
|
||||||
{
|
{
|
||||||
|
/// The sound will not restart when trying to play over itself.
|
||||||
const NO_RESTART = 1;
|
const NO_RESTART = 1;
|
||||||
|
/// The sound will not switch channels when trying to play over itself.
|
||||||
const NO_CHANNEL_SWITCH = 1 << 1;
|
const NO_CHANNEL_SWITCH = 1 << 1;
|
||||||
|
/// The pitch variance will be halved.
|
||||||
const LESS_PITCH_CHANGE = 1 << 2;
|
const LESS_PITCH_CHANGE = 1 << 2;
|
||||||
|
/// The pitch variance will be nullified.
|
||||||
const NO_PITCH_CHANGE = 1 << 3;
|
const NO_PITCH_CHANGE = 1 << 3;
|
||||||
|
/// The sound will play even when completely obstructed by walls.
|
||||||
const NO_OBSTRUCTION = 1 << 4;
|
const NO_OBSTRUCTION = 1 << 4;
|
||||||
|
/// The sound will play even when completely obstructed by media.
|
||||||
const NO_MEDIA_OBSTRUCT = 1 << 5;
|
const NO_MEDIA_OBSTRUCT = 1 << 5;
|
||||||
|
/// The sound will have special stereo effects.
|
||||||
const AMBIENT = 1 << 6;
|
const AMBIENT = 1 << 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,11 +128,11 @@ pub struct Group
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InterGroup
|
pub struct InterGroup
|
||||||
{
|
{
|
||||||
flags: GroupFlags,
|
pub flags: GroupFlags,
|
||||||
ttype: GroupType,
|
pub ttype: GroupType,
|
||||||
lines: u16,
|
pub lines: u16,
|
||||||
beg: usize,
|
pub beg: usize,
|
||||||
len: usize,
|
pub len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The command of a `Group`.
|
/// The command of a `Group`.
|
||||||
|
@ -163,7 +163,9 @@ bitflags! {
|
||||||
#[derive(Default, serde::Serialize)]
|
#[derive(Default, serde::Serialize)]
|
||||||
pub struct GroupFlags: u16
|
pub struct GroupFlags: u16
|
||||||
{
|
{
|
||||||
|
/// Draws the picture on the right.
|
||||||
const DRAW_ON_RIGHT = 1;
|
const DRAW_ON_RIGHT = 1;
|
||||||
|
/// Draws the picture in the center.
|
||||||
const DRAW_CENTER = 1 << 1;
|
const DRAW_CENTER = 1 << 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,13 +111,11 @@ pub fn read_wad(b: &[u8]) -> ResultS<Wad>
|
||||||
siz_went = u16[82] usize;
|
siz_went = u16[82] usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ver_wad = Ver::from_repr(ver_wad)?;
|
let old_dat = ver_dat == 0;
|
||||||
|
let old_wad = match Ver::from_repr(ver_wad)? {
|
||||||
let old_wad = match ver_wad {
|
|
||||||
Ver::Base => true,
|
Ver::Base => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
let old_dat = ver_dat == 0;
|
|
||||||
|
|
||||||
let siz_ent = if old_wad {8 } else {10};
|
let siz_ent = if old_wad {8 } else {10};
|
||||||
let siz_cnk = if old_wad {12} else {16};
|
let siz_cnk = if old_wad {12} else {16};
|
||||||
|
@ -132,60 +130,82 @@ pub fn read_wad(b: &[u8]) -> ResultS<Wad>
|
||||||
|
|
||||||
let entries = read_entries(b, old_wad, old_dat, siz_app, siz_ent, siz_cnk)?;
|
let entries = read_entries(b, old_wad, old_dat, siz_app, siz_ent, siz_cnk)?;
|
||||||
|
|
||||||
Ok(Wad{head: WadHeader{ver_wad, old_dat, siz_app, name}, entries})
|
Ok(Wad{name, siz_app, entries})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Any kind of chunk in an `Entry`.
|
/// Any kind of chunk in an `Entry`.
|
||||||
#[derive(Debug, serde::Serialize)]
|
#[derive(Debug, serde::Serialize)]
|
||||||
pub enum Chunk
|
pub enum Chunk
|
||||||
{
|
{
|
||||||
|
/// A `PICT` chunk.
|
||||||
Pict(image::Image8),
|
Pict(image::Image8),
|
||||||
|
/// A `Minf` chunk.
|
||||||
Minf(map::Minf),
|
Minf(map::Minf),
|
||||||
|
/// An `iidx` chunk.
|
||||||
Iidx(Vec<u16>),
|
Iidx(Vec<u16>),
|
||||||
|
/// A `PNTS` chunk.
|
||||||
Pnts(Vec<map::Point>),
|
Pnts(Vec<map::Point>),
|
||||||
|
/// A `LINS` chunk.
|
||||||
Lins(Vec<map::Line>),
|
Lins(Vec<map::Line>),
|
||||||
|
/// A `SIDS` chunk.
|
||||||
Sids(Vec<map::Side>),
|
Sids(Vec<map::Side>),
|
||||||
|
/// A `POLY` chunk.
|
||||||
Poly(Vec<map::Polygon>),
|
Poly(Vec<map::Polygon>),
|
||||||
|
/// A `LITE` chunk.
|
||||||
Lite(Vec<map::Light>),
|
Lite(Vec<map::Light>),
|
||||||
|
/// An `OBJS` chunk.
|
||||||
Objs(Vec<map::Object>),
|
Objs(Vec<map::Object>),
|
||||||
|
/// A `plac` chunk.
|
||||||
Plac(Vec<map::ObjectFreq>),
|
Plac(Vec<map::ObjectFreq>),
|
||||||
|
/// An `ambi` chunk.
|
||||||
Ambi(Vec<map::SoundAmbi>),
|
Ambi(Vec<map::SoundAmbi>),
|
||||||
|
/// A `bonk` chunk.
|
||||||
Bonk(Vec<map::SoundRand>),
|
Bonk(Vec<map::SoundRand>),
|
||||||
|
/// A `medi` chunk.
|
||||||
Medi(Vec<map::Media>),
|
Medi(Vec<map::Media>),
|
||||||
|
/// A `plat` chunk.
|
||||||
Plat(Vec<map::Platform>),
|
Plat(Vec<map::Platform>),
|
||||||
|
/// A `NOTE` chunk.
|
||||||
Note(Vec<map::Note>),
|
Note(Vec<map::Note>),
|
||||||
|
/// A `term` chunk.
|
||||||
Term(Vec<trm::Terminal>),
|
Term(Vec<trm::Terminal>),
|
||||||
|
/// A `FXpx` chunk.
|
||||||
Fxpx(Vec<phy::Effect>),
|
Fxpx(Vec<phy::Effect>),
|
||||||
|
/// A `MNpx` chunk.
|
||||||
Mnpx(Vec<phy::Monster>),
|
Mnpx(Vec<phy::Monster>),
|
||||||
|
/// A `PRpx` chunk.
|
||||||
Prpx(Vec<phy::Projectile>),
|
Prpx(Vec<phy::Projectile>),
|
||||||
|
/// A `PXpx` chunk.
|
||||||
Pxpx(Vec<phy::Physics>),
|
Pxpx(Vec<phy::Physics>),
|
||||||
|
/// A `WPpx` chunk.
|
||||||
Wppx(Vec<phy::Weapon>),
|
Wppx(Vec<phy::Weapon>),
|
||||||
Data{iden: Ident, data: Vec<u8>},
|
/// Any other type of chunk, which may have arbitrary data in it.
|
||||||
|
Data{/** The name of the chunk. */ iden: Ident,
|
||||||
|
/** The data. */ data: Vec<u8>},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An entry containing chunks and application-specific data.
|
/// An entry containing chunks and application-specific data.
|
||||||
#[derive(Debug, serde::Serialize)]
|
#[derive(Debug, serde::Serialize)]
|
||||||
pub struct Entry
|
pub struct Entry
|
||||||
{
|
{
|
||||||
|
/// All of the chunks in this `Entry`.
|
||||||
pub chunks: Vec<Chunk>,
|
pub chunks: Vec<Chunk>,
|
||||||
pub appdata: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The header of a `Wad`.
|
/// The application specific data for this Entry.
|
||||||
#[derive(Debug, serde::Serialize)]
|
pub appdata: Vec<u8>,
|
||||||
pub struct WadHeader
|
|
||||||
{
|
|
||||||
pub ver_wad: Ver,
|
|
||||||
pub old_dat: bool,
|
|
||||||
pub name: String,
|
|
||||||
pub siz_app: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A Map file containing entries.
|
/// A Map file containing entries.
|
||||||
#[derive(Debug, serde::Serialize)]
|
#[derive(Debug, serde::Serialize)]
|
||||||
pub struct Wad
|
pub struct Wad
|
||||||
{
|
{
|
||||||
pub head: WadHeader,
|
/// The original name of this file.
|
||||||
|
pub name: String,
|
||||||
|
|
||||||
|
/// The size of each `Entry`'s `appdata` field.
|
||||||
|
pub siz_app: usize,
|
||||||
|
|
||||||
|
/// All of the entries in this `Wad`.
|
||||||
pub entries: BTreeMap<u16, Entry>,
|
pub entries: BTreeMap<u16, Entry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,9 +47,16 @@ pub type Point = (Coord, Coord);
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct Rect
|
pub struct Rect
|
||||||
{
|
{
|
||||||
|
/// The horizontal coordinate to start at, from the left.
|
||||||
pub x: Coord,
|
pub x: Coord,
|
||||||
|
|
||||||
|
/// The vertical coordinate to start at, from the top.
|
||||||
pub y: Coord,
|
pub y: Coord,
|
||||||
|
|
||||||
|
/// The width of the rectangle.
|
||||||
pub w: Coord,
|
pub w: Coord,
|
||||||
|
|
||||||
|
/// The height of the rectangle.
|
||||||
pub h: Coord,
|
pub h: Coord,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@ fn read_epnt_must_process()
|
||||||
#[test]
|
#[test]
|
||||||
fn map_must_not_process()
|
fn map_must_not_process()
|
||||||
{
|
{
|
||||||
// these functions must not succeed
|
|
||||||
for inp in &RANDOM {
|
for inp in &RANDOM {
|
||||||
assert!(map::read_minf(inp).is_err());
|
assert!(map::read_minf(inp).is_err());
|
||||||
assert!(map::read_old_minf(inp).is_err());
|
assert!(map::read_old_minf(inp).is_err());
|
||||||
|
@ -50,9 +49,8 @@ fn map_must_not_process()
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(unused_must_use)]
|
#[allow(unused_must_use)]
|
||||||
fn map_wont_panic()
|
fn map_must_not_panic()
|
||||||
{
|
{
|
||||||
// these functions can succeed but must never panic
|
|
||||||
for inp in &RANDOM {
|
for inp in &RANDOM {
|
||||||
bin::rd_array(inp, map::read_ambi);
|
bin::rd_array(inp, map::read_ambi);
|
||||||
bin::rd_array(inp, map::read_bonk);
|
bin::rd_array(inp, map::read_bonk);
|
||||||
|
|
|
@ -5,7 +5,6 @@ include!("data/rand.rs");
|
||||||
#[test]
|
#[test]
|
||||||
fn phy_must_not_process()
|
fn phy_must_not_process()
|
||||||
{
|
{
|
||||||
// these functions must not succeed
|
|
||||||
for inp in &RANDOM {
|
for inp in &RANDOM {
|
||||||
assert!(bin::rd_array(inp, phy::read_fxpx).is_err());
|
assert!(bin::rd_array(inp, phy::read_fxpx).is_err());
|
||||||
assert!(bin::rd_array(inp, phy::read_mnpx).is_err());
|
assert!(bin::rd_array(inp, phy::read_mnpx).is_err());
|
||||||
|
@ -16,9 +15,8 @@ fn phy_must_not_process()
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(unused_must_use)]
|
#[allow(unused_must_use)]
|
||||||
fn phy_wont_panic()
|
fn phy_must_not_panic()
|
||||||
{
|
{
|
||||||
// these functions can succeed but must never panic
|
|
||||||
for inp in &RANDOM {
|
for inp in &RANDOM {
|
||||||
bin::rd_array(inp, phy::read_pxpx);
|
bin::rd_array(inp, phy::read_pxpx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ fn trm_must_not_process()
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(unused_must_use)]
|
#[allow(unused_must_use)]
|
||||||
fn trm_wont_panic()
|
fn trm_must_not_panic()
|
||||||
{
|
{
|
||||||
for inp in &RANDOM {
|
for inp in &RANDOM {
|
||||||
bin::rd_array(inp, trm::read_face);
|
bin::rd_array(inp, trm::read_face);
|
||||||
|
|
Loading…
Reference in New Issue