mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-04 00:21:57 +00:00
Revised dcb_io::GameFile to use cursors.
This commit is contained in:
parent
c622af8262
commit
eb52ba496d
@ -8,6 +8,7 @@ use std::{
|
||||
|
||||
/// A cursor over a cdrom-xa file.
|
||||
// TODO: Repair sector headers and edc/ecc after writing
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
pub struct CdRomCursor<T> {
|
||||
/// Underlying reader/writer
|
||||
inner: T,
|
||||
|
||||
@ -9,8 +9,8 @@ edition = "2018"
|
||||
# Dcb
|
||||
dcb-bytes = { path = "../dcb-bytes" }
|
||||
dcb-util = { path = "../dcb-util" }
|
||||
dcb-iso9660 = { path = "../dcb-iso9660" }
|
||||
dcb-cdrom-xa = { path = "../dcb-cdrom-xa" }
|
||||
dcb-drv = { path = "../dcb-drv" }
|
||||
|
||||
# Log
|
||||
log = "0.4.13"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
//! Abstraction over the game file.
|
||||
//! Game file.
|
||||
//!
|
||||
//! See [`GameFile`] for details
|
||||
|
||||
@ -6,59 +6,147 @@
|
||||
pub mod error;
|
||||
|
||||
// Exports
|
||||
pub use error::{NewError, ReadDrvError};
|
||||
pub use error::NewError;
|
||||
|
||||
// Imports
|
||||
use dcb_cdrom_xa::CdRomReader;
|
||||
use dcb_iso9660::entry::FileReader;
|
||||
use dcb_cdrom_xa::CdRomCursor;
|
||||
use dcb_drv::cursor::DrvFsCursor;
|
||||
use dcb_util::IoCursor;
|
||||
use std::io;
|
||||
|
||||
/// Game file reader.
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub struct GameFile<'a, R> {
|
||||
/// Game file.
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
pub struct GameFile<T> {
|
||||
/// CD-Rom
|
||||
cdrom: &'a mut CdRomReader<R>,
|
||||
cdrom: CdRomCursor<T>,
|
||||
|
||||
/// Iso9660 filesystem
|
||||
filesystem: dcb_iso9660::FilesystemReader,
|
||||
/// `A.DRV` cursor
|
||||
a_drv_cursor: DrvFsCursor,
|
||||
|
||||
/// `B.DRV` cursor
|
||||
b_drv_cursor: DrvFsCursor,
|
||||
|
||||
/// `C.DRV` cursor
|
||||
c_drv_cursor: DrvFsCursor,
|
||||
|
||||
/// `E.DRV` cursor
|
||||
e_drv_cursor: DrvFsCursor,
|
||||
|
||||
/// `F.DRV` cursor
|
||||
f_drv_cursor: DrvFsCursor,
|
||||
|
||||
/// `G.DRV` cursor
|
||||
g_drv_cursor: DrvFsCursor,
|
||||
|
||||
/// `P.DRV` cursor
|
||||
p_drv_cursor: DrvFsCursor,
|
||||
}
|
||||
|
||||
// Constructors
|
||||
impl<'a, R: io::Read + io::Seek> GameFile<'a, R> {
|
||||
/// Creates a new game file from the cd reader
|
||||
pub fn new(cdrom: &'a mut CdRomReader<R>) -> Result<Self, NewError> {
|
||||
// Read the filesystem
|
||||
let filesystem = dcb_iso9660::FilesystemReader::new(cdrom).map_err(NewError::ParseFilesystem)?;
|
||||
impl<T: io::Read + io::Seek> GameFile<T> {
|
||||
/// `A.DRV` Offset
|
||||
pub const A_OFFSET: u64 = 0xa1000;
|
||||
/// `A.DRV` Size
|
||||
pub const A_SIZE: u64 = 0xa78800;
|
||||
/// `B.DRV` Offset
|
||||
pub const B_OFFSET: u64 = 0xb19800;
|
||||
/// `B.DRV` Size
|
||||
pub const B_SIZE: u64 = 0x17ea800;
|
||||
/// `C.DRV` Offset
|
||||
pub const C_OFFSET: u64 = 0x2304000;
|
||||
/// `C.DRV` Size
|
||||
pub const C_SIZE: u64 = 0xb6c000;
|
||||
/// `E.DRV` Offset
|
||||
pub const E_OFFSET: u64 = 0x2e70000;
|
||||
/// `E.DRV` Size
|
||||
pub const E_SIZE: u64 = 0x1886800;
|
||||
/// `F.DRV` Offset
|
||||
pub const F_OFFSET: u64 = 0x46f6800;
|
||||
/// `F.DRV` Size
|
||||
pub const F_SIZE: u64 = 0xf2f800;
|
||||
/// `G.DRV` Offset
|
||||
pub const G_OFFSET: u64 = 0x5626000;
|
||||
/// `G.DRV` Size
|
||||
pub const G_SIZE: u64 = 0x293000;
|
||||
/// `P.DRV` Offset
|
||||
pub const P_OFFSET: u64 = 0xc000;
|
||||
/// `P.DRV` Size
|
||||
pub const P_SIZE: u64 = 0x95000;
|
||||
|
||||
Ok(Self { cdrom, filesystem })
|
||||
/// Creates a new game file
|
||||
pub fn new(mut cdrom: CdRomCursor<T>) -> Result<Self, NewError> {
|
||||
let mut a_drv = IoCursor::new(&mut cdrom, Self::A_OFFSET, Self::A_SIZE).map_err(NewError::OpenA)?;
|
||||
let a_drv_cursor = DrvFsCursor::new(&mut a_drv).map_err(NewError::CursorA)?;
|
||||
|
||||
let mut b_drv = IoCursor::new(&mut cdrom, Self::B_OFFSET, Self::B_SIZE).map_err(NewError::OpenB)?;
|
||||
let b_drv_cursor = DrvFsCursor::new(&mut b_drv).map_err(NewError::CursorB)?;
|
||||
|
||||
let mut c_drv = IoCursor::new(&mut cdrom, Self::C_OFFSET, Self::C_SIZE).map_err(NewError::OpenC)?;
|
||||
let c_drv_cursor = DrvFsCursor::new(&mut c_drv).map_err(NewError::CursorC)?;
|
||||
|
||||
let mut e_drv = IoCursor::new(&mut cdrom, Self::E_OFFSET, Self::E_SIZE).map_err(NewError::OpenE)?;
|
||||
let e_drv_cursor = DrvFsCursor::new(&mut e_drv).map_err(NewError::CursorE)?;
|
||||
|
||||
let mut f_drv = IoCursor::new(&mut cdrom, Self::F_OFFSET, Self::F_SIZE).map_err(NewError::OpenF)?;
|
||||
let f_drv_cursor = DrvFsCursor::new(&mut f_drv).map_err(NewError::CursorF)?;
|
||||
|
||||
let mut g_drv = IoCursor::new(&mut cdrom, Self::G_OFFSET, Self::G_SIZE).map_err(NewError::OpenG)?;
|
||||
let g_drv_cursor = DrvFsCursor::new(&mut g_drv).map_err(NewError::CursorG)?;
|
||||
|
||||
let mut p_drv = IoCursor::new(&mut cdrom, Self::P_OFFSET, Self::P_SIZE).map_err(NewError::OpenP)?;
|
||||
let p_drv_cursor = DrvFsCursor::new(&mut p_drv).map_err(NewError::CursorP)?;
|
||||
|
||||
Ok(Self {
|
||||
cdrom,
|
||||
a_drv_cursor,
|
||||
b_drv_cursor,
|
||||
c_drv_cursor,
|
||||
e_drv_cursor,
|
||||
f_drv_cursor,
|
||||
g_drv_cursor,
|
||||
p_drv_cursor,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the `A.DRV` file
|
||||
pub fn a_drv(cdrom: &mut CdRomCursor<T>) -> Result<IoCursor<&mut CdRomCursor<T>>, io::Error> {
|
||||
IoCursor::new(cdrom, Self::A_OFFSET, Self::A_SIZE)
|
||||
}
|
||||
|
||||
/// Returns the `B.DRV` file
|
||||
pub fn b_drv(cdrom: &mut CdRomCursor<T>) -> Result<IoCursor<&mut CdRomCursor<T>>, io::Error> {
|
||||
IoCursor::new(cdrom, Self::B_OFFSET, Self::B_SIZE)
|
||||
}
|
||||
|
||||
/// Returns the `C.DRV` file
|
||||
pub fn c_drv(cdrom: &mut CdRomCursor<T>) -> Result<IoCursor<&mut CdRomCursor<T>>, io::Error> {
|
||||
IoCursor::new(cdrom, Self::C_OFFSET, Self::C_SIZE)
|
||||
}
|
||||
|
||||
/// Returns the `E.DRV` file
|
||||
pub fn e_drv(cdrom: &mut CdRomCursor<T>) -> Result<IoCursor<&mut CdRomCursor<T>>, io::Error> {
|
||||
IoCursor::new(cdrom, Self::E_OFFSET, Self::E_SIZE)
|
||||
}
|
||||
|
||||
/// Returns the `F.DRV` file
|
||||
pub fn f_drv(cdrom: &mut CdRomCursor<T>) -> Result<IoCursor<&mut CdRomCursor<T>>, io::Error> {
|
||||
IoCursor::new(cdrom, Self::F_OFFSET, Self::F_SIZE)
|
||||
}
|
||||
|
||||
/// Returns the `G.DRV` file
|
||||
pub fn g_drv(cdrom: &mut CdRomCursor<T>) -> Result<IoCursor<&mut CdRomCursor<T>>, io::Error> {
|
||||
IoCursor::new(cdrom, Self::G_OFFSET, Self::G_SIZE)
|
||||
}
|
||||
|
||||
/// Returns the `P.DRV` file
|
||||
pub fn p_drv(cdrom: &mut CdRomCursor<T>) -> Result<IoCursor<&mut CdRomCursor<T>>, io::Error> {
|
||||
IoCursor::new(cdrom, Self::P_OFFSET, Self::P_SIZE)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R> GameFile<'a, R> {
|
||||
impl<T> GameFile<T> {
|
||||
/// Returns the cdrom associated with this game file
|
||||
pub fn cdrom(&mut self) -> &mut CdRomReader<R> {
|
||||
self.cdrom
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a, R: io::Read + io::Seek> GameFile<'a, R> {
|
||||
/// Reads a game file
|
||||
pub fn read_drv<'b>(&'b mut self, name: &str) -> Result<FileReader<'b, R>, ReadDrvError>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
// Read the root directory
|
||||
let root_dir = self
|
||||
.filesystem
|
||||
.root_dir()
|
||||
.read_dir(self.cdrom)
|
||||
.map_err(ReadDrvError::ReadRoot)?;
|
||||
|
||||
// Get the file
|
||||
let entry = root_dir.find(name).ok_or(ReadDrvError::FindFile)?;
|
||||
|
||||
// And read it
|
||||
entry.read_file(self.cdrom).map_err(ReadDrvError::ReadFile)
|
||||
pub fn cdrom(&mut self) -> &mut CdRomCursor<T> {
|
||||
&mut self.cdrom
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,25 +1,64 @@
|
||||
//! Errors
|
||||
|
||||
// Imports
|
||||
use std::io;
|
||||
|
||||
/// Error for [`GameFile::new`](super::GameFile::new)
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum NewError {
|
||||
/// Unable to parse filesystem
|
||||
#[error("Unable to parse filesystem")]
|
||||
ParseFilesystem(#[source] dcb_iso9660::NewError),
|
||||
}
|
||||
|
||||
/// Error for [`GameFile::read_drv`](super::GameFile::read_drv)
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ReadDrvError {
|
||||
/// Unable to read filesystem root
|
||||
#[error("Unable to read filesystem root")]
|
||||
ReadRoot(#[source] dcb_iso9660::entry::ReadDirError),
|
||||
|
||||
/// Unable to find file
|
||||
#[error("Unable to find file")]
|
||||
FindFile,
|
||||
|
||||
/// Unable to read file
|
||||
#[error("Unable to read file")]
|
||||
ReadFile(#[source] dcb_iso9660::entry::ReadFileError),
|
||||
/// Unable to open `A.DRV`
|
||||
#[error("Unable to open `A.DRV` file")]
|
||||
OpenA(#[source] io::Error),
|
||||
|
||||
/// Unable to create `A.DRV` cursor
|
||||
#[error("Unable to create `A.DRV` cursor")]
|
||||
CursorA(#[source] dcb_drv::cursor::NewError),
|
||||
|
||||
/// Unable to open `B.DRV`
|
||||
#[error("Unable to open `B.DRV` file")]
|
||||
OpenB(#[source] io::Error),
|
||||
|
||||
/// Unable to create `B.DRV` cursor
|
||||
#[error("Unable to create `B.DRV` cursor")]
|
||||
CursorB(#[source] dcb_drv::cursor::NewError),
|
||||
|
||||
/// Unable to open `C.DRV`
|
||||
#[error("Unable to open `C.DRV` file")]
|
||||
OpenC(#[source] io::Error),
|
||||
|
||||
/// Unable to create `C.DRV` cursor
|
||||
#[error("Unable to create `C.DRV` cursor")]
|
||||
CursorC(#[source] dcb_drv::cursor::NewError),
|
||||
|
||||
/// Unable to open `E.DRV`
|
||||
#[error("Unable to open `E.DRV` file")]
|
||||
OpenE(#[source] io::Error),
|
||||
|
||||
/// Unable to create `E.DRV` cursor
|
||||
#[error("Unable to create `E.DRV` cursor")]
|
||||
CursorE(#[source] dcb_drv::cursor::NewError),
|
||||
|
||||
/// Unable to open `F.DRV`
|
||||
#[error("Unable to open `F.DRV` file")]
|
||||
OpenF(#[source] io::Error),
|
||||
|
||||
/// Unable to create `F.DRV` cursor
|
||||
#[error("Unable to create `F.DRV` cursor")]
|
||||
CursorF(#[source] dcb_drv::cursor::NewError),
|
||||
|
||||
/// Unable to open `G.DRV`
|
||||
#[error("Unable to open `G.DRV` file")]
|
||||
OpenG(#[source] io::Error),
|
||||
|
||||
/// Unable to create `G.DRV` cursor
|
||||
#[error("Unable to create `G.DRV` cursor")]
|
||||
CursorG(#[source] dcb_drv::cursor::NewError),
|
||||
|
||||
/// Unable to open `P.DRV`
|
||||
#[error("Unable to open `P.DRV` file")]
|
||||
OpenP(#[source] io::Error),
|
||||
|
||||
/// Unable to create `P.DRV` cursor
|
||||
#[error("Unable to create `P.DRV` cursor")]
|
||||
CursorP(#[source] dcb_drv::cursor::NewError),
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user