Reverse-engineer the single-stream XBG7 geometry layout (clean-room: hex
inspection + geometric validation of the retail disc's
hidden/resource3d/*.xpr, no game code copied) and present models as
textured 3D meshes in the explorer.
Format (docs/re/structures/xbg7-mesh.md): XBG7 geometry resources sit
inside XPR2 containers alongside TX2D textures. For ~25 single-stream
models (weapons, simple props) the data section is a sequence of
sub-meshes, each an u16-BE triangle-list index buffer followed (after a
fixed 12-byte header) by a stride-24 vertex buffer whose declaration is
in the descriptor: POSITION f32x3 @0x00, NORMAL f16x4 @0x0C, TEXCOORD
f16x2 @0x14. Sub-mesh (vtx,idx) counts come from descriptor tuples.
The +12 vertex offset is pinned by the recovered normals being exactly
unit-length (align16 lands 4 bytes early and silently corrupts every
field). A safety gate rejects any model whose indices are out of range
or whose mean |normal| is not ~1, declining garbage (Stage_S*
placeholders, the complex multi-stream hero-ship body) rather than
mis-decoding it.
- mesh.rs: Xbg7Model::from_xpr2 -> GameMesh { positions, normals, uvs,
indices }; standalone f16->f32; unit + real-disc tests (weapon decodes
to 215v/364t with unit normals + in-range UVs; DeltaSaber body
declined).
- texture.rs: from_xpr2_index / texture_names so the viewer can pick a
model's _col albedo map.
- viewer: loose .xpr with decodable XBG7 spawns Bevy meshes (real normals,
double-sided) textured with the albedo, framed by the orbit camera; the
central egui panel goes transparent so the 3D scene shows through.
Complex multi-stream body meshes (DeltaSaber f004, other vertex layouts)
remain undecoded and are cleanly declined — next target is dynamic RE.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
63 lines
1.7 KiB
Rust
63 lines
1.7 KiB
Rust
//! # sylpheed-formats
|
|
//!
|
|
//! Asset format parsers for Project Sylpheed: Arc of Deception (Xbox 360).
|
|
//!
|
|
//! This crate handles:
|
|
//! - Reading game files from XISO disc images (native only)
|
|
//! - Reading IPFB archives (`*.pak` / `*.pNN`) and the `IDXD` definition objects inside
|
|
//! - Parsing Xbox 360 texture formats (XPR2 containers + DXT de-tiling)
|
|
//! - Parsing mesh formats (to be reverse engineered)
|
|
//! - Parsing audio formats (XMA → standard PCM)
|
|
//!
|
|
//! ## Platform notes
|
|
//! XISO reading is only available on native (Windows/macOS/Linux).
|
|
//! On WASM, assets must be pre-extracted and served over HTTP.
|
|
|
|
pub mod texture;
|
|
pub mod vfs;
|
|
|
|
// IPFB TOC name-hash (path → 32-bit key), recovered from the retail title
|
|
pub mod hash;
|
|
|
|
// IPFB archive (`*.pak` index + `*.pNN` segments) reader
|
|
pub mod pak;
|
|
|
|
// IDXD reflective object (ship / weapon / effect / menu definitions) reader
|
|
pub mod idxd;
|
|
|
|
// IXUD localized string / subtitle table reader
|
|
pub mod ixud;
|
|
|
|
// Embedded font (OTF / TTF / ttcf) metadata
|
|
pub mod font;
|
|
|
|
// T8aD 2D UI/HUD texture
|
|
pub mod t8ad;
|
|
|
|
// RATC nested resource bundle
|
|
pub mod ratc;
|
|
|
|
// LSTA sprite list (inline T8aD frames)
|
|
pub mod lsta;
|
|
|
|
// XISO reading is not available in-browser
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
pub mod xiso;
|
|
|
|
// Mesh parsing — scaffold for reverse engineering
|
|
pub mod mesh;
|
|
|
|
// Audio parsing — scaffold for XMA handling
|
|
pub mod audio;
|
|
|
|
/// Re-export the most commonly used types at the crate root.
|
|
pub use font::FontInfo;
|
|
pub use idxd::{IdxdError, IdxdObject};
|
|
pub use ixud::{Cue, Subtitle};
|
|
pub use mesh::{GameMesh, Xbg7Model};
|
|
pub use ratc::RatcChild;
|
|
pub use t8ad::T8adImage;
|
|
pub use pak::{PakArchive, PakEntry, PakError};
|
|
pub use texture::{X360Texture, X360TextureFormat};
|
|
pub use vfs::{GameAssets, VfsError};
|