refactor(formats): rework X360 texture descriptor + xiso reader
WIP: restructure texture.rs (X360TextureDesc accessors / decode path) and adjust the xiso reader. Builds clean (sylpheed-formats). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -14,25 +14,48 @@ use std::path::Path;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use tracing::{debug, info};
|
||||
use xdvdfs::blockdev::OffsetWrapper;
|
||||
use xdvdfs::layout::VolumeDescriptor;
|
||||
|
||||
/// A handle to an open XISO image.
|
||||
pub struct XisoReader<F: Read + Seek> {
|
||||
///
|
||||
/// The inner file is wrapped in an [`OffsetWrapper`] which probes the four
|
||||
/// known XGD partition offsets (raw XISO, XGD1, XGD2, XGD3) at open time,
|
||||
/// so both single-layer raw dumps **and** full dual-layer disc images are
|
||||
/// supported transparently.
|
||||
pub struct XisoReader<F: Read + Seek + Send + Sync> {
|
||||
volume: VolumeDescriptor,
|
||||
file: F,
|
||||
/// Offset-aware block device — all sector reads are shifted by the
|
||||
/// detected partition start offset automatically.
|
||||
file: OffsetWrapper<F, std::io::Error>,
|
||||
}
|
||||
|
||||
impl<F: Read + Seek + Send + Sync + 'static> XisoReader<F> {
|
||||
pub async fn open(mut file: F) -> Result<Self> {
|
||||
let volume = xdvdfs::read::read_volume(&mut file)
|
||||
pub async fn open(file: F) -> Result<Self> {
|
||||
// OffsetWrapper::new probes four known partition offsets:
|
||||
// 0x00000000 — raw XISO (trimmed, sector 0 = XDVDFS start)
|
||||
// 0x183E0000 — XGD1 (original Xbox)
|
||||
// 0x0FD90000 — XGD2 (Xbox 360, most retail titles)
|
||||
// 0x02080000 — XGD3 (Xbox 360, later dual-layer titles)
|
||||
let mut wrapper = OffsetWrapper::new(file).await.map_err(|e| {
|
||||
anyhow::anyhow!(
|
||||
"No valid XDVDFS partition found in this disc image. \
|
||||
Tried raw XISO, XGD1, XGD2, and XGD3 offsets. \
|
||||
Is this a valid Xbox 360 (or original Xbox) disc image? \
|
||||
(internal error: {e:?})"
|
||||
)
|
||||
})?;
|
||||
|
||||
// Re-read the volume descriptor via the wrapper (now at the correct offset).
|
||||
let volume = xdvdfs::read::read_volume(&mut wrapper)
|
||||
.await
|
||||
.context("Failed to read XDVDFS volume descriptor. Is this a valid Xbox 360 ISO?")?;
|
||||
.context("Found XDVDFS partition but failed to parse volume descriptor")?;
|
||||
|
||||
info!(
|
||||
"Opened XISO: root directory table at sector {}",
|
||||
{ let s = volume.root_table.region.sector; s }
|
||||
);
|
||||
Ok(Self { volume, file })
|
||||
Ok(Self { volume, file: wrapper })
|
||||
}
|
||||
|
||||
/// List all files in the disc image, recursively (directories excluded).
|
||||
@@ -135,10 +158,13 @@ impl<F: Read + Seek + Send + Sync + 'static> XisoReader<F> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Open an XISO from a file path (the common case).
|
||||
/// Open a disc image from a file path.
|
||||
///
|
||||
/// Accepts raw XISO dumps and full XGD1/XGD2/XGD3 disc images — the correct
|
||||
/// partition offset is detected automatically.
|
||||
pub async fn open_iso(path: &Path) -> Result<XisoReader<std::fs::File>> {
|
||||
let file = std::fs::File::open(path)
|
||||
.with_context(|| format!("Cannot open ISO: {}", path.display()))?;
|
||||
.with_context(|| format!("Cannot open disc image: {}", path.display()))?;
|
||||
XisoReader::open(file).await
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user