mirror of
https://github.com/encounter/decomp-toolkit.git
synced 2025-08-04 19:25:44 +00:00
- Transparent NLZSS decompression (add `:nlzss` to path) - Overhaul portions of the analyzer to support more games - Reject some invalid data relocations automatically - Jump table analysis fixes
64 lines
1.8 KiB
Rust
64 lines
1.8 KiB
Rust
use std::{fs, path::PathBuf};
|
|
|
|
use anyhow::{anyhow, Context, Result};
|
|
use argp::FromArgs;
|
|
|
|
use crate::util::{
|
|
file::{open_file, process_rsp},
|
|
IntoCow, ToCow,
|
|
};
|
|
|
|
#[derive(FromArgs, PartialEq, Debug)]
|
|
/// Commands for processing NLZSS-compressed files.
|
|
#[argp(subcommand, name = "nlzss")]
|
|
pub struct Args {
|
|
#[argp(subcommand)]
|
|
command: SubCommand,
|
|
}
|
|
|
|
#[derive(FromArgs, PartialEq, Debug)]
|
|
#[argp(subcommand)]
|
|
enum SubCommand {
|
|
Decompress(DecompressArgs),
|
|
}
|
|
|
|
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
|
/// Decompresses NLZSS-compressed files.
|
|
#[argp(subcommand, name = "decompress")]
|
|
pub struct DecompressArgs {
|
|
#[argp(positional)]
|
|
/// NLZSS-compressed file(s)
|
|
files: Vec<PathBuf>,
|
|
#[argp(option, short = 'o')]
|
|
/// Output file (or directory, if multiple files are specified).
|
|
/// If not specified, decompresses in-place.
|
|
output: Option<PathBuf>,
|
|
}
|
|
|
|
pub fn run(args: Args) -> Result<()> {
|
|
match args.command {
|
|
SubCommand::Decompress(args) => decompress(args),
|
|
}
|
|
}
|
|
|
|
fn decompress(args: DecompressArgs) -> Result<()> {
|
|
let files = process_rsp(&args.files)?;
|
|
let single_file = files.len() == 1;
|
|
for path in files {
|
|
let data = nintendo_lz::decompress(&mut open_file(&path)?)
|
|
.map_err(|e| anyhow!("Failed to decompress '{}' with NLZSS: {}", path.display(), e))?;
|
|
let out_path = if let Some(output) = &args.output {
|
|
if single_file {
|
|
output.as_path().to_cow()
|
|
} else {
|
|
output.join(path.file_name().unwrap()).into_cow()
|
|
}
|
|
} else {
|
|
path.as_path().to_cow()
|
|
};
|
|
fs::write(out_path.as_ref(), data)
|
|
.with_context(|| format!("Failed to write '{}'", out_path.display()))?;
|
|
}
|
|
Ok(())
|
|
}
|