bdat/io/
mod.rs

1pub(crate) mod detect;
2pub(crate) mod legacy;
3pub(crate) mod modern;
4
5mod read;
6
7pub use read::BdatFile;
8
9const BDAT_MAGIC: [u8; 4] = [b'B', b'D', b'A', b'T'];
10
11/// Alias for [`byteorder::LittleEndian`], i.e. the byte order used in Xenoblade 3D and
12/// in the Switch games.
13pub type SwitchEndian = byteorder::LittleEndian;
14/// Alias for [`byteorder::BigEndian`], i.e. the byte order used in the Wii/Wii U games.
15pub type WiiEndian = byteorder::BigEndian;
16
17/// The major categorization of the different BDAT formats.
18#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
19#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
20pub enum BdatVersion {
21    /// Used in all games prior to XC3
22    Legacy(LegacyVersion),
23    /// Used in XC3
24    Modern,
25}
26
27/// Subversion for legacy table formats.
28///
29/// The high-level format (i.e. [`LegacyTable`]) is the same
30/// for all of these. Only some parts of the internal binary representation
31/// are different.
32///
33/// [`LegacyTable`]: crate::legacy::LegacyTable
34#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
35#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
36pub enum LegacyVersion {
37    /// Used in XC1 (Wii)
38    Wii,
39    /// Used in XC3D (New 3DS)
40    New3ds,
41    /// Used in XC2/XCDE
42    Switch,
43    /// Used in XCX
44    X,
45}
46
47impl BdatVersion {
48    pub fn is_legacy(&self) -> bool {
49        *self != BdatVersion::Modern
50    }
51
52    pub fn is_modern(&self) -> bool {
53        !self.is_legacy()
54    }
55
56    /// Gets whether the version forces labels to be hashed.
57    pub fn are_labels_hashed(&self) -> bool {
58        self.is_modern()
59    }
60}
61
62impl LegacyVersion {
63    /// Returns the size in bytes of the table header.
64    pub(crate) const fn table_header_size(&self) -> usize {
65        if self.is_wii_table_format() {
66            legacy::HEADER_SIZE_WII
67        } else {
68            legacy::HEADER_SIZE
69        }
70    }
71
72    pub(crate) const fn is_wii_table_format(&self) -> bool {
73        matches!(self, Self::Wii | Self::New3ds)
74    }
75}
76
77impl From<LegacyVersion> for BdatVersion {
78    fn from(value: LegacyVersion) -> Self {
79        Self::Legacy(value)
80    }
81}