diff --git a/cz/src/compression.rs b/cz/src/compression.rs index 7990430..80cf2fd 100644 --- a/cz/src/compression.rs +++ b/cz/src/compression.rs @@ -1,7 +1,7 @@ use byteorder::{ReadBytesExt, WriteBytesExt, LE}; use std::{ collections::HashMap, - io::{Cursor, Read, Seek, Write}, + io::{Read, Seek, Write}, }; use crate::binio::BitIo; @@ -362,8 +362,7 @@ fn compress_lzw2(data: &[u8], last: Vec) -> (usize, Vec, Vec) { element = last } - let output_buf = Vec::new(); - let mut bit_io = BitIo::new(output_buf); + let mut bit_io = BitIo::new(vec![0u8; 0xF0000]); let write_bit = |bit_io: &mut BitIo, code: u64| { if code > 0x7FFF { bit_io.write_bit(1, 1); diff --git a/utils/Cargo.toml b/utils/Cargo.toml index 4e726fc..136bb7d 100644 --- a/utils/Cargo.toml +++ b/utils/Cargo.toml @@ -1,9 +1,10 @@ [package] name = "utils" -version = "0.1.2" +version = "0.2.0" edition = "2021" license = "GPL-3.0-or-later" authors.workspace = true +build = "build.rs" [[bin]] name = "czutil" @@ -16,7 +17,10 @@ cz = { path = "../cz/", features = ["png"] } luca_pak = { path = "../luca_pak/" } image = { version = "0.25", default-features = false, features = ["png"] } -clap = { version = "4.5.9", features = ["derive"] } +clap = { version = "4.5", features = ["derive", "error-context"] } + +[build-dependencies] +vergen-git2 = { version = "1.0", features = ["build", "cargo", "rustc", "si"] } [lints] workspace = true diff --git a/utils/build.rs b/utils/build.rs new file mode 100644 index 0000000..98d09a2 --- /dev/null +++ b/utils/build.rs @@ -0,0 +1,17 @@ +use vergen_git2::{BuildBuilder, CargoBuilder, Emitter, Git2Builder, RustcBuilder, SysinfoBuilder}; + +fn main() { + let build = BuildBuilder::all_build().unwrap(); + let cargo = CargoBuilder::all_cargo().unwrap(); + let git2 = Git2Builder::all_git().unwrap(); + let rustc = RustcBuilder::all_rustc().unwrap(); + let si = SysinfoBuilder::all_sysinfo().unwrap(); + + Emitter::default() + .add_instructions(&build).unwrap() + .add_instructions(&cargo).unwrap() + .add_instructions(&git2).unwrap() + .add_instructions(&rustc).unwrap() + .add_instructions(&si).unwrap() + .emit().unwrap(); +} diff --git a/utils/src/bin/czutil.rs b/utils/src/bin/czutil.rs index 673578a..19ed478 100644 --- a/utils/src/bin/czutil.rs +++ b/utils/src/bin/czutil.rs @@ -1,17 +1,22 @@ -use clap::{error::ErrorKind, Error, Parser, Subcommand}; +use clap::{error::ErrorKind, Command, Error, Parser, Subcommand}; use std::{ fs, - path::{Path, PathBuf}, + path::{Path, PathBuf}, process::exit, }; /// Utility to maniuplate CZ image files from the LUCA System game engine by /// Prototype Ltd. #[derive(Parser)] #[command(name = "CZ Utility")] -#[command(version, about, long_about = None)] +#[command(author, version, about, long_about = None, disable_version_flag = true)] +#[command(arg_required_else_help(true))] struct Cli { + /// Show program version information + #[arg(short('V'), long)] + version: bool, + #[command(subcommand)] - command: Commands, + command: Option, } #[derive(Subcommand)] @@ -63,8 +68,24 @@ enum Commands { fn main() { let cli = Cli::parse(); + if cli.version { + println!( + "{}, {} v{}-{}", + env!("CARGO_BIN_NAME"), + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_VERSION"), + &env!("VERGEN_GIT_SHA")[0..=6] + ); + exit(0); + } + + let command = match cli.command { + Some(c) => c, + None => exit(0), + }; + // Check what subcommand was run - match &cli.command { + match &command { Commands::Decode { input, output, diff --git a/utils/src/bin/pakutil.rs b/utils/src/bin/pakutil.rs index 46c7603..66659b2 100644 --- a/utils/src/bin/pakutil.rs +++ b/utils/src/bin/pakutil.rs @@ -3,19 +3,23 @@ use clap::{ Parser, Subcommand, }; use luca_pak::Pak; -use std::{fs, path::PathBuf}; +use std::{fs, path::PathBuf, process::exit}; /// Utility to maniuplate PAK archive files from the LUCA System game engine by /// Prototype Ltd. #[derive(Parser)] #[command(name = "PAK Utility")] -#[command(version, about, long_about = None)] +#[command(author, version, about, long_about = None, disable_version_flag = true)] struct Cli { - #[arg(value_name = "PAK FILE")] - input: PathBuf, + /// Show program version information + #[arg(short('V'), long)] + version: bool, + + #[arg(value_name = "PAK FILE", required_unless_present("version"))] + input: Option, #[command(subcommand)] - command: Commands, + command: Option, } #[derive(Subcommand)] @@ -59,12 +63,30 @@ enum Commands { fn main() { let cli = Cli::parse(); - let mut pak = match Pak::open(&cli.input) { + if cli.version { + println!( + "{}, {} v{}-{}", + env!("CARGO_BIN_NAME"), + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_VERSION"), + &env!("VERGEN_GIT_SHA")[0..=6] + ); + exit(0); + } + + let mut pak = match Pak::open(&cli.input.unwrap()) { Ok(pak) => pak, Err(err) => fmt_error(&format!("Could not open PAK file: {}", err)).exit(), }; - match cli.command { + let command = match cli.command { + Some(c) => c, + None => { + exit(0); + }, + }; + + match command { Commands::Extract { output } => { if output.exists() && !output.is_dir() { fmt_error("The output given was not a directory").exit() @@ -74,7 +96,11 @@ fn main() { for entry in pak.entries() { let mut outpath = output.clone(); - outpath.push(entry.display_name()); + if let Some(n) = entry.name() { + outpath.push(n); + } else { + outpath.push(entry.index().to_string()) + } entry.save(&outpath).unwrap(); } }