png-branch
an 2019-02-17 23:04:04 -05:00
parent 1a802c47db
commit 4c88a142fd
3 changed files with 110 additions and 46 deletions

View File

@ -1200,8 +1200,14 @@ actually useful field.
| Name | Type | Offset |
| ---- | ---- | ------ |
| `Frames` | `u32` | `0` |
| `SampleBits` | `u16` | `26` |
- `Frames` is used instead of `Size` for sounds with this header, since it
represents how many frames there are rather than how many bytes. Even though
this is actually a pointless distinction and Size is left at 1 anyway.
- `SampleBits` must be either 16 or 8.
# ENUMERATIONS ################################################################
Here is a list of names and descriptions for enumerations used throughout this
@ -1673,5 +1679,14 @@ gravity.
### Sound Definition Flags ###
| Name | Bit |
| ---- | --- |
| `NoRestart` | `0` |
| `NoChannelSwitch` | `1` |
| `LessPitchChange` | `2` |
| `NoPitchChange` | `3` |
| `NoObstruction` | `4` |
| `NoMediaObstruct` | `5` |
| `Ambient` | `6` |
<!-- EOF -->

View File

@ -135,15 +135,38 @@ fn process_shp(opt: &Options, b: &[u8]) -> ResultS<()>
Ok(())
}
fn process_snd(_opt: &Options, b: &[u8]) -> ResultS<()>
fn dump_sounds(opt: &Options, st: &snd::SoundTable, c: usize) -> ResultS<()>
{
if !opt.snd_dump {
return Ok(());
}
for (k, sd) in st {
for (i, snd) in sd.sounds.iter().enumerate() {
let fname = format!("{}/snd{}_{}_{}.wav", opt.out_dir, c, k, i);
make_wav(&fname, snd)?;
}
}
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<()>
{
for (c, st) in snd::read_sounds(b)?.iter().enumerate() {
for (k, sd) in st {
for (i, snd) in sd.sounds.iter().enumerate() {
let fname = format!("out/snd{}_{}_{}.wav", c, k, i);
make_wav(&fname, snd)?;
}
}
dump_sounds(opt, st, c)?;
write_sounds(opt, st)?;
}
Ok(())
@ -156,48 +179,63 @@ fn main() -> ResultS<()>
let mut opt: Options = Default::default();
{
macro_rules! arg {
($name:expr, $ref:expr, $type:expr, $ap:expr, $desc:expr) => {
$ap.refer(&mut $ref).add_option(&[$name], $type, $desc);
}
}
let mut ap = ArgumentParser::new();
ap.set_description(env!("CARGO_PKG_DESCRIPTION"));
ap.add_option(&["-v", "--version"],
Print(concat!(env!("CARGO_PKG_NAME"),
" ",
env!("CARGO_PKG_VERSION")).to_string()),
"Show the version");
ap.refer(&mut opt.shp_tab)
.add_option(&["--shp-write-tab"], StoreTrue,
"shp: Dump all CLUTs as YAML to standard output");
ap.refer(&mut opt.shp_bmp)
.add_option(&["--shp-dump-bitmaps"], StoreTrue,
"shp: Dump bitmaps into a folder");
ap.refer(&mut opt.shp_bmp_all)
.add_option(&["--shp-dump-more-bitmaps"], StoreTrue,
"shp: Dump all color variations of each bitmap");
ap.refer(&mut opt.shp_frm)
.add_option(&["--shp-write-frm"], StoreTrue,
"shp: Dump all frames as YAML to standard output");
ap.refer(&mut opt.shp_seq)
.add_option(&["--shp-write-seq"], StoreTrue,
"shp: Dump all sequences as YAML to standard output");
ap.refer(&mut opt.wad_all)
.add_option(&["--wad-dump-all"], StoreTrue,
"wad: Dump all chunks into a folder");
ap.refer(&mut opt.wad_unknown)
.add_option(&["--wad-dump-unknown"], StoreTrue,
"wad: Dump all unknown chunks into a folder");
ap.refer(&mut opt.wad_header)
.add_option(&["--wad-write-header"], StoreTrue,
"wad: Dump header info as YAML to standard output");
ap.refer(&mut opt.wad_c_temp)
.add_option(&["--wad-write-chunks"], Store,
"wad: Dump specified chunks in various formats");
ap.refer(&mut opt.out_dir)
.add_option(&["--out-dir"], Store,
"Sets output directory for dump options");
ap.refer(&mut opt.out_debug)
.add_option(&["--out-debug"], StoreTrue,
"Writes debugging output rather than YAML");
ap.refer(&mut opt.inputs)
.add_argument("inputs", Collect, "Input files");
arg!("--shp-write-tab", opt.shp_tab, StoreTrue, ap,
"shp: Dump all CLUTs as YAML to standard output");
arg!("--shp-dump-bitmaps", opt.shp_bmp, StoreTrue, ap,
"shp: Dump bitmaps into a folder");
arg!("--shp-dump-more-bitmaps", opt.shp_bmp_all, StoreTrue, ap,
"shp: Dump all color variations of each bitmap");
arg!("--shp-write-frm", opt.shp_frm, StoreTrue, ap,
"shp: Dump all frames as YAML to standard output");
arg!("--shp-write-seq", opt.shp_seq, StoreTrue, ap,
"shp: Dump all sequences as YAML to standard output");
arg!("--snd-write", opt.snd_write, StoreTrue, ap,
"snd: Dump all sound headers as YAML to standard output");
arg!("--snd-dump", opt.snd_dump, StoreTrue, ap,
"snd: Dump all sounds to WAVE files");
arg!("--wad-dump-all", opt.wad_all, StoreTrue, ap,
"wad: Dump all chunks into a folder");
arg!("--wad-dump-unknown", opt.wad_unknown, StoreTrue, ap,
"wad: Dump all unknown chunks into a folder");
arg!("--wad-write-header", opt.wad_header, StoreTrue, ap,
"wad: Dump header info as YAML to standard output");
arg!("--wad-write-chunks", opt.wad_c_temp, Store, ap,
"wad: Dump specified chunks in various formats");
arg!("--out-dir", opt.out_dir, Store, ap,
"Sets output directory for dump options");
arg!("--out-debug", opt.out_debug, StoreTrue, ap,
"Writes debugging output rather than YAML");
ap.parse_args_or_exit();
}
@ -250,6 +288,8 @@ struct Options
shp_bmp_all: bool,
shp_frm: bool,
shp_seq: bool,
snd_dump: bool,
snd_write: bool,
wad_all: bool,
wad_unknown: bool,
wad_header: bool,

View File

@ -25,10 +25,11 @@ fn sound(b: &[u8]) -> ResultS<Sound16>
let stream = c_data(b, 63..63 + len * 2)?;
Ok(Sound16::new_from_16(rate, lp_beg, lp_end, stream))
}
_ => {
8 => {
let stream = c_data(b, 63..63 + len)?;
Ok(Sound16::new_from_8(rate, lp_beg, lp_end, stream))
}
_ => bail!("bad bits per sample"),
}
}
_ => bail!("invalid magic number"),
@ -66,8 +67,10 @@ fn sound_def(b: &[u8]) -> ResultS<Option<(Vec<usize>, u16, SoundDef)>>
p += 4;
}
Ok(Some((ofs, index, SoundDef{volume, flags, chance, pitch_lo, pitch_hi,
sounds: Vec::with_capacity(n_sounds)})))
let header = SoundHead{volume, flags, chance, pitch_lo, pitch_hi};
let sounds = Vec::with_capacity(n_sounds);
Ok(Some((ofs, index, SoundDef{header, sounds})))
}
pub fn read_sounds(b: &[u8]) -> ResultS<Vec<SoundTable>>
@ -105,17 +108,23 @@ pub fn read_sounds(b: &[u8]) -> ResultS<Vec<SoundTable>>
Ok(sc)
}
pub struct SoundDef
#[derive(Debug, Serialize)]
pub struct SoundHead
{
pub volume: Volume,
pub flags: SoundFlags,
pub chance: u16,
pub pitch_lo: Fixed,
pub pitch_hi: Fixed,
pub sounds: Vec<Sound16>,
}
type SoundTable = HashMap<u16, SoundDef>;
pub struct SoundDef
{
pub header: SoundHead,
pub sounds: Vec<Sound16>,
}
pub type SoundTable = HashMap<u16, SoundDef>;
bitflags! {
#[derive(Serialize)]