Prepare LeadOut-Support
This commit is contained in:
parent
d1321b133f
commit
4b4085007d
|
@ -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);
|
||||
|
|
|
@ -13,11 +13,12 @@ pub struct Configuration {
|
|||
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}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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> {
|
||||
|
@ -377,14 +361,17 @@ fn process_file(file: &File, sec_writer: &mut dyn SectorWriter) -> Result<(), Er
|
|||
}
|
||||
}
|
||||
|
||||
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()?;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue