jabyengine/src/Tools/psxcdgen_ex/src/encoder/psx.rs

132 lines
4.7 KiB
Rust

use super::{*, Sector, SectorWriter, {CDDesc, Error}};
use super::super::types::{layout::Layout, *};
use builder::SubModeBuilder;
use cdtypes::types::{cdstring::{AString, DString}, date::Date, helper::sector_count_mode2_form1, pvd as cd_pvd};
const SYSTEM_AREA_SECTOR_COUNT:usize = 16;
const PVD_SECTOR_COUNT:usize = 2;
pub fn calculate_psx_lbas(cd_desc: &mut CDDesc) {
let path_table_size = PathTable::calculate_size_for(cd_desc.root.clone());
let mut cur_lba = 0;
CDDesc::for_each_dir_mut(cd_desc.root.clone(), &|dir| {dir.update_content_size();});
for element in cd_desc.get_memory_layout() {
fn update_lba(properties: &mut Properties, cur_lba: usize, content_sector_size: usize) -> usize {
properties.track_rel_lba = cur_lba;
cur_lba + content_sector_size
}
match element {
Layout::SystemArea(system_area) => {
let mut system_area = system_area.borrow_mut();
system_area.track_rel_lba = cur_lba;
cur_lba += SYSTEM_AREA_SECTOR_COUNT;
},
Layout::PVD(pvd) => {
let mut pvd = pvd.borrow_mut();
pvd.track_rel_lba = cur_lba;
cur_lba += PVD_SECTOR_COUNT;
},
Layout::PathTables(path_table) => {
let mut path_table = path_table.borrow_mut();
path_table.track_rel_lba = cur_lba;
path_table.single_sector_size = sector_count_mode2_form1(path_table_size);
cur_lba += path_table.single_sector_size*4;
},
Layout::Directory(dir) => {
let sector_count = sector_count_mode2_form1(dir.borrow().get_size());
let mut dir = dir.borrow_mut();
cur_lba = update_lba(&mut dir.properties, cur_lba, sector_count)
},
Layout::File(file) => {
let sector_count = {
let file = file.borrow();
let fake_size = file.get_size();
sector_count_mode2_form1(fake_size)
};
let mut file = file.borrow_mut();
cur_lba = update_lba(&mut file.properties, cur_lba, sector_count);
}
}
println!("cur_lba: {}", cur_lba);
}
}
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)?,
Layout::PVD(pvd) => process_pvd(&pvd.borrow(), cd_desc.path_table.clone(), sec_writer)?,
_ => ()
}
}
//Err(Error::not_implemented("encode_psx_image"))
Ok(())
}
fn process_system_area(system_area: &SystemArea, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
let system_area_lba = system_area.track_rel_lba;
if system_area_lba != 0 {
return Err(Error::from_text(format!("System Area required to start at sector 0 of Track - found LBA: {}", system_area_lba)));
}
for _ in 0..SYSTEM_AREA_SECTOR_COUNT {
sec_writer.write(Sector::CDXAData(builder::create_xa_data_zero()))?;
}
Ok(())
}
fn process_pvd(pvd: &PrimaryVolumeDescriptor, path_table: SharedPtr<PathTable>, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
const PLAYSATATION_STR:&'static str = "PLAYSTATION";
let path_table = path_table.borrow();
if pvd.track_rel_lba != 16 {
return Err(Error::from_text(format!("PVD required to start at sector 16 of Track - found LBA: {}", pvd.track_rel_lba)));
}
let mut cd_pvd = cd_pvd::PrimaryVolumeDescriptor::new();
let now = Date::now();
//Config pvd here
cd_pvd.system_id = AString::from_str(PLAYSATATION_STR)?;
cd_pvd.volume_id = DString::from_str("PSX")?;
&cd_pvd.vol_space_size;
&cd_pvd.path_table_size;
&cd_pvd.path_table_1;
&cd_pvd.path_table_2;
&cd_pvd.path_table_3;
&cd_pvd.path_table_4;
&cd_pvd.root_dir_record;
&cd_pvd.publisher_id; //< Company name
&cd_pvd.data_preparer;
cd_pvd.app_id = AString::from_str(PLAYSATATION_STR)?;
cd_pvd.vol_create_time = now;
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];
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())))?;
Ok(())
}