LBAs are track relative
This commit is contained in:
parent
97c4f0a05d
commit
840ca74e6d
|
@ -20,6 +20,16 @@ impl Sector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_header_mut(&mut self) -> Option<&mut Header> {
|
||||||
|
match self {
|
||||||
|
Sector::Audio(_) => None,
|
||||||
|
Sector::Empty(sec) => Some(&mut sec.header),
|
||||||
|
Sector::CDData(sec) => Some(&mut sec.header),
|
||||||
|
Sector::CDXAData(sec) => Some(&mut sec.header),
|
||||||
|
Sector::CDXAAudio(sec) => Some(&mut sec.header),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_sub_header(&self) -> Option<&SubHeader> {
|
pub fn get_sub_header(&self) -> Option<&SubHeader> {
|
||||||
match self {
|
match self {
|
||||||
Sector::CDXAData(sec) => Some(&sec.sub_header),
|
Sector::CDXAData(sec) => Some(&sec.sub_header),
|
||||||
|
|
|
@ -5,6 +5,10 @@ pub struct BCDValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BCDValue {
|
impl BCDValue {
|
||||||
|
pub const fn new(value: u8) -> BCDValue {
|
||||||
|
BCDValue{value: (((value/10) << 4) | (value%10))}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_decimal(&self) -> u8 {
|
pub fn get_decimal(&self) -> u8 {
|
||||||
((self.value >> 4)*10) + (self.value & 0b1111)
|
((self.value >> 4)*10) + (self.value & 0b1111)
|
||||||
}
|
}
|
||||||
|
@ -12,7 +16,7 @@ impl BCDValue {
|
||||||
|
|
||||||
impl std::convert::From<u8> for BCDValue {
|
impl std::convert::From<u8> for BCDValue {
|
||||||
fn from(value: u8) -> Self {
|
fn from(value: u8) -> Self {
|
||||||
BCDValue{value: (((value/10) << 4) | (value%10))}
|
BCDValue::new(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,15 +13,15 @@ impl Time {
|
||||||
pub const MAX_SECONDS:usize = 60;
|
pub const MAX_SECONDS:usize = 60;
|
||||||
pub const MAX_MINUTES:usize = 74;
|
pub const MAX_MINUTES:usize = 74;
|
||||||
|
|
||||||
pub fn cue_start() -> Time {
|
pub const fn cue_start() -> Time {
|
||||||
Time{minute: 0, second: 0, sector: 0}
|
Time{minute: 0, second: 0, sector: 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cd_start() -> Time {
|
pub const fn cd_start() -> Time {
|
||||||
Time{minute: 0, second: 2, sector: 0}
|
Time{minute: 0, second: 2, sector: 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cd_pregap() -> Time {
|
pub const fn cd_pregap() -> Time {
|
||||||
Time{minute: 0, second: 2, sector: 0}
|
Time{minute: 0, second: 2, sector: 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ impl Time {
|
||||||
(BCDValue::from(self.minute), BCDValue::from(self.second), BCDValue::from(self.sector))
|
(BCDValue::from(self.minute), BCDValue::from(self.second), BCDValue::from(self.sector))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_lba(&self) -> usize {
|
pub const fn to_lba(&self) -> usize {
|
||||||
self.sector as usize + (self.second as usize*Self::MAX_SECTORS) + (self.minute as usize*Self::MAX_SECONDS*Self::MAX_SECTORS)
|
self.sector as usize + (self.second as usize*Self::MAX_SECTORS) + (self.minute as usize*Self::MAX_SECONDS*Self::MAX_SECTORS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
use cdtypes::types::{sector::*, time::Time};
|
use cdtypes::types::sector::*;
|
||||||
|
|
||||||
pub fn create_xa_data_for_data(lba: usize, data: &[u8; Mode2Form1::DATA_SIZE]) -> Mode2Form1 {
|
pub fn create_xa_data_for_data(data: &[u8; Mode2Form1::DATA_SIZE]) -> Mode2Form1 {
|
||||||
let mut sector = Mode2Form1::new();
|
let mut sector = Mode2Form1::new();
|
||||||
|
|
||||||
sector.header.set_time(Time::from_lba(lba));
|
|
||||||
sector.sub_header.sub_mode.set_data();
|
sector.sub_header.sub_mode.set_data();
|
||||||
sector.data = *data;
|
sector.data = *data;
|
||||||
|
|
||||||
sector
|
sector
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_xa_data_zero(lba: usize) -> Mode2Form1 {
|
pub fn create_xa_data_zero() -> Mode2Form1 {
|
||||||
create_xa_data_for_data(lba, &[0u8; Mode2Form1::DATA_SIZE])
|
create_xa_data_for_data(&[0u8; Mode2Form1::DATA_SIZE])
|
||||||
}
|
}
|
|
@ -12,7 +12,7 @@ pub fn encode_psx_image(cd_desc: CDDesc, sec_writer: &mut dyn SectorWriter) -> R
|
||||||
Err(Error::not_implemented("encode_psx_image"))
|
Err(Error::not_implemented("encode_psx_image"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_system_area(system_area: &SystemArea, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
|
fn process_system_area(_: &SystemArea, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
|
||||||
|
|
||||||
sec_writer.write(Sector::CDXAData(builder::create_xa_data_zero(system_area.properties.lba)))
|
sec_writer.write(Sector::CDXAData(builder::create_xa_data_zero()))
|
||||||
}
|
}
|
|
@ -1,20 +1,32 @@
|
||||||
use std::io::Write;
|
|
||||||
use super::{Error, Sector, SectorWriter};
|
use super::{Error, Sector, SectorWriter};
|
||||||
|
use cdtypes::types::time::Time;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
pub struct BinCueWriter {
|
pub struct BinCueWriter {
|
||||||
_bin_out: std::boxed::Box<dyn Write>,
|
_bin_out: std::boxed::Box<dyn Write>,
|
||||||
sector_count: usize
|
cd_time: Time,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BinCueWriter {
|
impl BinCueWriter {
|
||||||
pub fn new<T: Write + 'static>(writer: T) -> BinCueWriter {
|
pub fn new<T: Write + 'static>(writer: T) -> BinCueWriter {
|
||||||
BinCueWriter{_bin_out: std::boxed::Box::new(writer), sector_count: 0}
|
BinCueWriter{_bin_out: std::boxed::Box::new(writer), cd_time: Time::cd_start()}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finalize(&mut self, sector: &mut Sector) -> Result<(), Error> {
|
||||||
|
sector.finalize();
|
||||||
|
|
||||||
|
if let Some(header) = sector.get_header_mut() {
|
||||||
|
header.set_time(self.cd_time.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.cd_time.add_sector()?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SectorWriter for BinCueWriter {
|
impl SectorWriter for BinCueWriter {
|
||||||
fn write(&mut self, mut sector: Sector) -> Result<(), Error> {
|
fn write(&mut self, mut sector: Sector) -> Result<(), Error> {
|
||||||
self.finalize_sector(&mut sector)?;
|
self.finalize(&mut sector)?;
|
||||||
|
|
||||||
match sector {
|
match sector {
|
||||||
Sector::Empty(_) => Err(Error::not_implemented("Empty sector encoding")),
|
Sector::Empty(_) => Err(Error::not_implemented("Empty sector encoding")),
|
||||||
|
@ -24,8 +36,4 @@ impl SectorWriter for BinCueWriter {
|
||||||
Sector::CDXAAudio(_) => Err(Error::not_implemented("CD XA Audio sector encoding"))
|
Sector::CDXAAudio(_) => Err(Error::not_implemented("CD XA Audio sector encoding"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sector_written_count(&self) -> usize {
|
|
||||||
self.sector_count
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -13,20 +13,6 @@ pub enum ImageType {
|
||||||
|
|
||||||
pub trait SectorWriter {
|
pub trait SectorWriter {
|
||||||
fn write(&mut self, sector: Sector) -> Result<(), Error>;
|
fn write(&mut self, sector: Sector) -> Result<(), Error>;
|
||||||
fn sector_written_count(&self) -> usize;
|
|
||||||
|
|
||||||
fn finalize_sector(&self, sector: &mut Sector) -> Result<(), Error> {
|
|
||||||
let sectors_written = self.sector_written_count();
|
|
||||||
if let Some(header) = sector.get_header() {
|
|
||||||
let sector_lba = header.get_time().to_lba();
|
|
||||||
if sector_lba != sectors_written {
|
|
||||||
return Err(Error::from_text(format!("Header LBA {} doesn't match written sector count of {}", sector_lba, sectors_written)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sector.finalize();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_image(cd_desc: CDDesc, encoder: EncoderFunction, image_type: ImageType, output_path: PathBuf) -> Result<(), Error> {
|
pub fn write_image(cd_desc: CDDesc, encoder: EncoderFunction, image_type: ImageType, output_path: PathBuf) -> Result<(), Error> {
|
||||||
|
|
Loading…
Reference in New Issue