From 6c4277a9a3cb397ccca013d832b426d42ea1bf7d Mon Sep 17 00:00:00 2001 From: Jaby Date: Thu, 27 Oct 2022 22:22:54 +0200 Subject: [PATCH] Successfully write BIN --- src/Tools/psxcdgen_ex/src/encoder/builder.rs | 2 +- src/Tools/psxcdgen_ex/src/encoder/psx.rs | 47 +++++++++++++++----- src/Tools/psxcdgen_ex/src/types/mod.rs | 12 ++--- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/Tools/psxcdgen_ex/src/encoder/builder.rs b/src/Tools/psxcdgen_ex/src/encoder/builder.rs index 934c79f9..8d63081f 100644 --- a/src/Tools/psxcdgen_ex/src/encoder/builder.rs +++ b/src/Tools/psxcdgen_ex/src/encoder/builder.rs @@ -38,7 +38,7 @@ pub fn create_xa_data_for(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, data: Vec) -> Vec { +pub fn create_xa_data_for_vec(sub_mode: Option, data: &Vec) -> Vec { 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]; diff --git a/src/Tools/psxcdgen_ex/src/encoder/psx.rs b/src/Tools/psxcdgen_ex/src/encoder/psx.rs index 381c833d..6bb90c02 100644 --- a/src/Tools/psxcdgen_ex/src/encoder/psx.rs +++ b/src/Tools/psxcdgen_ex/src/encoder/psx.rs @@ -1,7 +1,7 @@ use super::{*, SectorWriter, {CDDesc, Error}}; use super::super::types::{helper::{DirectoryRecordMember, PathTableMember}, layout::Layout, *}; use builder::SubModeBuilder; -use cdtypes::types::{cdstring::{AString, DString}, date::*, dir_record::*, helper::sector_count_mode2_form1, path_table::*, pvd as cd_pvd, lsb_msb::*, sector::Mode2Form1}; +use cdtypes::types::{cdstring::{AString, DString}, date::*, dir_record::*, helper::{round_bytes_mode2_form1, sector_count_mode2_form1}, path_table::*, pvd as cd_pvd, lsb_msb::*, sector::Mode2Form1}; const ROOT_DIR_NAME:&'static str = "\x00"; const SYSTEM_AREA_SECTOR_COUNT:usize = 16; @@ -80,11 +80,10 @@ pub fn encode_psx_image(cd_desc: CDDesc, sec_writer: &mut dyn SectorWriter) -> R Layout::PVD(pvd) => process_pvd(&pvd.borrow(), cd_desc.path_table.clone(), cd_desc.root.clone(), vol_sector_count, sec_writer)?, Layout::PathTables(path_table) => process_path_table(&path_table.borrow(), cd_desc.root.clone(), sec_writer)?, Layout::Directory(dir) => process_directory_record(&dir.borrow(), sec_writer)?, - _ => () + Layout::File(file) => process_file(&file.borrow(), sec_writer)?, } } - //Err(Error::not_implemented("encode_psx_image")) Ok(()) } @@ -117,7 +116,7 @@ fn process_pvd(pvd: &PrimaryVolumeDescriptor, path_table: SharedPtr, //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.write(vol_sector_count as u32); + cd_pvd.vol_space_size.write(28 as u32); //Set PathTable values cd_pvd.path_table_size.write(path_table.size_bytes as u32); @@ -167,8 +166,8 @@ fn process_path_table(path_table: &PathTable, root_dir: SharedPtr, se 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)?}; } - 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); + 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); @@ -187,13 +186,16 @@ fn process_directory_record(dir: &Directory, sec_writer: &mut dyn SectorWriter) raw_data = &mut raw_data[bytes_written..raw_data_len]; } + + + let dir_record_sectors = builder::create_xa_data_for_vec(None, &dir_record); + let dir_record_sector_count = dir_record_sectors.len(); - let dir_record_sector_count = sector_count_mode2_form1(raw_data.len()); if dir_record_sector_count > 1 { return Err(Error::from_text(format!("Directory Record for {} spans {} sectors but PSX doesn't support more then one sector", dir.name.as_str().unwrap_or(""), dir_record_sector_count))); } - for sector in builder::create_xa_data_for_vec(None, dir_record) { + for sector in dir_record_sectors { sec_writer.write_cd_xa_data(sector)?; } @@ -205,6 +207,26 @@ fn process_directory_record(dir: &Directory, sec_writer: &mut dyn SectorWriter) Ok(()) } +fn process_file(file: &File, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> { + let content_sectors = { + match &file.content { + FileType::Regular(raw) => builder::create_xa_data_for_vec(None, raw), + } + }; + let content_sector_count = content_sectors.len(); + + for sector in content_sectors { + sec_writer.write_cd_xa_data(sector)?; + } + + let extended_sector_count = sector_count_mode2_form1(file.properties.get_extended_size()) - content_sector_count; + for _ in 0..extended_sector_count { + sec_writer.write_cd_xa_data(builder::create_xa_data_zero())?; + } + + Ok(()) +} + fn validate_path_table(path_table: &PathTable) -> Result<(), Error> { if path_table.size_bytes > Mode2Form1::DATA_SIZE { Err(Error::from_text(format!("Path Tables are not allowed to be bigger then {} bytes - Path Table has {} bytes", Mode2Form1::DATA_SIZE, path_table.size_bytes))) @@ -244,7 +266,8 @@ fn update_path_table_entry(path_table_l: &mut PathTableL, path_table_b: &mut Pat } fn create_dir_record_raw<'a>(dst: &'a mut [u8], name: &str, track_rel_lba: u32, size_bytes: u32, system_use: Option) -> Result<&'a mut DirectoryRecord, Error> { - let bytes_needed = DirectoryRecord::calculate_size_for(name, system_use.is_some()); + let has_system_use = system_use.is_some(); + let bytes_needed = DirectoryRecord::calculate_size_for(name, has_system_use); if dst.len() < bytes_needed { return Err(Error::from_text(format!("DirectoryRecord for entry {} needs {} bytes but {} bytes were provided", name, bytes_needed, dst.len()))); @@ -252,7 +275,7 @@ fn create_dir_record_raw<'a>(dst: &'a mut [u8], name: &str, track_rel_lba: u32, unsafe { let mut dir_record = std::mem::transmute::<&mut u8, &mut DirectoryRecord>(&mut dst[0]); - dir_record.new(name, false); + dir_record.new(name, has_system_use); dir_record.data_block_number.write(track_rel_lba); dir_record.data_size.write(size_bytes); @@ -286,9 +309,9 @@ fn write_dir_record(dir_record: &mut [u8], dir_member: &DirectoryRecordMember, h } }; - let dir_record = create_dir_record_raw(dir_record, name.as_str(), *track_rel_lba, *real_size, system_use)?; + let dir_record = create_dir_record_raw(dir_record, name.as_str(), *track_rel_lba, round_bytes_mode2_form1(*real_size as usize) as u32, system_use)?; - dir_record.set_file(); + dir_record.set_directory(); return Ok(dir_record.length[0] as usize); }, diff --git a/src/Tools/psxcdgen_ex/src/types/mod.rs b/src/Tools/psxcdgen_ex/src/types/mod.rs index 4ffff14f..480d7de9 100644 --- a/src/Tools/psxcdgen_ex/src/types/mod.rs +++ b/src/Tools/psxcdgen_ex/src/types/mod.rs @@ -159,21 +159,21 @@ impl std::fmt::Display for Directory { } } -enum FileType { +pub(super) enum FileType { Regular(Vec) } pub struct File { - pub name: FileName, - pub properties: Properties, - parent_properties: Option>, - _content: FileType + pub name: FileName, + pub properties: Properties, + parent_properties: Option>, + pub(super) content: FileType } impl File { pub fn new_regular(file_name: &str, content: Vec) -> Result { let content_size = content.len(); - let mut file = File{name: FileName::from_str(file_name)?, properties: Properties::default(), parent_properties: None, _content: FileType::Regular(content)}; + let mut file = File{name: FileName::from_str(file_name)?, properties: Properties::default(), parent_properties: None, content: FileType::Regular(content)}; file.properties.size_bytes = content_size; Ok(file)