diff --git a/src/Tools/cdtypes/src/cd/sector.rs b/src/Tools/cdtypes/src/cd/sector.rs index 4410a7b4..4a055660 100644 --- a/src/Tools/cdtypes/src/cd/sector.rs +++ b/src/Tools/cdtypes/src/cd/sector.rs @@ -115,4 +115,14 @@ impl Sector { Sector::CDXAAudio(_) => () } } + + pub fn finalize(&mut self) { + match self { + Sector::Audio(_) => (), + Sector::Empty(_) => (), + Sector::CDData(sector) => sector.finalize(), + Sector::CDXAData(sector) => sector.finalize(), + Sector::CDXAAudio(sector) => sector.finalize(), + } + } } diff --git a/src/Tools/cdtypes/src/types/sector.rs b/src/Tools/cdtypes/src/types/sector.rs index f3d23541..c8e49cff 100644 --- a/src/Tools/cdtypes/src/types/sector.rs +++ b/src/Tools/cdtypes/src/types/sector.rs @@ -80,6 +80,10 @@ impl Header { self.sector = sector; } + pub fn get_time(&self) -> Time { + Time::from((self.minute.clone(), self.second.clone(), self.sector.clone())) + } + pub fn get_mode(&self) -> Result { match self.mode { 0 => Ok(HeaderMode::Mode0), diff --git a/src/Tools/psxcdgen_ex/src/encoder/builder.rs b/src/Tools/psxcdgen_ex/src/encoder/builder.rs new file mode 100644 index 00000000..1bbd6687 --- /dev/null +++ b/src/Tools/psxcdgen_ex/src/encoder/builder.rs @@ -0,0 +1,15 @@ +use cdtypes::types::{sector::*, time::Time}; + +pub fn create_xa_data_for_data(lba: usize, data: &[u8; Mode2Form1::DATA_SIZE]) -> Mode2Form1 { + let mut sector = Mode2Form1::new(); + + sector.header.set_time(Time::from_lba(lba)); + sector.sub_header.sub_mode.set_data(); + sector.data = *data; + + sector +} + +pub fn create_xa_data_zero(lba: usize) -> Mode2Form1 { + create_xa_data_for_data(lba, &[0u8; Mode2Form1::DATA_SIZE]) +} \ No newline at end of file diff --git a/src/Tools/psxcdgen_ex/src/encoder/mod.rs b/src/Tools/psxcdgen_ex/src/encoder/mod.rs index 19929cd1..8f7ff676 100644 --- a/src/Tools/psxcdgen_ex/src/encoder/mod.rs +++ b/src/Tools/psxcdgen_ex/src/encoder/mod.rs @@ -1,5 +1,6 @@ -use super::{file_writer::SectorWriter, types::{CDDesc, Error}}; +use super::{file_writer::{Sector, SectorWriter}, types::{CDDesc, Error}}; pub mod psx; +pub mod builder; pub type EncoderFunction = fn(CDDesc, &mut dyn SectorWriter) -> Result<(), Error>; \ No newline at end of file diff --git a/src/Tools/psxcdgen_ex/src/encoder/psx.rs b/src/Tools/psxcdgen_ex/src/encoder/psx.rs index 1e67ddca..22281842 100644 --- a/src/Tools/psxcdgen_ex/src/encoder/psx.rs +++ b/src/Tools/psxcdgen_ex/src/encoder/psx.rs @@ -1,5 +1,18 @@ -use super::{SectorWriter, {CDDesc, Error}}; +use super::{*, Sector, SectorWriter, {CDDesc, Error}}; +use super::super::types::{layout::Layout, SystemArea}; + +pub fn encode_psx_image(cd_desc: CDDesc, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> { + for element in cd_desc.get_memory_layout() { + match element { + Layout::SystemArea(system_area) => process_system_area(&system_area.borrow(), sec_writer)?, + _ => () + } + } -pub fn encode_psx_image(_: CDDesc, _: &mut dyn SectorWriter) -> Result<(), Error> { Err(Error::not_implemented("encode_psx_image")) +} + +fn process_system_area(system_area: &SystemArea, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> { + + sec_writer.write(Sector::CDXAData(builder::create_xa_data_zero(system_area.properties.lba))) } \ No newline at end of file diff --git a/src/Tools/psxcdgen_ex/src/file_writer/bin_cue.rs b/src/Tools/psxcdgen_ex/src/file_writer/bin_cue.rs index c886f8f8..4fab7fe5 100644 --- a/src/Tools/psxcdgen_ex/src/file_writer/bin_cue.rs +++ b/src/Tools/psxcdgen_ex/src/file_writer/bin_cue.rs @@ -1,5 +1,5 @@ use std::io::Write; -use super::{Error, SectorWriter}; +use super::{Error, Sector, SectorWriter}; pub struct BinCueWriter { _bin_out: std::boxed::Box, @@ -13,10 +13,16 @@ impl BinCueWriter { } impl SectorWriter for BinCueWriter { - fn write(&mut self) -> Result<(), Error> { - self.sector_count += 1; + fn write(&mut self, mut sector: Sector) -> Result<(), Error> { + self.finalize_sector(&mut sector)?; - Err(Error::not_implemented("write for BinCueWriter")) + match sector { + Sector::Empty(_) => Err(Error::not_implemented("Empty sector encoding")), + Sector::Audio(_) => Err(Error::not_implemented("Audio sector encoding")), + Sector::CDData(_) => Err(Error::not_implemented("CD Data sector encoding")), + Sector::CDXAData(_) => Err(Error::not_implemented("CD XA Data sector encoding")), + Sector::CDXAAudio(_) => Err(Error::not_implemented("CD XA Audio sector encoding")) + } } fn sector_written_count(&self) -> usize { diff --git a/src/Tools/psxcdgen_ex/src/file_writer/mod.rs b/src/Tools/psxcdgen_ex/src/file_writer/mod.rs index 2b2e453f..73f9cbee 100644 --- a/src/Tools/psxcdgen_ex/src/file_writer/mod.rs +++ b/src/Tools/psxcdgen_ex/src/file_writer/mod.rs @@ -1,5 +1,7 @@ pub mod bin_cue; +pub use cdtypes::cd::sector::Sector; + use super::{encoder::EncoderFunction, types::CDDesc}; use bin_cue::BinCueWriter; use std::path::PathBuf; @@ -10,8 +12,21 @@ pub enum ImageType { } pub trait SectorWriter { - fn write(&mut self) -> Result<(), Error>; - fn sector_written_count(&self) -> usize; + fn write(&mut self, sector: Sector) -> Result<(), Error>; + fn sector_written_count(&self) -> usize; + + fn finalize_sector(&self, sector: &mut Sector) -> Result<(), Error> { + let sectors_written = self.sector_written_count(); + if let Some(header) = sector.get_header() { + let sector_lba = header.get_time().to_lba(); + if sector_lba != sectors_written { + return Err(Error::from_text(format!("Header LBA {} doesn't match written sector count of {}", sector_lba, sectors_written))); + } + } + + sector.finalize(); + Ok(()) + } } pub fn write_image(cd_desc: CDDesc, encoder: EncoderFunction, image_type: ImageType, output_path: PathBuf) -> Result<(), Error> {