Integrate all the progress into master #6

Merged
jaby merged 595 commits from ToolBox into main 2025-01-01 13:17:44 +00:00
9 changed files with 78 additions and 87 deletions
Showing only changes of commit d4d3340f58 - Show all commits

View File

@ -3,7 +3,7 @@ PKG_OUTPUT ?= $(REGION)/$(ARTIFACT).pkg
$(CD_OUTPUT): always
@mkdir -p $(REGION)
psxcdgen_ex --list $(REGION)/$(ARTIFACT).lba -o $(REGION)/$(ARTIFACT) psx bin-cue Config.xml
psxcdgen_ex --list $(REGION)/$(ARTIFACT).lba -o $(REGION)/$(ARTIFACT) bin-cue Config.xml
$(PKG_OUTPUT): always
@mkdir -p $(REGION)

View File

@ -6,40 +6,59 @@ use tool_helper::{BufferedInputFile, format_if_error, open_input_file_buffered,
use std::io::{Read, Seek, SeekFrom};
const ROOT_DIR_NAME:&'static str = "\x00";
const SYSTEM_AREA_SECTOR_COUNT:usize = 16;
const PVD_SECTOR_COUNT:usize = 2;
pub fn calculate_psx_length_for(element: &Layout) -> LengthInfo {
match element {
Layout::SystemArea(_) => LengthInfo{bytes: None, sectors: SYSTEM_AREA_SECTOR_COUNT},
Layout::PVD(_) => LengthInfo{bytes: None, sectors: PVD_SECTOR_COUNT},
Layout::PathTables(root, _) => {
let path_table_size = PathTable::calculate_size_for(root.clone());
LengthInfo{bytes: Some(path_table_size), sectors: sector_count_mode2_form1(path_table_size)}
},
Layout::Directory(dir) => {
let dir = dir.borrow();
let properties = dir.properties.borrow_mut();
let size_bytes = properties.get_padded_size();
pub mod length_of {
use cdtypes::types::helper::{sector_count_mode2_form1, sector_count_mode2_form2};
use crate::types::FileType;
use super::{Directory, File, LengthInfo, PathTable};
pub const SYSTEM_AREA_SECTOR_COUNT:usize = 16;
pub const PVD_SECTOR_COUNT:usize = 2;
return LengthInfo{bytes: Some(size_bytes), sectors: sector_count_mode2_form1(size_bytes)};
},
Layout::File(file) => {
let file = file.borrow();
let fake_size = file.properties.get_padded_size();
pub const fn system_area() -> LengthInfo {
LengthInfo{bytes: None, sectors: SYSTEM_AREA_SECTOR_COUNT}
}
if matches!(file.content, FileType::XAAudio(_)) {
return LengthInfo{bytes: Some(fake_size), sectors: sector_count_mode2_form2(fake_size)};
}
pub const fn pvd() -> LengthInfo {
LengthInfo{bytes: None, sectors: PVD_SECTOR_COUNT}
}
else {
return LengthInfo{bytes: Some(fake_size), sectors: sector_count_mode2_form1(fake_size)};
}
pub fn path_tables(root: &Directory) -> LengthInfo {
let path_table_size = PathTable::calculate_size_for(root);
LengthInfo{bytes: Some(path_table_size), sectors: sector_count_mode2_form1(path_table_size)}
}
pub fn directory(dir: &Directory) -> LengthInfo {
let properties = dir.properties.borrow_mut();
let size_bytes = properties.get_padded_size();
LengthInfo{bytes: Some(size_bytes), sectors: sector_count_mode2_form1(size_bytes)}
}
pub fn file(file: &File) -> LengthInfo {
let fake_size = file.properties.get_padded_size();
if matches!(file.content, FileType::XAAudio(_)) {
LengthInfo{bytes: Some(fake_size), sectors: sector_count_mode2_form2(fake_size)}
}
else {
LengthInfo{bytes: Some(fake_size), sectors: sector_count_mode2_form1(fake_size)}
}
}
}
pub fn calculate_psx_lbas(cd_desc: &mut CDDesc) {
pub fn calculate_length_for(element: &Layout) -> LengthInfo {
match element {
Layout::SystemArea(_) => length_of::system_area(),
Layout::PVD(_) => length_of::pvd(),
Layout::PathTables(root, _) => length_of::path_tables(&root.borrow()),
Layout::Directory(dir) => length_of::directory(&dir.borrow()),
Layout::File(file) => length_of::file(&file.borrow()),
}
}
pub fn calculate_lbas(cd_desc: &mut CDDesc) {
let mut cur_lba = 0;
let track_offset = LBA::FIRST_TRACK_OFFSET;
@ -52,7 +71,7 @@ pub fn calculate_psx_lbas(cd_desc: &mut CDDesc) {
cur_lba + content_sector_size
}
let element_size_info = calculate_psx_length_for(&element);
let element_size_info = calculate_length_for(&element);
match element {
Layout::SystemArea(system_area) => {
let mut system_area = system_area.borrow_mut();
@ -101,7 +120,7 @@ pub fn calculate_psx_lbas(cd_desc: &mut CDDesc) {
}
}
pub fn encode_psx_image(cd_desc: &CDDesc, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
pub fn encode_image(cd_desc: &CDDesc, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
let vol_sector_count = cd_desc.vol_sector_count;
for element in cd_desc.get_memory_layout() {
@ -202,7 +221,7 @@ fn process_system_area(system_area: &SystemArea, sec_writer: &mut dyn SectorWrit
else {
// No license specified - filling it with zeros
print_warning("WARNING: No license file provided. Some emulators (like No$PSX) will not boot this CD.".to_owned());
write_dummy(sec_writer, SYSTEM_AREA_SECTOR_COUNT)
write_dummy(sec_writer, length_of::SYSTEM_AREA_SECTOR_COUNT)
}
}
@ -267,7 +286,7 @@ fn process_path_table(path_table: &PathTable, root_dir: SharedPtr<Directory>, se
let mut path_table_raw_b = vec![0u8; path_table.size_bytes];
validate_path_table(path_table)?;
let path_table = PathTable::collect_member(root_dir);
let path_table = PathTable::collect_member(&root_dir.borrow());
for entry in path_table {
bytes_used += unsafe{update_path_table_entry(std::mem::transmute::<&mut u8, &mut PathTableL>(&mut path_table_raw_l[bytes_used]), std::mem::transmute::<&mut u8, &mut PathTableB>(&mut path_table_raw_b[bytes_used]), entry)?};

View File

@ -1,19 +1,9 @@
use super::{file_writer::{SectorWriter}, types::{CDDesc, Error, layout::Layout}};
use super::{file_writer::SectorWriter, types::{CDDesc, Error}};
pub mod psx;
pub mod cd;
pub mod builder;
pub type LengthCalculatorFunction = fn(&Layout) -> LengthInfo;
pub type LbaCalculatorFunction = fn(&mut CDDesc);
pub type ImageEncoderFunction = fn(&CDDesc, &mut dyn SectorWriter) -> Result<(), Error>;
pub struct LengthInfo {
pub bytes: Option<usize>,
pub sectors: usize,
}
pub struct EncodingFunctions {
pub length_calculator: LengthCalculatorFunction,
pub lba_calculator: LbaCalculatorFunction,
pub encoder: ImageEncoderFunction
}

View File

@ -4,7 +4,7 @@ pub use cdtypes::{cd::sector::Sector, types::*};
use sector::Mode0;
use crate::types::helper::InterleavedXASector;
use super::{encoder::ImageEncoderFunction, types::CDDesc};
use super::{encoder::cd::encode_image, types::CDDesc};
use bin_cue::BinCueWriter;
use clap::ValueEnum;
use std::path::PathBuf;
@ -48,7 +48,7 @@ pub trait SectorWriter {
fn cd_da_start(&mut self) -> Result<(), Error>;
}
pub fn write_image(cd_desc: &CDDesc, encoder: ImageEncoderFunction, image_type: ImageType, mut output_path: PathBuf) -> Result<(), Error> {
pub fn write_image(cd_desc: &CDDesc, image_type: ImageType, mut output_path: PathBuf) -> Result<(), Error> {
match image_type {
ImageType::BinCue => {
output_path.set_extension("bin");
@ -62,7 +62,7 @@ pub fn write_image(cd_desc: &CDDesc, encoder: ImageEncoderFunction, image_type:
let mut writer = BinCueWriter::new(open_output_file(&output_path)?, &output_path)?;
encoder(cd_desc, &mut writer)?;
encode_image(cd_desc, &mut writer)?;
// TODO: Write times here?!
writer.write_cue(open_output_file(&cue_output_path)?)
}

View File

@ -8,7 +8,7 @@ pub mod types;
use crate::types::RawData;
use cdtypes::types::sector::AudioSample;
use config_reader::LZ4State;
use encoder::{LbaCalculatorFunction, LengthCalculatorFunction};
use encoder::cd::{calculate_lbas, calculate_length_for};
use tool_helper::{format_if_error, Output, read_file};
use types::{layout::Layout, CDDesc, Directory, File, FileType, FileSystemMap, Properties, SharedPtr};
use std::path::PathBuf;
@ -24,29 +24,29 @@ struct ContentDumpAlignment {
const DEFAULT_CONTENT_ALIGNMENT:ContentDumpAlignment = ContentDumpAlignment{name: 24, lba_pair: 16, size: 8, ex_size: 8};
pub fn process(config: config_reader::Configuration, calculate_lba: LbaCalculatorFunction) -> Result<(CDDesc, LBAEmbeddedFiles), Error> {
pub fn process(config: config_reader::Configuration) -> Result<(CDDesc, LBAEmbeddedFiles), Error> {
let (mut cd_desc, lba_embedded_files) = parse_configuration(config)?;
calculate_lba(&mut cd_desc);
calculate_lbas(&mut cd_desc);
Ok((cd_desc, lba_embedded_files))
}
pub fn process_files(file_map: FileSystemMap, lba_embedded_files: LBAEmbeddedFiles, length_func: LengthCalculatorFunction) -> Result<(), Error> {
pub fn process_files(file_map: FileSystemMap, lba_embedded_files: LBAEmbeddedFiles) -> Result<(), Error> {
for lba_embedded_file_raw in lba_embedded_files {
let new_content_info = {
let mut lba_embedded_file = lba_embedded_file_raw.borrow_mut();
match &mut lba_embedded_file.content {
FileType::Overlay(content, lba_names) => Some(types::overlay::update_content(content, lba_names, &file_map, length_func)?),
FileType::Main(content, lba_names) => Some(types::overlay::update_content_for_main(content, lba_names, &file_map, length_func)?),
FileType::Overlay(content, lba_names) => Some(types::overlay::update_content(content, lba_names, &file_map)?),
FileType::Main(content, lba_names) => Some(types::overlay::update_content_for_main(content, lba_names, &file_map)?),
_ => None
}
};
if let Some(new_content) = new_content_info {
let old_size_info = length_func(&Layout::File(lba_embedded_file_raw.clone()));
let old_size_info = calculate_length_for(&Layout::File(lba_embedded_file_raw.clone()));
lba_embedded_file_raw.borrow_mut().make_regular(new_content);
let new_size_info = length_func(&Layout::File(lba_embedded_file_raw.clone()));
let new_size_info = calculate_length_for(&Layout::File(lba_embedded_file_raw.clone()));
if new_size_info.sectors != old_size_info.sectors {
let lba_embedded_file = lba_embedded_file_raw.borrow();

View File

@ -1,14 +1,11 @@
use clap::{Parser, ValueEnum};
use psxcdgen_ex::{encoder::{EncodingFunctions, psx::{calculate_psx_lbas, calculate_psx_length_for, encode_psx_image}}, file_writer::{ImageType, write_image}, config_reader};
use clap::Parser;
use psxcdgen_ex::{file_writer::{ImageType, write_image}, config_reader};
use std::path::PathBuf;
use tool_helper::{Error, exit_with_error, read_file_to_string};
#[derive(Parser)]
#[clap(about = "Creates an ISO image from a description file", long_about = None)]
struct CommandLine {
#[clap(value_enum, value_parser, help="Specifies the system for which to create the disc image")]
system_type: SystemType,
#[clap(value_enum, value_parser, help="Specifies the disc image type")]
output_type: ImageType,
@ -22,27 +19,13 @@ struct CommandLine {
input_file: PathBuf,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
enum SystemType {
Psx
}
impl SystemType {
pub fn get_encoding_functions(self) -> EncodingFunctions {
match self {
SystemType::Psx => EncodingFunctions{length_calculator: calculate_psx_length_for, lba_calculator: calculate_psx_lbas, encoder: encode_psx_image}
}
}
}
fn run_main(cmd_line: CommandLine) -> Result<(), Error> {
const PKG_MINIMUM_CONTENT_SIZE:usize = 512*1024;
let encoding_functions = cmd_line.system_type.get_encoding_functions();
let (mut desc, lba_embedded_files) = psxcdgen_ex::process(config_reader::parse_xml(read_file_to_string(&cmd_line.input_file)?)?, encoding_functions.lba_calculator)?;
let (mut desc, lba_embedded_files) = psxcdgen_ex::process(config_reader::parse_xml(read_file_to_string(&cmd_line.input_file)?)?)?;
let file_map = desc.create_file_map();
psxcdgen_ex::process_files(file_map, lba_embedded_files, encoding_functions.length_calculator)?;
psxcdgen_ex::process_files(file_map, lba_embedded_files)?;
let content_size = desc.get_content_size();
if content_size < PKG_MINIMUM_CONTENT_SIZE {
let missing_size = PKG_MINIMUM_CONTENT_SIZE - content_size;
@ -50,7 +33,7 @@ fn run_main(cmd_line: CommandLine) -> Result<(), Error> {
tool_helper::print_warning(format!("Content size {}b smaller then {}b.\nCD will be padded with {}b to work as a .pkg", content_size, PKG_MINIMUM_CONTENT_SIZE, missing_size));
}
write_image(&desc, encoding_functions.encoder, cmd_line.output_type, cmd_line.output_file)?;
write_image(&desc, cmd_line.output_type, cmd_line.output_file)?;
if let Some(list_content_option) = cmd_line.list_content {
psxcdgen_ex::dump_content(&desc, tool_helper::open_output(&list_content_option)?)

View File

@ -54,7 +54,7 @@ impl DirectoryRecordMember {
}
}
pub fn collect_path_table_member(root: SharedPtr<Directory>) -> Vec<PathTableMember> {
pub fn collect_path_table_member(root: &Directory) -> Vec<PathTableMember> {
fn collect_path_table_for(collection: &mut Vec<PathTableMember>, dirs: &Vec<SharedPtr<Directory>>, parent_id: usize) {
let mut cur_dirs = Vec::new();
@ -76,7 +76,6 @@ pub fn collect_path_table_member(root: SharedPtr<Directory>) -> Vec<PathTableMem
}
}
let mut collection = Vec::new();
let root = root.borrow();
collection.push(PathTableMember{name: CURRENT_DIR_NAME.to_owned(), track_rel_lba: root.get_track_rel_lba(), parent_table_id: 1});
collect_path_table_for(&mut collection, &root.dirs, 1);

View File

@ -118,11 +118,11 @@ impl PathTable {
PathTable{lba: LBA::default(), size_bytes: 0}
}
pub fn collect_member(root: SharedPtr<Directory>) -> Vec<helper::PathTableMember> {
pub fn collect_member(root: &Directory) -> Vec<helper::PathTableMember> {
helper::collect_path_table_member(root)
}
pub fn calculate_size_for(root: SharedPtr<Directory>) -> usize {
pub fn calculate_size_for(root: &Directory) -> usize {
let mut size_bytes = 0;
Self::collect_member(root).into_iter().for_each(|element| {

View File

@ -1,6 +1,6 @@
use super::RawData;
use super::{layout::Layout, File, FileSystemMap};
use super::super::encoder::LengthCalculatorFunction;
use super::super::encoder::cd::calculate_length_for;
use std::path::PathBuf;
use no_comment::{IntoWithoutComments as _, languages};
use tool_helper::{bits::{Bit, BitRange}, Error, format_if_error, read_file, read_file_to_string, format_if_error_drop_cause};
@ -57,28 +57,28 @@ pub fn load_for_main(file_name: &str, content: RawData, lba_source: PathBuf) ->
File::new_main(file_name, content, load_lba_names(lba_source)?)
}
pub fn update_content(content: &mut RawData, lba_names: &LBANameVec, file_map: &FileSystemMap, length_func: LengthCalculatorFunction) -> Result<RawData, Error> {
pub fn update_content(content: &mut RawData, lba_names: &LBANameVec, file_map: &FileSystemMap) -> Result<RawData, Error> {
let lba_header = skip_to_lba_header(content);
let lba_header = unsafe{std::slice::from_raw_parts_mut(lba_header.as_mut_ptr() as *mut LBAEntry, lba_names.len())};
for_each_lba_name(lba_names, file_map, length_func, |idx, (lba, bytes), is_lz4| {
for_each_lba_name(lba_names, file_map, |idx, (lba, bytes), is_lz4| {
lba_header[idx].write_entry(lba, bytes, is_lz4)
})?;
Ok(tool_helper::compress::psx_default::lz4(content)?)
}
pub fn update_content_for_main(content: &mut RawData, lba_names: &LBANameVec, file_map: &FileSystemMap, length_func: LengthCalculatorFunction) -> Result<RawData, Error> {
pub fn update_content_for_main(content: &mut RawData, lba_names: &LBANameVec, file_map: &FileSystemMap) -> Result<RawData, Error> {
let lba_header = unsafe{std::slice::from_raw_parts_mut(main::skip_to_lba_area(content).as_mut_ptr() as *mut LBAEntry, lba_names.len())};
for_each_lba_name(lba_names, file_map, length_func, |idx, (lba, bytes), is_lz4| {
for_each_lba_name(lba_names, file_map, |idx, (lba, bytes), is_lz4| {
lba_header[idx].write_entry(lba, bytes, is_lz4)
})?;
Ok(content.clone())
}
fn for_each_lba_name<F: FnMut(usize, (usize, usize), bool) -> Result<(), Error>>(lba_names: &LBANameVec, file_map: &FileSystemMap, length_func: LengthCalculatorFunction, mut functor: F) -> Result<(), Error> {
fn for_each_lba_name<F: FnMut(usize, (usize, usize), bool) -> Result<(), Error>>(lba_names: &LBANameVec, file_map: &FileSystemMap, mut functor: F) -> Result<(), Error> {
let mut idx = 0;
for lba_name in lba_names {
if let Some(file) = file_map.get(lba_name) {
@ -90,7 +90,7 @@ fn for_each_lba_name<F: FnMut(usize, (usize, usize), bool) -> Result<(), Error>>
}
else {
length_func(&Layout::File(file.clone())).bytes
calculate_length_for(&Layout::File(file.clone())).bytes
}
});
let is_lz4 = file_ref.properties.is_lz4;