Basic project suport
This commit is contained in:
parent
e3ed4a3b43
commit
4ea7575057
File diff suppressed because it is too large
Load Diff
|
@ -34,5 +34,8 @@ hound = "3.5.1"
|
|||
paste = "1.0.15"
|
||||
png = "0.17.16"
|
||||
rubato = "0.16.1"
|
||||
serde = {version = "1.0.219", features = ["derive"]}
|
||||
serde_json = "1.0"
|
||||
symphonia = {version = "0.5.4", optional = true, default-features = false}
|
||||
tim_tool = {path = "../tim_tool"}
|
||||
tool_helper = {path = "../tool_helper"}
|
||||
|
|
|
@ -9,13 +9,13 @@ use tool_helper::{Error, Input};
|
|||
#[derive(Args)]
|
||||
pub struct Arguments {
|
||||
#[clap(flatten)]
|
||||
global: super::args::Arguments,
|
||||
pub(crate) global: super::args::Arguments,
|
||||
|
||||
#[clap(long, value_parser, default_value_t, value_name = Point::POINT_VALUE_NAME)]
|
||||
clut_pos: Point,
|
||||
pub(crate) clut_pos: Point,
|
||||
|
||||
#[clap(long, value_parser, default_value_t, value_name = Point::POINT_VALUE_NAME)]
|
||||
tex_pos: Point,
|
||||
pub(crate) tex_pos: Point,
|
||||
}
|
||||
|
||||
pub fn convert(args: Arguments, input: Input, output: &mut dyn Write) -> Result<(), Error> {
|
||||
|
|
|
@ -1,3 +1,67 @@
|
|||
pub mod audio;
|
||||
pub mod images;
|
||||
pub mod nothing;
|
||||
pub mod project;
|
||||
|
||||
use crate::audio::*;
|
||||
use crate::images::*;
|
||||
|
||||
use clap::Subcommand;
|
||||
use std::path::PathBuf;
|
||||
use tool_helper::Error;
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum SubCommands {
|
||||
Nothing,
|
||||
SimpleTIM(reduced_tim::Arguments),
|
||||
TIM(tim::Arguments),
|
||||
VAG(vag::Arguments),
|
||||
XA(xa::Arguments),
|
||||
Project,
|
||||
}
|
||||
|
||||
pub fn run_subcommand(compress_lz4: bool, input_path: Option<PathBuf>, output_path: Option<PathBuf>, sub_command: SubCommands) -> Result<(), Error> {
|
||||
let mut input = tool_helper::open_input(&input_path)?;
|
||||
let mut buffer = Vec::<u8>::new();
|
||||
let mut output_file = tool_helper::open_output(&output_path)?;
|
||||
let dst_buffer = {
|
||||
if compress_lz4 {
|
||||
&mut buffer as &mut dyn std::io::Write
|
||||
}
|
||||
|
||||
else {
|
||||
&mut output_file as &mut dyn std::io::Write
|
||||
}
|
||||
};
|
||||
|
||||
let cmd_result: Result<(), Error> = {
|
||||
match sub_command {
|
||||
SubCommands::Nothing => nothing::copy(&mut input, dst_buffer),
|
||||
SubCommands::SimpleTIM(args) => reduced_tim::convert(args, input, dst_buffer),
|
||||
SubCommands::TIM(args) => tim::convert(args, input, dst_buffer),
|
||||
SubCommands::VAG(args) => audio::vag::convert(args, &output_path, input, dst_buffer),
|
||||
SubCommands::XA(args) => audio::xa::convert(args, input, dst_buffer),
|
||||
SubCommands::Project => project::run_project(input, input_path, &output_path),
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(cmd_error) = cmd_result {
|
||||
if let Some(file_path) = output_path {
|
||||
let _result = std::fs::remove_file(file_path);
|
||||
}
|
||||
|
||||
else {
|
||||
tool_helper::print_warning("Open stream detected! Incomplete file can not be deleted".to_owned());
|
||||
}
|
||||
|
||||
return Err(cmd_error);
|
||||
}
|
||||
|
||||
// We encoded the file to a temporary buffer and now need to write it
|
||||
if compress_lz4 {
|
||||
let buffer = tool_helper::compress::psx_default::lz4(&buffer)?;
|
||||
output_file.write(&buffer)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
use clap::{Parser, Subcommand};
|
||||
use psxfileconv::{audio::{self, *}, images::*, nothing};
|
||||
use clap::Parser;
|
||||
use std::path::PathBuf;
|
||||
use tool_helper::{exit_with_error, Error};
|
||||
use psxfileconv::{SubCommands, run_subcommand};
|
||||
use tool_helper::exit_with_error;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(about = "Converts files to various JabyEngine related file formats", long_about = None)]
|
||||
struct CommandLine {
|
||||
pub struct CommandLine {
|
||||
#[clap(long="lz4", default_value_t=false)]
|
||||
compress_lz4: bool,
|
||||
|
||||
|
@ -19,64 +19,10 @@ struct CommandLine {
|
|||
sub_command: SubCommands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum SubCommands {
|
||||
Nothing,
|
||||
SimpleTIM(reduced_tim::Arguments),
|
||||
TIM(tim::Arguments),
|
||||
VAG(vag::Arguments),
|
||||
XA(xa::Arguments),
|
||||
}
|
||||
|
||||
fn run_main(cmd: CommandLine) -> Result<(), Error> {
|
||||
let mut input = tool_helper::open_input(&cmd.input_file)?;
|
||||
let mut buffer = Vec::<u8>::new();
|
||||
let mut output_file = tool_helper::open_output(&cmd.output_file)?;
|
||||
let dst_buffer = {
|
||||
if cmd.compress_lz4 {
|
||||
&mut buffer as &mut dyn std::io::Write
|
||||
}
|
||||
|
||||
else {
|
||||
&mut output_file as &mut dyn std::io::Write
|
||||
}
|
||||
};
|
||||
|
||||
let cmd_result: Result<(), Error> = {
|
||||
match cmd.sub_command {
|
||||
SubCommands::Nothing => nothing::copy(&mut input, dst_buffer),
|
||||
SubCommands::SimpleTIM(args) => reduced_tim::convert(args, input, dst_buffer),
|
||||
SubCommands::TIM(args) => tim::convert(args, input, dst_buffer),
|
||||
SubCommands::VAG(args) => audio::vag::convert(args, &cmd.output_file, input, dst_buffer),
|
||||
SubCommands::XA(args) => audio::xa::convert(args, input, dst_buffer),
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(cmd_error) = cmd_result {
|
||||
if let Some(file_path) = cmd.output_file {
|
||||
let _result = std::fs::remove_file(file_path);
|
||||
}
|
||||
|
||||
else {
|
||||
tool_helper::print_warning("Open stream detected! Incomplete file can not be deleted".to_owned());
|
||||
}
|
||||
|
||||
return Err(cmd_error);
|
||||
}
|
||||
|
||||
// We encoded the file to a temporary buffer and now need to write it
|
||||
if cmd.compress_lz4 {
|
||||
let buffer = tool_helper::compress::psx_default::lz4(&buffer)?;
|
||||
output_file.write(&buffer)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
match CommandLine::try_parse() {
|
||||
Ok(cmd) => {
|
||||
if let Err(error) = run_main(cmd) {
|
||||
if let Err(error) = run_subcommand(cmd.compress_lz4, cmd.input_file, cmd.output_file, cmd.sub_command) {
|
||||
exit_with_error(error);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
use crate::images::args::{Arguments, ClutAlignment, ColorType};
|
||||
use std::path::PathBuf;
|
||||
use tool_helper::{Error, Input};
|
||||
use tim_tool::logic::{tim::types::Encoding, project::*};
|
||||
|
||||
pub fn run_project(input: Input, input_path: Option<PathBuf>, output_path: &Option<PathBuf>) -> Result<(), Error> {
|
||||
let location_path = if let Some(input_path) = input_path {input_path} else {PathBuf::from(".")};
|
||||
let output_path = if let Some(output_path) = &output_path {
|
||||
let mut output_path = output_path.clone();
|
||||
if output_path.is_file() {
|
||||
output_path.pop();
|
||||
}
|
||||
output_path
|
||||
} else {PathBuf::from(".")};
|
||||
let project = serde_json::from_reader::<Input, Project>(input).map_err(|error|{Error::from_text(format!("Reading project failed: {}", error))})?;
|
||||
|
||||
for job in project.jobs {
|
||||
let args = to_arguments(&job)?;
|
||||
let output_path = {
|
||||
let mut path = output_path.clone();
|
||||
|
||||
path.push(job.name);
|
||||
path.set_extension("img");
|
||||
path
|
||||
};
|
||||
|
||||
let sub_command = crate::SubCommands::SimpleTIM(args);
|
||||
crate::run_subcommand(job.settings.compress, Some(Job::create_file_path(job.file_path, &location_path)), Some(output_path), sub_command)?;
|
||||
// Create .cpp file
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn to_arguments(job: &Job) -> Result<Arguments, Error> {
|
||||
let (semi_transparent, transparent_palette) = get_transparency(&job.settings.transparency);
|
||||
|
||||
return Ok(Arguments {
|
||||
color_depth: get_encoding(&job.settings.encoding),
|
||||
clut_align: get_palette_rect(&job.palette_rect)?,
|
||||
semi_transparent,
|
||||
transparent_palette,
|
||||
});
|
||||
|
||||
fn get_transparency(transparency: &Transparency) -> (bool, bool) {
|
||||
match transparency {
|
||||
Transparency::None => (false, false),
|
||||
Transparency::FirstColor => (false, true),
|
||||
Transparency::PSXSemi => (true, false),
|
||||
Transparency::Both => (true, true),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_encoding(encoding: &Encoding) -> ColorType {
|
||||
match encoding {
|
||||
Encoding::FourBit => ColorType::Clut4,
|
||||
Encoding::EightBit => ColorType::Clut8,
|
||||
Encoding::FullColor => ColorType::Full16,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_palette_rect(rect: &Option<PaletteRect>) -> Result<ClutAlignment, Error> {
|
||||
if let Some(rect) = rect {
|
||||
if rect.size.height == 1 {
|
||||
return Ok(ClutAlignment::Linear);
|
||||
}
|
||||
|
||||
if rect.size.width%16 == 0 {
|
||||
return Ok(ClutAlignment::Block);
|
||||
}
|
||||
|
||||
return Err(Error::from_text(format!("psxfileconv currently only supports linear or block CLUTs with a width of 16px")));
|
||||
}
|
||||
|
||||
Ok(ClutAlignment::None)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue