From bae614000704ecc413513ced6871951803a8e1c2 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 20 Oct 2022 21:28:34 +0200 Subject: [PATCH] Introduce PSX encoder to handle lba calculation better and improve many things --- src/Tools/psxcdgen_ex/planschi.bin | Bin 0 -> 37632 bytes src/Tools/psxcdgen_ex/src/encoder/psx.rs | 84 +++++++++- src/Tools/psxcdgen_ex/src/main.rs | 14 +- src/Tools/psxcdgen_ex/src/types/layout.rs | 4 +- src/Tools/psxcdgen_ex/src/types/mod.rs | 179 ++++++++-------------- 5 files changed, 154 insertions(+), 127 deletions(-) diff --git a/src/Tools/psxcdgen_ex/planschi.bin b/src/Tools/psxcdgen_ex/planschi.bin index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c2ef3956c01a09296d9949bbf361051bf17e5906 100644 GIT binary patch literal 37632 zcmeI!JxT*%5P;z^{zXLazY!6!x61{r>;-#mY(>0)g42oNAZpp?M+)5FX75C3*!bj{-&KEA$< z-}BRr(KU~=zi~8}e$VUM^VQw=^~v~w7 z{~tcdrD4}g3wmjm%RK=C1PBl)B%qga*{xpc>7`^c2@oJafIvY3y_8FD_0pnVN+y#4 z0RjXF6co@)x%5^qE$O9XG6@hMK!89&0lkzmD009C72ox01OS$w`FRkdM zWHJd5AV7dXK>@v#OK 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() { @@ -13,8 +78,19 @@ pub fn encode_psx_image(cd_desc: CDDesc, sec_writer: &mut dyn SectorWriter) -> R Ok(()) } -fn process_system_area(_: &SystemArea, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> { +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))); + } - sec_writer.write(Sector::CDXAData(builder::create_xa_data_zero()))?; + for _ in 0..SYSTEM_AREA_SECTOR_COUNT { + sec_writer.write(Sector::CDXAData(builder::create_xa_data_zero()))?; + } Ok(()) -} \ No newline at end of file +} + +fn _process_pvd(_pvd: &PrimaryVolumeDescriptor, _sec_writer: &mut dyn SectorWriter) { + +} + diff --git a/src/Tools/psxcdgen_ex/src/main.rs b/src/Tools/psxcdgen_ex/src/main.rs index 2c788980..27fbc547 100644 --- a/src/Tools/psxcdgen_ex/src/main.rs +++ b/src/Tools/psxcdgen_ex/src/main.rs @@ -1,4 +1,4 @@ -use psxcdgen_ex::{encoder::psx::encode_psx_image, file_writer::{ImageType, write_image}, types::{layout::Layout, CDDesc, File, Directory}}; +use psxcdgen_ex::{encoder::psx::{calculate_psx_lbas, encode_psx_image}, file_writer::{ImageType, write_image}, types::{layout::Layout, CDDesc, File, Directory}}; use std::{path::PathBuf, str::FromStr}; use tool_helper::Error; @@ -32,7 +32,7 @@ fn populate() -> Result { desc.add_file(file); desc.add_file(file2); - desc.calculate_lbas(); + calculate_psx_lbas(&mut desc); Ok(desc) } @@ -42,11 +42,11 @@ fn run_main() -> Result<(), Error> { println!("\n<== Planschbecken ==>"); for element in desc.get_memory_layout().iter() { match element { - Layout::SystemArea(_) => println!("SystemArea:"), - Layout::PVD(_) => println!("PVD:"), - Layout::PathTables => println!("PathTables:"), - Layout::Directory(dir) => println!("Dir: {} @{}-{}", dir.borrow().name, dir.borrow().properties.track_rel_lba, dir.borrow().properties.overwrite_size_bytes.unwrap_or(0)), - Layout::File(file) => println!("File: {} @{}-{}", file.borrow(), file.borrow().properties.track_rel_lba, file.borrow().properties.overwrite_size_bytes.unwrap_or(0)), + Layout::SystemArea(_) => println!("SystemArea:"), + Layout::PVD(_) => println!("PVD:"), + Layout::PathTables(_) => println!("PathTables:"), + Layout::Directory(dir) => println!("Dir: {} @{}-{}", dir.borrow().name, dir.borrow().get_track_rel_lba(), dir.borrow().get_size()), + Layout::File(file) => println!("File: {} @{}-{}", file.borrow(), file.borrow().get_track_rel_lba(), file.borrow().get_size()), } } println!("\n<== Planschbecken ==>"); diff --git a/src/Tools/psxcdgen_ex/src/types/layout.rs b/src/Tools/psxcdgen_ex/src/types/layout.rs index 9e9ccd5b..e3400c8f 100644 --- a/src/Tools/psxcdgen_ex/src/types/layout.rs +++ b/src/Tools/psxcdgen_ex/src/types/layout.rs @@ -11,7 +11,7 @@ impl DefaultLayout { layout.push(Layout::SystemArea(parent.system_area.clone())); layout.push(Layout::PVD(parent.pvd.clone())); - layout.push(Layout::PathTables); + layout.push(Layout::PathTables(parent.path_table.clone())); Self::add_dir_and_subdir(&mut layout, parent.root.clone()); layout @@ -34,7 +34,7 @@ impl DefaultLayout { pub enum Layout { SystemArea(SharedPtr), PVD(SharedPtr), - PathTables, + PathTables(SharedPtr), Directory(SharedPtr), File(SharedPtr) } diff --git a/src/Tools/psxcdgen_ex/src/types/mod.rs b/src/Tools/psxcdgen_ex/src/types/mod.rs index e91a5fd3..3dade461 100644 --- a/src/Tools/psxcdgen_ex/src/types/mod.rs +++ b/src/Tools/psxcdgen_ex/src/types/mod.rs @@ -2,9 +2,8 @@ mod helper; pub mod layout; pub mod file_map; -use cdtypes::types::{cdstring::DString, dir_record::DirectoryRecord, helper::{round_bytes_mode2_form1, sector_count_mode2_form1}, sector::*, path_table::PathTableL}; +use cdtypes::types::{cdstring::DString, dir_record::DirectoryRecord, path_table::PathTableL}; use file_map::FileSystemMap; -use layout::Layout; use std::{cell::RefCell, rc::Rc}; pub use tool_helper::Error; @@ -15,15 +14,16 @@ pub fn new_shared_ptr(value: T) -> SharedPtr { } pub struct CDDesc { - system_area: SharedPtr, - pvd: SharedPtr, - root: SharedPtr + system_area: SharedPtr, + path_table: SharedPtr, + pvd: SharedPtr, + pub(super) root: SharedPtr } impl CDDesc { pub fn new() -> CDDesc { match Directory::new("root") { - Ok(root) => CDDesc{system_area: new_shared_ptr(SystemArea::new()), pvd: new_shared_ptr(PrimaryVolumeDescriptor::new()), root: new_shared_ptr(root)}, + Ok(root) => CDDesc{system_area: new_shared_ptr(SystemArea::new()), path_table: new_shared_ptr(PathTable::new()), pvd: new_shared_ptr(PrimaryVolumeDescriptor::new()), root: new_shared_ptr(root)}, Err(error) => panic!("Creating root directory failed with: {}", error) } } @@ -44,60 +44,7 @@ impl CDDesc { file_map::new_file_map(&self.root.borrow()) } - pub fn calculate_lbas(&mut self) { - let (mut path_table_properties, path_table_sector_count) = { - let mut size_bytes = 0; - - helper::collect_path_table_member(self.root.clone()).into_iter().for_each(|element| { - println!("PT: {} ^{}", element.name, element.parent_table_id); - size_bytes += PathTableL::calculate_size_for(element.name.as_ref()); - }); - - size_bytes = round_bytes_mode2_form1(size_bytes)*4; - (Properties{track_rel_lba: 0, overwrite_size_bytes: None, is_hidden: false}, sector_count_mode2_form1(size_bytes)) - }; - let mut cur_lba = 0; - - Self::for_each_dir_mut(self.root.clone(), &|dir| {dir.update_content_size();}); - - // Now layout iterate? - for element in self.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(); - cur_lba = update_lba(&mut system_area.properties, cur_lba, SystemArea::get_sector_count()); - }, - Layout::PVD(pvd) => { - let mut pvd = pvd.borrow_mut(); - cur_lba = update_lba(&mut pvd.properties, cur_lba, PrimaryVolumeDescriptor::get_sector_count()); - }, - Layout::PathTables => { - cur_lba = update_lba(&mut path_table_properties, cur_lba, path_table_sector_count); - }, - Layout::Directory(dir) => { - let sector_count = dir.borrow().get_sector_count(); - let mut dir = dir.borrow_mut(); - - cur_lba = update_lba(&mut dir.properties, cur_lba, sector_count) - }, - Layout::File(file) => { - let sector_count = file.borrow().get_sector_count(); - let mut file = file.borrow_mut(); - - cur_lba = update_lba(&mut file.properties, cur_lba, sector_count); - } - } - - println!("cur_lba: {}", cur_lba); - } - } - - fn for_each_dir_mut(dir: SharedPtr, function: &T) { + pub(super) fn for_each_dir_mut(dir: SharedPtr, function: &T) { let mut dir = dir.borrow_mut(); function(&mut dir); @@ -108,49 +55,58 @@ impl CDDesc { } pub struct SystemArea { - pub properties: Properties + pub(in super) track_rel_lba: usize, } impl SystemArea { - const SECTOR_COUNT:usize = 16; - const DEFAULT_SIZE:usize = (Self::SECTOR_COUNT*Mode2Form1::DATA_SIZE); - pub fn new() -> SystemArea { - SystemArea{properties: Properties{track_rel_lba: 0, overwrite_size_bytes: Some(Self::DEFAULT_SIZE), is_hidden: false}} + SystemArea{track_rel_lba: 0} + } +} + +pub struct PathTable { + pub(super) track_rel_lba: usize, + pub(super) single_sector_size: usize, +} + +impl PathTable { + pub fn new() -> PathTable { + PathTable{track_rel_lba: 0, single_sector_size: 0} } - fn get_sector_count() -> usize { - Self::SECTOR_COUNT + pub fn calculate_size_for(root: SharedPtr) -> usize { + let mut size_bytes = 0; + + helper::collect_path_table_member(root).into_iter().for_each(|element| { + println!("PT: {} ^{}", element.name, element.parent_table_id); + size_bytes += PathTableL::calculate_size_for(element.name.as_ref()); + }); + + size_bytes } } pub struct PrimaryVolumeDescriptor { - pub properties: Properties + pub(in super) track_rel_lba: usize } impl PrimaryVolumeDescriptor { - const SECTOR_COUNT:usize = 2; - const DEFAULT_SIZE:usize = (Self::SECTOR_COUNT*Mode2Form1::DATA_SIZE); - pub fn new() -> PrimaryVolumeDescriptor { - PrimaryVolumeDescriptor{properties: Properties{track_rel_lba: 0, overwrite_size_bytes: Some(Self::DEFAULT_SIZE), is_hidden: false}} - } - - fn get_sector_count() -> usize { - Self::SECTOR_COUNT + PrimaryVolumeDescriptor{track_rel_lba: 0} } } pub struct Directory { pub name: DirectoryName, pub properties: Properties, + size_bytes: usize, files: Vec>, dirs: Vec> } impl Directory { pub fn new(dir_name: &str) -> Result { - Ok(Directory{name: DirectoryName::from_str(dir_name)?, properties: Properties::default(), files: Vec::new(), dirs: Vec::new()}) + Ok(Directory{name: DirectoryName::from_str(dir_name)?, properties: Properties::default(), size_bytes: 0, files: Vec::new(), dirs: Vec::new()}) } pub fn add_dir(&mut self, dir: Directory) { @@ -161,7 +117,15 @@ impl Directory { self.files.push(new_shared_ptr(file)); } - fn update_content_size(&mut self) { + pub fn get_track_rel_lba(&self) -> usize { + self.properties.track_rel_lba + } + + pub fn get_size(&self) -> usize { + self.properties.get_size(self.size_bytes) + } + + pub(super) fn update_content_size(&mut self) { let dir_member = helper::collect_directory_record_member(&self.files, &self.dirs); let mut size_bytes = 0; @@ -169,20 +133,7 @@ impl Directory { size_bytes += DirectoryRecord::calculate_size_for(member.get_name().as_str(), true); } - self.properties.overwrite_size_bytes = Some(size_bytes); - } - - fn _update_content(&mut self) { - let dir_member = helper::collect_directory_record_member(&self.files, &self.dirs); - - println!("{} updating content", self.name.as_string().unwrap_or("".to_owned())); - for member in dir_member { - println!(">>> {}", member.get_name()); - } - } - - fn get_sector_count(&self) -> usize { - self.properties.sector_count_xa_data(0) + self.size_bytes = size_bytes; } } @@ -207,14 +158,18 @@ impl File { Ok(File{name: FileName::from_str(file_name)?, properties: Properties::default(), content: FileType::Regular(content)}) } - pub fn get_sector_count(&self) -> usize { - let content_size = { - match &self.content { - FileType::Regular(content) => content.len() - } - }; + pub fn get_track_rel_lba(&self) -> usize { + self.properties.track_rel_lba + } - self.properties.sector_count_xa_data(content_size) + pub fn get_size(&self) -> usize { + self.properties.get_size(self.get_content_size()) + } + + pub(super) fn get_content_size(&self) -> usize { + match &self.content { + FileType::Regular(content) => content.len() + } } } @@ -262,7 +217,7 @@ impl FileName { let file_name = file_name.to_uppercase(); let (name, ext) = { let mut sub_str = file_name.split('.'); - (Error::ok_or_new(sub_str.next(), || "File name can't be emplty".to_owned())?, sub_str.next()) + (Error::ok_or_new(sub_str.next(), || "File name can't be empty".to_owned())?, sub_str.next()) }; let (ext, ext_len) = { match ext { @@ -292,24 +247,20 @@ impl std::fmt::Display for FileName { } pub struct Properties { - pub track_rel_lba: usize, - pub overwrite_size_bytes: Option, - pub is_hidden: bool + pub(in super) track_rel_lba: usize, + pub(in super) overwrite_size_bytes: Option, + pub(in super) is_hidden: bool } impl Properties { - pub fn sector_count_xa_data(&self, content_size: usize) -> usize { - let size_bytes = { - if let Some(forced_bytes) = self.overwrite_size_bytes { - forced_bytes - } + pub(super) fn get_size(&self, content_size: usize) -> usize { + if let Some(forced_bytes) = self.overwrite_size_bytes { + forced_bytes + } - else { - content_size - } - }; - - sector_count_mode2_form1(size_bytes) + else { + content_size + } } }