Encode first sector
This commit is contained in:
parent
1a3da8f412
commit
4b2ed4b3de
|
@ -115,4 +115,14 @@ impl Sector {
|
||||||
Sector::CDXAAudio(_) => ()
|
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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,10 @@ impl Header {
|
||||||
self.sector = sector;
|
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<HeaderMode, u8> {
|
pub fn get_mode(&self) -> Result<HeaderMode, u8> {
|
||||||
match self.mode {
|
match self.mode {
|
||||||
0 => Ok(HeaderMode::Mode0),
|
0 => Ok(HeaderMode::Mode0),
|
||||||
|
|
|
@ -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])
|
||||||
|
}
|
|
@ -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 psx;
|
||||||
|
pub mod builder;
|
||||||
|
|
||||||
pub type EncoderFunction = fn(CDDesc, &mut dyn SectorWriter) -> Result<(), Error>;
|
pub type EncoderFunction = fn(CDDesc, &mut dyn SectorWriter) -> Result<(), Error>;
|
|
@ -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"))
|
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)))
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use super::{Error, SectorWriter};
|
use super::{Error, Sector, SectorWriter};
|
||||||
|
|
||||||
pub struct BinCueWriter {
|
pub struct BinCueWriter {
|
||||||
_bin_out: std::boxed::Box<dyn Write>,
|
_bin_out: std::boxed::Box<dyn Write>,
|
||||||
|
@ -13,10 +13,16 @@ impl BinCueWriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SectorWriter for BinCueWriter {
|
impl SectorWriter for BinCueWriter {
|
||||||
fn write(&mut self) -> Result<(), Error> {
|
fn write(&mut self, mut sector: Sector) -> Result<(), Error> {
|
||||||
self.sector_count += 1;
|
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 {
|
fn sector_written_count(&self) -> usize {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
pub mod bin_cue;
|
pub mod bin_cue;
|
||||||
|
|
||||||
|
pub use cdtypes::cd::sector::Sector;
|
||||||
|
|
||||||
use super::{encoder::EncoderFunction, types::CDDesc};
|
use super::{encoder::EncoderFunction, types::CDDesc};
|
||||||
use bin_cue::BinCueWriter;
|
use bin_cue::BinCueWriter;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -10,8 +12,21 @@ pub enum ImageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SectorWriter {
|
pub trait SectorWriter {
|
||||||
fn write(&mut self) -> Result<(), Error>;
|
fn write(&mut self, sector: Sector) -> Result<(), Error>;
|
||||||
fn sector_written_count(&self) -> usize;
|
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> {
|
pub fn write_image(cd_desc: CDDesc, encoder: EncoderFunction, image_type: ImageType, output_path: PathBuf) -> Result<(), Error> {
|
||||||
|
|
Loading…
Reference in New Issue