Successfully write BIN
This commit is contained in:
parent
efaef79046
commit
8ed59961b3
|
@ -38,7 +38,7 @@ 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> {
|
||||
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];
|
||||
|
|
|
@ -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<PathTable>,
|
|||
//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<Directory>, 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("<No name>"), 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<CDXASystemUse>) -> 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);
|
||||
},
|
||||
|
||||
|
|
|
@ -159,21 +159,21 @@ impl std::fmt::Display for Directory {
|
|||
}
|
||||
}
|
||||
|
||||
enum FileType {
|
||||
pub(super) enum FileType {
|
||||
Regular(Vec<u8>)
|
||||
}
|
||||
|
||||
pub struct File {
|
||||
pub name: FileName,
|
||||
pub properties: Properties,
|
||||
parent_properties: Option<SharedPtr<Properties>>,
|
||||
_content: FileType
|
||||
pub name: FileName,
|
||||
pub properties: Properties,
|
||||
parent_properties: Option<SharedPtr<Properties>>,
|
||||
pub(super) content: FileType
|
||||
}
|
||||
|
||||
impl File {
|
||||
pub fn new_regular(file_name: &str, content: Vec<u8>) -> Result<File, Error> {
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue