Integrate all the progress into master #6

Merged
jaby merged 595 commits from ToolBox into main 2025-01-01 13:17:44 +00:00
5 changed files with 73 additions and 34 deletions
Showing only changes of commit 4b4085007d - Show all commits

View File

@ -25,6 +25,10 @@ impl Time {
Time{minute: 0, second: 2, sector: 0}
}
pub const fn from_mss(minute: u8, second: u8, sector: u8) -> Time {
Time{minute, second, sector}
}
pub fn add_sectors(&mut self, sector: usize) -> Result<(), Error> {
let sector = self.sector as usize + sector;
let second = self.second as usize + (sector/Self::MAX_SECTORS);

View File

@ -9,15 +9,16 @@ pub enum LZ4State {
}
pub struct Configuration {
pub publisher: Option<String>,
pub license_path: Option<PathBuf>,
pub root: Directory,
pub cd_audio_files: Vec<PathBuf>,
pub publisher: Option<String>,
pub license_path: Option<PathBuf>,
pub root: Directory,
pub cd_audio_files: Vec<PathBuf>,
pub lead_out_sectors: Option<usize>,
}
impl Configuration {
pub fn new() -> Configuration {
Configuration{publisher: None, license_path: None, root: Directory::new("root", false), cd_audio_files: Vec::new()}
Configuration{publisher: None, license_path: None, root: Directory::new("root", false), cd_audio_files: Vec::new(), lead_out_sectors: None}
}
}

View File

@ -1,5 +1,6 @@
use cdtypes::types::time::Time;
use std::path::PathBuf;
use tool_helper::{format_if_error, path_with_env_from, string_with_env_from};
use tool_helper::{format_if_error, path_with_env_from, print_warning, string_with_env_from};
use crate::config_reader::Directory;
use super::{CommonProperties, Configuration, Error, File, FileKind, LZ4State};
@ -27,11 +28,23 @@ pub fn parse(xml: String) -> Result<Configuration, Error> {
}
fn parse_iso_project(iso_project: roxmltree::Node, config: &mut Configuration) -> Result<(), Error> {
let mut parsed_track = false;
for node in iso_project.children() {
if node.is_element() {
match node.tag_name().name() {
"Description" => parse_description(node, config),
"Track" => parse_track(node, config),
"Track" => {
if !parsed_track {
parsed_track = true;
parse_track(node, config)
}
else {
print_warning("Found more than 1 track. Track will be ignored".to_owned());
Ok(())
}
},
"CD_Audio" => parse_cd_audio(node, config),
_ => Ok(())
}?;
@ -125,6 +138,38 @@ fn parse_track(track: roxmltree::Node, config: &mut Configuration) -> Result<(),
Ok(())
}
fn get_lead_out_sectors(track: roxmltree::Node) -> Result<Option<usize>, Error> {
const ATTRIBUTE_NAME:&'static str = "lead-out";
const MIN_OPTION_NAME:&'static str = "minutes";
const SECOND_OPTION_NAME:&'static str = "seconds";
const SECTOR_OPTION_NAME:&'static str = "sectors";
fn parse_split<'a>(who: &'a str, str_opt: Option<&'a str>) -> Result<u8, Error> {
match str_opt.unwrap_or("0").parse::<u8>() {
Ok(num) => Ok(num),
Err(error) => Err(Error::from_text(format!("Failed converting \"{}\" option for \"Track\" attribute \"{}\": {}", who, ATTRIBUTE_NAME, error)))
}
}
//---------------------------------------------------------------------
if let Some(length_str) = track.attribute(ATTRIBUTE_NAME) {
let mut pieces = length_str.split(':');
let (mins, seconds, sectors) = (
parse_split(MIN_OPTION_NAME, pieces.next())?,
parse_split(SECOND_OPTION_NAME, pieces.next())?,
parse_split(SECTOR_OPTION_NAME, pieces.next())?
);
Ok(Some(Time::from_mss(mins, seconds, sectors).as_sectors()))
}
else {
Ok(None)
}
}
config.lead_out_sectors = get_lead_out_sectors(track)?;
parse_file_system(track, &mut config.root, false)
}

View File

@ -121,11 +121,7 @@ pub fn encode_psx_image(cd_desc: &CDDesc, sec_writer: &mut dyn SectorWriter) ->
fn process_system_area(system_area: &SystemArea, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
fn write_license_file(sec_writer: &mut dyn SectorWriter, mut license_file: BufferedInputFile) -> Result<(), Error> {
fn write_data_zeros(sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
for _ in 0..4 {
sec_writer.write_cd_xa_data(builder::create_xa_data_zero())?;
}
Ok(())
write_dummy(sec_writer, 4)
}
fn write_license_string(sec_writer: &mut dyn SectorWriter, license_file: &mut BufferedInputFile) -> Result<(), Error> {
@ -206,11 +202,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());
for _ in 0..SYSTEM_AREA_SECTOR_COUNT {
sec_writer.write_cd_xa_data(builder::create_xa_data_zero())?;
}
Ok(())
write_dummy(sec_writer, SYSTEM_AREA_SECTOR_COUNT)
}
}
@ -323,11 +315,7 @@ fn process_directory_record(dir: &Directory, sec_writer: &mut dyn SectorWriter)
}
let extended_sector_count = sector_count_mode2_form1(dir.properties.borrow().get_padded_size()) - dir_record_sector_count;
for _ in 0..extended_sector_count {
sec_writer.write_cd_xa_data(builder::create_xa_data_zero())?;
}
Ok(())
write_dummy(sec_writer, extended_sector_count)
}
fn process_file(file: &File, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
@ -340,11 +328,7 @@ fn process_file(file: &File, sec_writer: &mut dyn SectorWriter) -> Result<(), Er
}
let extended_sector_count = sector_count_mode2_form1(padded_size) - content_sector_count;
for _ in 0..extended_sector_count {
sec_writer.write_cd_xa_data(builder::create_xa_data_zero())?;
}
Ok(())
write_dummy(sec_writer, extended_sector_count)
}
fn process_cd_xa_file(content: &Vec<RawData>, sec_writer: &mut dyn SectorWriter, padded_size: usize) -> Result<(), Error> {
@ -370,21 +354,24 @@ fn process_file(file: &File, sec_writer: &mut dyn SectorWriter) -> Result<(), Er
}
match &file.content {
FileType::Regular(raw) => process_regular_file(raw, sec_writer, file.properties.get_padded_size()),
FileType::XAAudio(raw) => process_cd_xa_file(raw, sec_writer, file.properties.get_padded_size()),
FileType::Main(_, _) => Err(Error::from_str("Trying to encode an unprocessed main file")),
FileType::Overlay(_, _) => Err(Error::from_str("Trying to encode an unprocessed overlay file")),
FileType::Regular(raw) => process_regular_file(raw, sec_writer, file.properties.get_padded_size()),
FileType::XAAudio(raw) => process_cd_xa_file(raw, sec_writer, file.properties.get_padded_size()),
FileType::Main(_, _) => Err(Error::from_str("Trying to encode an unprocessed main file")),
FileType::Overlay(_, _) => Err(Error::from_str("Trying to encode an unprocessed overlay file")),
}
}
fn process_end_dummy_section(padding: usize, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
for _ in 0..sector_count_mode2_form1(padding) {
fn write_dummy(sec_writer: &mut dyn SectorWriter, sectors: usize) -> Result<(), Error> {
for _ in 0..sectors {
sec_writer.write_cd_xa_data(builder::create_xa_data_zero())?;
}
Ok(())
}
fn process_end_dummy_section(padding: usize, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
write_dummy(sec_writer, sector_count_mode2_form1(padding))
}
fn process_cd_da(cd_da_tracks: &Vec<Vec<AudioSample>>, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
for cd_da_track in cd_da_tracks {
sec_writer.cd_da_start()?;

View File

@ -24,6 +24,7 @@ pub struct CDDesc {
pub(super) root: SharedPtr<Directory>,
pub(super) cd_da_tracks: Vec<Vec<AudioSample>>,
pub(super) vol_sector_count: usize,
pub(super) lead_out_sectors: Option<usize>,
pub(super) end_dummy_padding: usize
}
@ -37,6 +38,7 @@ impl CDDesc {
root: new_shared_ptr(root),
cd_da_tracks: Vec::new(),
vol_sector_count: 0,
lead_out_sectors: None,
end_dummy_padding: 0
},
Err(error) => panic!("Creating root directory failed with: {}", error)