Parse and write PathTable
This commit is contained in:
parent
6ee4b7103f
commit
469bce16ab
|
@ -1,4 +1,4 @@
|
|||
use cdtypes::types::sector::*;
|
||||
use cdtypes::types::{helper::*, sector::*};
|
||||
|
||||
pub struct SubModeBuilder {
|
||||
sub_mode: SubMode
|
||||
|
@ -38,6 +38,55 @@ pub fn create_xa_data_for<T>(sub_mode: SubMode, data: &T) -> Mode2Form1 {
|
|||
create_xa_data_for_raw(sub_mode, unsafe {std::mem::transmute::<&T, &[u8; Mode2Form1::DATA_SIZE]>(data)})
|
||||
}
|
||||
|
||||
pub fn create_xa_data_for_vec(sub_mode: Option<SubMode>, data: Vec<u8>) -> Vec<Mode2Form1> {
|
||||
let sectors_to_parse = sector_count_mode2_form1(data.len());
|
||||
let mut data = &data[0..data.len()];
|
||||
let mut sectors = vec![Mode2Form1::new(); sectors_to_parse];
|
||||
let sub_mode = {
|
||||
if let Some(sub_mode) = sub_mode {
|
||||
sub_mode
|
||||
}
|
||||
|
||||
else {
|
||||
SubMode::default_form1()
|
||||
}
|
||||
};
|
||||
|
||||
for cur_sector in 0..sectors_to_parse {
|
||||
let mut raw_data = [0u8; Mode2Form1::DATA_SIZE];
|
||||
let sub_mode = {
|
||||
let mut sub_mode = sub_mode.clone();
|
||||
|
||||
if cur_sector + 1 == sectors_to_parse {
|
||||
sub_mode.set_eof();
|
||||
sub_mode.set_eor();
|
||||
}
|
||||
|
||||
sub_mode
|
||||
};
|
||||
|
||||
data = copy_array(&mut raw_data, data);
|
||||
sectors[cur_sector] = create_xa_data_for_raw(sub_mode, &raw_data);
|
||||
}
|
||||
|
||||
sectors
|
||||
}
|
||||
|
||||
pub fn create_xa_data_zero() -> Mode2Form1 {
|
||||
create_xa_data_for_raw(SubMode::default_form1(), &[0u8; Mode2Form1::DATA_SIZE])
|
||||
}
|
||||
|
||||
fn copy_array<'a, T, const SIZE:usize>(dst: &mut [T; SIZE], src: &'a [T]) -> &'a [T] {
|
||||
let data_size = {
|
||||
if src.len() > SIZE {
|
||||
SIZE
|
||||
}
|
||||
|
||||
else {
|
||||
src.len()
|
||||
}
|
||||
};
|
||||
|
||||
unsafe{std::ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), data_size)};
|
||||
&src[data_size..src.len()]
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use super::{file_writer::{Sector, SectorWriter}, types::{CDDesc, Error}};
|
||||
use super::{file_writer::{SectorWriter}, types::{CDDesc, Error}};
|
||||
|
||||
pub mod psx;
|
||||
pub mod builder;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::{*, Sector, SectorWriter, {CDDesc, Error}};
|
||||
use super::{*, SectorWriter, {CDDesc, Error}};
|
||||
use super::super::types::{helper::PathTableMember, layout::Layout, *};
|
||||
use builder::SubModeBuilder;
|
||||
use cdtypes::types::{cdstring::{AString, DString}, date::*, dir_record::DirectoryRecord, helper::sector_count_mode2_form1, path_table::*, pvd as cd_pvd, lsb_msb::*, sector::Mode2Form1};
|
||||
|
@ -72,7 +72,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> {
|
||||
let vol_sector_count = cd_desc.vol_sector_count;
|
||||
|
||||
|
||||
for element in cd_desc.get_memory_layout() {
|
||||
match element {
|
||||
Layout::SystemArea(system_area) => process_system_area(&system_area.borrow(), sec_writer)?,
|
||||
|
@ -93,7 +93,7 @@ fn process_system_area(system_area: &SystemArea, sec_writer: &mut dyn SectorWrit
|
|||
}
|
||||
|
||||
for _ in 0..SYSTEM_AREA_SECTOR_COUNT {
|
||||
sec_writer.write(Sector::CDXAData(builder::create_xa_data_zero()))?;
|
||||
sec_writer.write_cd_xa_data(builder::create_xa_data_zero())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -138,22 +138,41 @@ fn process_pvd(pvd: &PrimaryVolumeDescriptor, path_table: SharedPtr<PathTable>,
|
|||
cd_pvd.cd_xa_id = ['C' as u8, 'D' as u8, '-' as u8, 'X' as u8, 'A' as u8, '0' as u8, '0' as u8, '1' as u8];
|
||||
|
||||
//Write PVD and VDT
|
||||
sec_writer.write(Sector::CDXAData(builder::create_xa_data_for(SubModeBuilder::new_mode1().set_eor().create(), &cd_pvd)))?;
|
||||
sec_writer.write(Sector::CDXAData(builder::create_xa_data_for(SubModeBuilder::new_mode1().set_eor().set_eof().create(), &cd_pvd::VolumeDescriptorTerminator::new())))?;
|
||||
sec_writer.write_cd_xa_data(builder::create_xa_data_for(SubModeBuilder::new_mode1().set_eor().create(), &cd_pvd))?;
|
||||
sec_writer.write_cd_xa_data(builder::create_xa_data_for(SubModeBuilder::new_mode1().set_eor().set_eof().create(), &cd_pvd::VolumeDescriptorTerminator::new()))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn process_path_table(path_table: &PathTable, root_dir: SharedPtr<Directory>, _sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
|
||||
fn process_path_table(path_table: &PathTable, root_dir: SharedPtr<Directory>, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
|
||||
macro_rules! write_path_table_twice {
|
||||
($table:ident) => {
|
||||
for sector in $table.clone() {
|
||||
sec_writer.write_cd_xa_data(sector)?;
|
||||
}
|
||||
|
||||
for sector in $table {
|
||||
sec_writer.write_cd_xa_data(sector)?;
|
||||
}
|
||||
};
|
||||
}
|
||||
let mut bytes_used = 0;
|
||||
let mut path_table_raw_l = vec![0u8; path_table.size_bytes];
|
||||
let mut path_table_raw_b = vec![0u8; path_table.size_bytes];
|
||||
let path_table = PathTable::collect_member(root_dir);
|
||||
|
||||
validate_path_table(path_table)?;
|
||||
let path_table = PathTable::collect_member(root_dir);
|
||||
|
||||
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)?};
|
||||
}
|
||||
|
||||
Err(Error::not_implemented("process_path_table"))
|
||||
let path_table_l = builder::create_xa_data_for_vec(None, path_table_raw_l);
|
||||
let path_table_b = builder::create_xa_data_for_vec(None, path_table_raw_b);
|
||||
|
||||
write_path_table_twice!(path_table_l);
|
||||
write_path_table_twice!(path_table_b);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_path_table(path_table: &PathTable) -> Result<(), Error> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
pub mod bin_cue;
|
||||
|
||||
pub use cdtypes::cd::sector::Sector;
|
||||
pub use cdtypes::{cd::sector::Sector, types::*};
|
||||
|
||||
use super::{encoder::EncoderFunction, types::CDDesc};
|
||||
use bin_cue::BinCueWriter;
|
||||
|
@ -12,6 +12,26 @@ pub enum ImageType {
|
|||
}
|
||||
|
||||
pub trait SectorWriter {
|
||||
fn write_audio(&mut self, sector: sector::Audio) -> Result<usize, Error> {
|
||||
self.write(Sector::Audio(sector))
|
||||
}
|
||||
|
||||
fn write_empty(&mut self, sector: sector::Mode0) -> Result<usize, Error> {
|
||||
self.write(Sector::Empty(sector))
|
||||
}
|
||||
|
||||
fn write_cd_data(&mut self, sector: sector::Mode1) -> Result<usize, Error> {
|
||||
self.write(Sector::CDData(sector))
|
||||
}
|
||||
|
||||
fn write_cd_xa_data(&mut self, sector: sector::Mode2Form1) -> Result<usize, Error> {
|
||||
self.write(Sector::CDXAData(sector))
|
||||
}
|
||||
|
||||
fn write_cd_xa_audio(&mut self, sector: sector::Mode2Form2) -> Result<usize, Error> {
|
||||
self.write(Sector::CDXAAudio(sector))
|
||||
}
|
||||
|
||||
fn write(&mut self, sector: Sector) -> Result<usize, Error>;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue