make the commandline application actually useful
parent
3329fde767
commit
5b3c8fcbe1
|
@ -18,6 +18,8 @@ failure = "0.1"
|
||||||
generic-array = "0.12"
|
generic-array = "0.12"
|
||||||
#gtk = "0.4"
|
#gtk = "0.4"
|
||||||
memmap = "0.6"
|
memmap = "0.6"
|
||||||
|
serde = {version = "1.0", features = ["derive"]}
|
||||||
|
serde_yaml = "0.8"
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 1
|
opt-level = 1
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! Binary data conversion utilities.
|
//! Binary data conversion utilities.
|
||||||
|
|
||||||
use crate::durandal::err::*;
|
use crate::durandal::err::*;
|
||||||
|
use serde::Serialize;
|
||||||
use std::{fmt, num::NonZeroU16, slice::SliceIndex};
|
use std::{fmt, num::NonZeroU16, slice::SliceIndex};
|
||||||
|
|
||||||
/// Returns a byte array from `b` at `i`.
|
/// Returns a byte array from `b` at `i`.
|
||||||
|
@ -144,6 +145,7 @@ pub type Ident = [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 None.
|
/// represent None.
|
||||||
|
#[derive(Serialize)]
|
||||||
pub struct ObjID(Option<NonZeroU16>);
|
pub struct ObjID(Option<NonZeroU16>);
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
//! File utilities.
|
||||||
|
|
||||||
|
use crate::durandal::err::*;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
pub fn validate_folder_path(p: &str) -> ResultS<()>
|
||||||
|
{
|
||||||
|
let at = fs::metadata(p)?;
|
||||||
|
if !at.is_dir() {
|
||||||
|
Err(err_msg("not a directory"))
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF
|
|
@ -1,6 +1,8 @@
|
||||||
|
use serde::Serialize;
|
||||||
use std::{fmt::{self, Write},
|
use std::{fmt::{self, Write},
|
||||||
ops};
|
ops};
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
pub struct Fx32(i32);
|
pub struct Fx32(i32);
|
||||||
|
|
||||||
impl Fx32
|
impl Fx32
|
||||||
|
|
|
@ -8,6 +8,7 @@ pub mod err;
|
||||||
pub mod bin;
|
pub mod bin;
|
||||||
pub mod chunk;
|
pub mod chunk;
|
||||||
pub mod crc;
|
pub mod crc;
|
||||||
|
pub mod file;
|
||||||
pub mod fx32;
|
pub mod fx32;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
pub mod text;
|
pub mod text;
|
||||||
|
|
200
src/main.rs
200
src/main.rs
|
@ -1,98 +1,149 @@
|
||||||
use maraiah::{durandal::{bin::*, chunk::*, err::*, image::*, text::*},
|
use maraiah::{durandal::{bin::*, chunk::*, err::*, file::*, image::*, text::*},
|
||||||
marathon::{machdr, map, pict, shp, term, wad}};
|
marathon::{machdr, map, pict, shp, term, wad}};
|
||||||
use std::{fs,
|
use std::{collections::HashSet,
|
||||||
|
fs,
|
||||||
io::{self, Write}};
|
io::{self, Write}};
|
||||||
|
|
||||||
fn write_chunk(cid: &Ident, cnk: &[u8], eid: u16) -> ResultS<()>
|
fn make_tga(fname: &str, im: &impl Image) -> ResultS<()>
|
||||||
{
|
{
|
||||||
let fname = format!("out/{:04}{}.bin", eid, mac_roman_conv(cid));
|
let out = fs::File::create(fname)?;
|
||||||
|
let mut out = io::BufWriter::new(out);
|
||||||
|
write_tga(&mut out, im)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_chunk(opt: &Options, cid: &Ident, cnk: &[u8], eid: u16) -> ResultS<()>
|
||||||
|
{
|
||||||
|
let cid = mac_roman_conv(cid);
|
||||||
|
let fname = format!("{}/{:04}{}.bin", opt.out_dir, eid, cid);
|
||||||
let out = fs::File::create(&fname)?;
|
let out = fs::File::create(&fname)?;
|
||||||
let mut out = io::BufWriter::new(out);
|
let mut out = io::BufWriter::new(out);
|
||||||
out.write(cnk)?;
|
out.write(cnk)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_chunk(cid: &Ident, cnk: &[u8], eid: u16) -> ResultS<()>
|
fn make_yaml(data: &impl serde::Serialize) -> ResultS<()>
|
||||||
{
|
{
|
||||||
|
serde_yaml::to_writer(io::stdout(), &data)?;
|
||||||
|
println!();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dump_chunk(opt: &Options, cid: &Ident, cnk: &[u8], eid: u16) -> ResultS<()>
|
||||||
|
{
|
||||||
|
if opt.wad_all {
|
||||||
|
make_chunk(opt, cid, cnk, eid)?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
match cid {
|
match cid {
|
||||||
b"PICT" => {
|
b"PICT" => {
|
||||||
let im = pict::load_pict(cnk)?;
|
if opt.wad_chunks.contains(cid) {
|
||||||
eprintln!("entry {} has PICT {}x{}", eid, im.w(), im.h());
|
let im = pict::load_pict(cnk)?;
|
||||||
let out = fs::File::create(&format!("out/{}.ppm", eid))?;
|
make_tga(&format!("{}/pict_{}.tga", opt.out_dir, eid), &im)?;
|
||||||
let mut out = io::BufWriter::new(out);
|
}
|
||||||
write_ppm(&mut out, &im)?;
|
|
||||||
}
|
}
|
||||||
b"Minf" => {
|
b"Minf" => {
|
||||||
let minf = map::Minf::chunk(cnk)?;
|
if opt.wad_chunks.contains(cid) {
|
||||||
eprintln!("entry {} has {:#?}", eid, minf);
|
make_yaml(&map::Minf::chunk(cnk)?)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
b"EPNT" => {
|
b"EPNT" => {
|
||||||
let epnt = map::Endpoint::chunk(cnk)?;
|
if opt.wad_chunks.contains(cid) {
|
||||||
eprintln!("entry {} has EPNT {:#?}", eid, epnt);
|
make_yaml(&map::Endpoint::chunk(cnk)?)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
b"PNTS" => {
|
b"PNTS" => {
|
||||||
let epnt = map::Point::chunk(cnk)?;
|
if opt.wad_chunks.contains(cid) {
|
||||||
eprintln!("entry {} has PNTS {:#?}", eid, epnt);
|
make_yaml(&map::Point::chunk(cnk)?)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
b"LINS" => {
|
b"LINS" => {
|
||||||
let line = map::Line::chunk(cnk)?;
|
if opt.wad_chunks.contains(cid) {
|
||||||
eprintln!("entry {} has LINS {:#?}", eid, line);
|
make_yaml(&map::Line::chunk(cnk)?)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
b"SIDS" => {
|
b"SIDS" => {
|
||||||
let line = map::Side::chunk(cnk)?;
|
if opt.wad_chunks.contains(cid) {
|
||||||
eprintln!("entry {} has SIDS {:#?}", eid, line);
|
make_yaml(&map::Side::chunk(cnk)?)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
b"term" => {
|
b"term" => {
|
||||||
let term = term::Terminal::chunk(cnk)?;
|
if opt.wad_chunks.contains(cid) {
|
||||||
eprintln!("entry {} has term {:#?}", eid, term);
|
make_yaml(&term::Terminal::chunk(cnk)?)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cid => {
|
cid => {
|
||||||
write_chunk(cid, cnk, eid)?;
|
if opt.wad_unknown {
|
||||||
|
make_chunk(opt, cid, cnk, eid)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_wad(b: &[u8]) -> ResultS<()>
|
fn process_wad(opt: &Options, b: &[u8]) -> ResultS<()>
|
||||||
{
|
{
|
||||||
let wad = wad::Wad::new(b)?;
|
let wad = wad::Wad::new(b)?;
|
||||||
|
|
||||||
eprintln!("{:#?}", wad);
|
if opt.wad_header {
|
||||||
|
make_yaml(&wad)?;
|
||||||
|
}
|
||||||
|
|
||||||
for (eid, ent) in wad.entries {
|
for (eid, ent) in wad.entries {
|
||||||
for (cid, cnk) in ent.chunks {
|
for (cid, cnk) in ent.chunks {
|
||||||
read_chunk(&cid, cnk, eid)?;
|
dump_chunk(opt, &cid, cnk, eid)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dump_bitmaps(c: &shp::Collection, i: usize) -> ResultS<()>
|
fn dump_bitmaps(opt: &Options, c: &shp::Collection, i: usize) -> ResultS<()>
|
||||||
{
|
{
|
||||||
|
if !opt.shp_bmp {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
for (j, bmp) in c.bmps.iter().enumerate() {
|
for (j, bmp) in c.bmps.iter().enumerate() {
|
||||||
for (k, tab) in c.tabs.iter().enumerate() {
|
if opt.shp_bmp_all {
|
||||||
let fname = format!("out/shape{}_{}_{}.tga", i, j, k);
|
for (k, tab) in c.tabs.iter().enumerate() {
|
||||||
let out = fs::File::create(&fname)?;
|
let fname = format!("{}/shape{}_{}_{}.tga", opt.out_dir, i, j, k);
|
||||||
let mut out = io::BufWriter::new(out);
|
make_tga(&fname, &shp::ImageShp::new(bmp, &tab))?;
|
||||||
write_tga(&mut out, &shp::ImageShp::new(bmp, &tab))?;
|
}
|
||||||
|
} else {
|
||||||
|
let fname = format!("{}/shape{}_{}.tga", opt.out_dir, i, j);
|
||||||
|
make_tga(&fname, &shp::ImageShp::new(bmp, &c.tabs[0]))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_shp(b: &[u8]) -> ResultS<()>
|
fn write_shp_objs(opt: &Options, cl: &shp::Collection) -> ResultS<()>
|
||||||
|
{
|
||||||
|
if opt.shp_tab {
|
||||||
|
make_yaml(&cl.tabs)?;
|
||||||
|
}
|
||||||
|
if opt.shp_frm {
|
||||||
|
make_yaml(&cl.frms)?;
|
||||||
|
}
|
||||||
|
if opt.shp_seq {
|
||||||
|
make_yaml(&cl.seqs)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process_shp(opt: &Options, b: &[u8]) -> ResultS<()>
|
||||||
{
|
{
|
||||||
for (i, cl) in shp::read_shapes(b)?.iter().enumerate() {
|
for (i, cl) in shp::read_shapes(b)?.iter().enumerate() {
|
||||||
if let Some(cl) = &cl.0 {
|
if let Some(cl) = &cl.0 {
|
||||||
dump_bitmaps(cl, i)?;
|
dump_bitmaps(opt, cl, i)?;
|
||||||
eprintln!("<{} lo> {:#?}\n{:#?}", i, cl.frms, cl.seqs);
|
write_shp_objs(opt, cl)?;
|
||||||
}
|
}
|
||||||
if let Some(cl) = &cl.1 {
|
if let Some(cl) = &cl.1 {
|
||||||
dump_bitmaps(cl, i + 100)?;
|
dump_bitmaps(opt, cl, i + 100)?;
|
||||||
eprintln!("<{} hi> {:#?}\n{:#?}", i, cl.frms, cl.seqs);
|
write_shp_objs(opt, cl)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +155,7 @@ fn main() -> ResultS<()>
|
||||||
use argparse::*;
|
use argparse::*;
|
||||||
use memmap::Mmap;
|
use memmap::Mmap;
|
||||||
|
|
||||||
let mut args: Vec<String> = Vec::new();
|
let mut opt: Options = Default::default();
|
||||||
{
|
{
|
||||||
let mut ap = ArgumentParser::new();
|
let mut ap = ArgumentParser::new();
|
||||||
ap.set_description(env!("CARGO_PKG_DESCRIPTION"));
|
ap.set_description(env!("CARGO_PKG_DESCRIPTION"));
|
||||||
|
@ -113,12 +164,58 @@ fn main() -> ResultS<()>
|
||||||
env!("CARGO_PKG_NAME"),
|
env!("CARGO_PKG_NAME"),
|
||||||
env!("CARGO_PKG_VERSION"))),
|
env!("CARGO_PKG_VERSION"))),
|
||||||
"Show the version");
|
"Show the version");
|
||||||
ap.refer(&mut args)
|
ap.refer(&mut opt.shp_tab)
|
||||||
.add_argument("inputs", List, "Input files");
|
.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.inputs)
|
||||||
|
.add_argument("inputs", Collect, "Input files");
|
||||||
ap.parse_args_or_exit();
|
ap.parse_args_or_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
for arg in &args {
|
if opt.shp_bmp_all {
|
||||||
|
opt.shp_bmp = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if opt.out_dir.is_empty() {
|
||||||
|
opt.out_dir = ".".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
if !opt.wad_c_temp.is_empty() {
|
||||||
|
for ctyp in opt.wad_c_temp.split(',') {
|
||||||
|
opt.wad_chunks.insert(c_iden(ctyp.as_bytes(), 0)?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_folder_path(&opt.out_dir)?;
|
||||||
|
|
||||||
|
for arg in &opt.inputs {
|
||||||
let (typ, fna) = if let Some(st) = arg.find(':') {
|
let (typ, fna) = if let Some(st) = arg.find(':') {
|
||||||
arg.split_at(st + 1)
|
arg.split_at(st + 1)
|
||||||
} else {
|
} else {
|
||||||
|
@ -130,8 +227,8 @@ fn main() -> ResultS<()>
|
||||||
let b = c_data(&mm, machdr::try_mac_header(&mm)..)?;
|
let b = c_data(&mm, machdr::try_mac_header(&mm)..)?;
|
||||||
|
|
||||||
match typ {
|
match typ {
|
||||||
"wad:" => process_wad(b),
|
"wad:" => process_wad(&opt, b),
|
||||||
"shp:" => process_shp(b),
|
"shp:" => process_shp(&opt, b),
|
||||||
_ => Err(err_msg("invalid file type specified on commandline")),
|
_ => Err(err_msg("invalid file type specified on commandline")),
|
||||||
}?;
|
}?;
|
||||||
}
|
}
|
||||||
|
@ -139,4 +236,21 @@ fn main() -> ResultS<()>
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct Options
|
||||||
|
{
|
||||||
|
inputs: Vec<String>,
|
||||||
|
out_dir: String,
|
||||||
|
shp_tab: bool,
|
||||||
|
shp_bmp: bool,
|
||||||
|
shp_bmp_all: bool,
|
||||||
|
shp_frm: bool,
|
||||||
|
shp_seq: bool,
|
||||||
|
wad_all: bool,
|
||||||
|
wad_unknown: bool,
|
||||||
|
wad_header: bool,
|
||||||
|
wad_chunks: HashSet<Ident>,
|
||||||
|
wad_c_temp: String,
|
||||||
|
}
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::{durandal::{bin::*, chunk::*, err::*, fx32::*,
|
||||||
text::mac_roman_conv},
|
text::mac_roman_conv},
|
||||||
marathon::xfer::TransferMode};
|
marathon::xfer::TransferMode};
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
|
use serde::Serialize;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
impl Chunked<Point> for Point
|
impl Chunked<Point> for Point
|
||||||
|
@ -118,13 +119,14 @@ impl Chunker<Minf> for Minf
|
||||||
|
|
||||||
type Unit = i16;
|
type Unit = i16;
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
pub struct Point
|
pub struct Point
|
||||||
{
|
{
|
||||||
x: Unit,
|
x: Unit,
|
||||||
y: Unit,
|
y: Unit,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct Endpoint
|
pub struct Endpoint
|
||||||
{
|
{
|
||||||
flags: EndpFlags,
|
flags: EndpFlags,
|
||||||
|
@ -134,7 +136,7 @@ pub struct Endpoint
|
||||||
support: u16,
|
support: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct Line
|
pub struct Line
|
||||||
{
|
{
|
||||||
flags: LineFlags,
|
flags: LineFlags,
|
||||||
|
@ -149,14 +151,14 @@ pub struct Line
|
||||||
poly_b: u16,
|
poly_b: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct SideTex
|
pub struct SideTex
|
||||||
{
|
{
|
||||||
offs: Point,
|
offs: Point,
|
||||||
tex_id: ObjID,
|
tex_id: ObjID,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct Side
|
pub struct Side
|
||||||
{
|
{
|
||||||
stype: u16,
|
stype: u16,
|
||||||
|
@ -176,7 +178,7 @@ pub struct Side
|
||||||
shade: Fx32,
|
shade: Fx32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct Minf
|
pub struct Minf
|
||||||
{
|
{
|
||||||
env_code: u16,
|
env_code: u16,
|
||||||
|
@ -189,6 +191,7 @@ pub struct Minf
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
|
#[derive(Serialize)]
|
||||||
pub struct EndpFlags: u16
|
pub struct EndpFlags: u16
|
||||||
{
|
{
|
||||||
const Solid = 0x00_01;
|
const Solid = 0x00_01;
|
||||||
|
@ -198,6 +201,7 @@ bitflags! {
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
|
#[derive(Serialize)]
|
||||||
pub struct LineFlags: u16
|
pub struct LineFlags: u16
|
||||||
{
|
{
|
||||||
const TransSide = 0x02_00;
|
const TransSide = 0x02_00;
|
||||||
|
@ -210,6 +214,7 @@ bitflags! {
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
|
#[derive(Serialize)]
|
||||||
pub struct SideFlags: u16
|
pub struct SideFlags: u16
|
||||||
{
|
{
|
||||||
const Status = 0x00_01;
|
const Status = 0x00_01;
|
||||||
|
@ -224,6 +229,7 @@ bitflags! {
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
|
#[derive(Serialize)]
|
||||||
pub struct EnvFlags: u16
|
pub struct EnvFlags: u16
|
||||||
{
|
{
|
||||||
const Vacuum = 0x00_01;
|
const Vacuum = 0x00_01;
|
||||||
|
@ -243,6 +249,7 @@ bitflags! {
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
|
#[derive(Serialize)]
|
||||||
pub struct EntFlags: u32
|
pub struct EntFlags: u32
|
||||||
{
|
{
|
||||||
const Solo = 0x00_01;
|
const Solo = 0x00_01;
|
||||||
|
@ -257,6 +264,7 @@ bitflags! {
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
|
#[derive(Serialize)]
|
||||||
pub struct MsnFlags: u16
|
pub struct MsnFlags: u16
|
||||||
{
|
{
|
||||||
const Extermination = 0x00_01;
|
const Extermination = 0x00_01;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
use crate::{durandal::{bin::*, err::*, fx32::*, image::*, text::*},
|
use crate::{durandal::{bin::*, err::*, fx32::*, image::*, text::*},
|
||||||
marathon::xfer::TransferMode};
|
marathon::xfer::TransferMode};
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
fn color(b: &[u8]) -> ResultS<(usize, ColorShp)>
|
fn color(b: &[u8]) -> ResultS<(usize, ColorShp)>
|
||||||
{
|
{
|
||||||
|
@ -313,7 +314,7 @@ impl Color for ColorShp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, Serialize)]
|
||||||
pub enum ColorShp
|
pub enum ColorShp
|
||||||
{
|
{
|
||||||
Translucent,
|
Translucent,
|
||||||
|
@ -342,7 +343,7 @@ pub struct ImageShp<'a, 'b>
|
||||||
clut: &'b [ColorShp],
|
clut: &'b [ColorShp],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct Frame
|
pub struct Frame
|
||||||
{
|
{
|
||||||
flags: FrameFlags,
|
flags: FrameFlags,
|
||||||
|
@ -356,7 +357,7 @@ pub struct Frame
|
||||||
wrl_y: i16,
|
wrl_y: i16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct Sequence
|
pub struct Sequence
|
||||||
{
|
{
|
||||||
name: String,
|
name: String,
|
||||||
|
@ -393,6 +394,7 @@ bitflags! {
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
|
#[derive(Serialize)]
|
||||||
pub struct FrameFlags: u16
|
pub struct FrameFlags: u16
|
||||||
{
|
{
|
||||||
const Obscure = 0x20_00;
|
const Obscure = 0x20_00;
|
||||||
|
@ -402,7 +404,7 @@ bitflags! {
|
||||||
}
|
}
|
||||||
|
|
||||||
c_enum! {
|
c_enum! {
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub enum CollectionType: u16
|
pub enum CollectionType: u16
|
||||||
{
|
{
|
||||||
0 => Unused,
|
0 => Unused,
|
||||||
|
@ -414,7 +416,7 @@ c_enum! {
|
||||||
}
|
}
|
||||||
|
|
||||||
c_enum! {
|
c_enum! {
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub enum ViewType: u16
|
pub enum ViewType: u16
|
||||||
{
|
{
|
||||||
1 => Anim,
|
1 => Anim,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::durandal::{bin::*, chunk::*, err::*, text::*};
|
use crate::durandal::{bin::*, chunk::*, err::*, text::*};
|
||||||
|
use serde::Serialize;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
fn read_group(b: &[u8], text: &[u8]) -> ResultS<Group>
|
fn read_group(b: &[u8], text: &[u8]) -> ResultS<Group>
|
||||||
|
@ -78,7 +79,7 @@ impl Chunker<Vec<Terminal>> for Terminal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct Terminal
|
pub struct Terminal
|
||||||
{
|
{
|
||||||
lines: u16,
|
lines: u16,
|
||||||
|
@ -86,7 +87,7 @@ pub struct Terminal
|
||||||
faces: Vec<Face>,
|
faces: Vec<Face>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct Face
|
pub struct Face
|
||||||
{
|
{
|
||||||
start: usize,
|
start: usize,
|
||||||
|
@ -94,6 +95,7 @@ pub struct Face
|
||||||
color: u16,
|
color: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
pub struct Group
|
pub struct Group
|
||||||
{
|
{
|
||||||
ttype: GroupType,
|
ttype: GroupType,
|
||||||
|
@ -103,7 +105,7 @@ pub struct Group
|
||||||
}
|
}
|
||||||
|
|
||||||
c_enum! {
|
c_enum! {
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub enum GroupType: u16
|
pub enum GroupType: u16
|
||||||
{
|
{
|
||||||
0 => Logon,
|
0 => Logon,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! Marathon Wad format handling.
|
//! Marathon Wad format handling.
|
||||||
|
|
||||||
use crate::durandal::{bin::*, err::*, text::mac_roman_conv};
|
use crate::durandal::{bin::*, err::*, text::mac_roman_conv};
|
||||||
|
use serde::Serialize;
|
||||||
use std::{collections::BTreeMap, fmt};
|
use std::{collections::BTreeMap, fmt};
|
||||||
|
|
||||||
impl Wad<'_>
|
impl Wad<'_>
|
||||||
|
@ -85,18 +86,19 @@ pub struct Entry<'a>
|
||||||
pub appdata: &'a [u8],
|
pub appdata: &'a [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct Wad<'a>
|
pub struct Wad<'a>
|
||||||
{
|
{
|
||||||
wadver: Ver,
|
wadver: Ver,
|
||||||
dataver: u16,
|
dataver: u16,
|
||||||
origname: String,
|
origname: String,
|
||||||
appsize: usize,
|
appsize: usize,
|
||||||
|
#[serde(skip)]
|
||||||
pub entries: EntryMap<'a>,
|
pub entries: EntryMap<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
c_enum! {
|
c_enum! {
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub enum Ver: u16
|
pub enum Ver: u16
|
||||||
{
|
{
|
||||||
0 => Base,
|
0 => Base,
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use crate::durandal::err::*;
|
use crate::durandal::err::*;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
c_enum! {
|
c_enum! {
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub enum TransferMode: u16
|
pub enum TransferMode: u16
|
||||||
{
|
{
|
||||||
0 => Normal,
|
0 => Normal,
|
||||||
|
|
Loading…
Reference in New Issue