From 46a814ac736f1b36237214933e8a3a803eba4d1a Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Fri, 3 Nov 2023 15:18:26 -0400 Subject: [PATCH] Add PS3 SFB and SFO models --- PlayStation3/Constants.cs | 57 ++++++++++++ PlayStation3/Enums.cs | 31 +++++++ PlayStation3/SFB.cs | 140 +++++++++++++++++++++++++++++ PlayStation3/SFO.cs | 75 ++++++++++++++++ PlayStation3/SFOHeader.cs | 35 ++++++++ PlayStation3/SFOIndexTableEntry.cs | 33 +++++++ 6 files changed, 371 insertions(+) create mode 100644 PlayStation3/Constants.cs create mode 100644 PlayStation3/Enums.cs create mode 100644 PlayStation3/SFB.cs create mode 100644 PlayStation3/SFO.cs create mode 100644 PlayStation3/SFOHeader.cs create mode 100644 PlayStation3/SFOIndexTableEntry.cs diff --git a/PlayStation3/Constants.cs b/PlayStation3/Constants.cs new file mode 100644 index 0000000..f43fa76 --- /dev/null +++ b/PlayStation3/Constants.cs @@ -0,0 +1,57 @@ +// TODO: Add more constants from the wiki +namespace SabreTools.Models.PlayStation3 +{ + /// + public static class Constants + { + #region Hybrid Flags + + /// + /// Not dependant of other disc files, enables a network connection to PSN store + /// + public const char FlagDiscBenefits = 'S'; + + /// + /// dev_bdvd/PS3_CONTENT/THEMEDIR/PARAM.SFO + /// + public const char FlagThemes = 'T'; + + /// + /// dev_bdvd/PS3_CONTENT/VIDEODIR/PARAM.SFO + /// + public const char FlagVideo = 'V'; + + /// + /// friends? (unknown yet, usually combined with g/p?) + /// + public const char FlagFriends = 'f'; + + /// + /// dev_bdvd/PS3_GAME/USRDIR/PARAM.SFO + /// dev_bdvd/PS3_EXTRA/PARAM.SFO + /// + public const char FlagGameExtras = 'g'; + + /// + /// music? + /// + public const char FlagMusic = 'm'; + + /// + /// photo? (unknown yet, used with v, fv,..) + /// + public const char FlagPhoto = 'p'; + + /// + /// dev_bdvd/PS3_UPDATE/PS3UPDAT.PUP + /// + public const char FlagFirmwareUpdate = 'u'; + + /// + /// dev_bdvd/PS3_VPRM/PARAM.SFO + /// + public const char FlagMovie = 'v'; + + #endregion + } +} \ No newline at end of file diff --git a/PlayStation3/Enums.cs b/PlayStation3/Enums.cs new file mode 100644 index 0000000..13276e3 --- /dev/null +++ b/PlayStation3/Enums.cs @@ -0,0 +1,31 @@ +// TODO: Add more enumerations from the wiki +namespace SabreTools.Models.PlayStation3 +{ + /// + public enum DataFormat : ushort + { + /// + /// UTF-8 Special Mode, NOT NULL terminated + /// + /// + /// Used in SFO's generated by the system and/or linked to an user (Game Saves and Trophies). + /// + UTF8SpecialMode = 0x0004, + + /// + /// UTF-8 character string, NULL terminated (0x00) + /// + /// + /// Can be used any character from the system fonts. The NULL byte is counted as part of the used bytes in len + /// + UTF8 = 0x0204, + + /// + /// Integer 32 bits unsigned + /// + /// + /// Always has a length of 4 bytes in len and max_len (even in the case some bytes are not used, all them are marked as used) + /// + Integer = 0x0404, + } +} \ No newline at end of file diff --git a/PlayStation3/SFB.cs b/PlayStation3/SFB.cs new file mode 100644 index 0000000..a848c11 --- /dev/null +++ b/PlayStation3/SFB.cs @@ -0,0 +1,140 @@ +namespace SabreTools.Models.PlayStation3 +{ + /// + public class SFB + { + /// + /// ".SFB" + /// +#if NET48 + public byte[] Magic { get; set; } +#else + public byte[]? Magic { get; set; } +#endif + + /// + /// File version(?) + /// + public uint FileVersion { get; set; } + + /// + /// Unknown (zeroes) + /// + /// 0x18 bytes +#if NET48 + public byte[] Reserved1 { get; set; } +#else + public byte[]? Reserved1 { get; set; } +#endif + + /// + /// "HYBRID_FLAG" (Flags type) + /// + /// 0x10 bytes +#if NET48 + public string FlagsType { get; set; } +#else + public string? FlagsType { get; set; } +#endif + + /// + /// Disc Content Data Offset + /// + public uint DiscContentDataOffset { get; set; } + + /// + /// Disc Content Data Length + /// + public uint DiscContentDataLength { get; set; } + + /// + /// Unknown (zeroes) + /// + /// 0x08 bytes +#if NET48 + public byte[] Reserved2 { get; set; } +#else + public byte[]? Reserved2 { get; set; } +#endif + + /// + /// "TITLE_ID" (Disc Title Name) + /// + /// 0x08 bytes +#if NET48 + public string DiscTitleName { get; set; } +#else + public string? DiscTitleName { get; set; } +#endif + + /// + /// Unknown (zeroes) + /// + /// 0x08 bytes +#if NET48 + public byte[] Reserved3 { get; set; } +#else + public byte[]? Reserved3 { get; set; } +#endif + + /// + /// Disc Version Data Offset + /// + public uint DiscVersionDataOffset { get; set; } + + /// + /// Disc Version Data Length + /// + public uint DiscVersionDataLength { get; set; } + + /// + /// Unknown (zeroes) + /// + /// 0x188 bytes +#if NET48 + public byte[] Reserved4 { get; set; } +#else + public byte[]? Reserved4 { get; set; } +#endif + + /// + /// Disc Content (Hybrid Flags) + /// + /// 0x20 bytes +#if NET48 + public string DiscContent { get; set; } +#else + public string? DiscContent { get; set; } +#endif + + /// + /// Disc Title + /// + /// 0x10 bytes +#if NET48 + public string DiscTitle { get; set; } +#else + public string? DiscTitle { get; set; } +#endif + + /// + /// Disc Version + /// + /// 0x10 bytes +#if NET48 + public string DiscVersion { get; set; } +#else + public string? DiscVersion { get; set; } +#endif + + /// + /// Unknown (zeroes) + /// + /// 0x3C0 bytes +#if NET48 + public byte[] Reserved5 { get; set; } +#else + public byte[]? Reserved5 { get; set; } +#endif + } +} diff --git a/PlayStation3/SFO.cs b/PlayStation3/SFO.cs new file mode 100644 index 0000000..ff43b66 --- /dev/null +++ b/PlayStation3/SFO.cs @@ -0,0 +1,75 @@ +namespace SabreTools.Models.PlayStation3 +{ + /// + public class SFO + { + /// + /// SFO header + /// +#if NET48 + public SFOHeader Header { get; set; } +#else + public SFOHeader? Header { get; set; } +#endif + + /// + /// Index table + /// +#if NET48 + public SFOIndexTableEntry[] IndexTable { get; set; } +#else + public SFOIndexTableEntry[]? IndexTable { get; set; } +#endif + + /// + /// Key table + /// + /// + /// Composed by a number of key entries defined with tables_entries in + /// the header, are short utf8 strings in capitals, NULL terminated + /// (0x00), and ordered alphabetically (from A to Z). This alphabetically + /// order defines the order of the associated entries in the other + /// two tables (index_table, and data_table) + /// + /// The end offset of this table needs to be aligned to a multiply of + /// 32bits (4 bytes), this is made with a padding at the end of key_table + /// when needed (in a few SFO's the table is aligned naturally as a + /// coincidence caused by the length of the key names used, when this + /// happens there is no padding needed) + /// +#if NET48 + public string[] KeyTable { get; set; } +#else + public string[]? KeyTable { get; set; } +#endif + + /// + /// Padding + /// + /// Enough bytes to align to 4 bytes +#if NET48 + public byte[] Padding { get; set; } +#else + public byte[]? Padding { get; set; } +#endif + + /// + /// Data table + /// + /// + /// Composed by a number of data entries defined with tables_entries in + /// the header, every entry in this table is defined by the associated entry + /// in the index_table by using: fmt, len, max_len, and offset. There is + /// no padding between entries neither at the end of this table + /// + /// Some data entries can be filled with zeroes (not used, but availables for + /// being used). This entries can be considered reserved, and are marked with + /// a len = 0 in the associated entry in the index_table + /// +#if NET48 + public byte[][] DataTable { get; set; } +#else + public byte[][]? DataTable { get; set; } +#endif + } +} diff --git a/PlayStation3/SFOHeader.cs b/PlayStation3/SFOHeader.cs new file mode 100644 index 0000000..5a6412e --- /dev/null +++ b/PlayStation3/SFOHeader.cs @@ -0,0 +1,35 @@ +namespace SabreTools.Models.PlayStation3 +{ + /// + public class SFOHeader + { + /// + /// "\0PSF" + /// +#if NET48 + public byte[] Magic { get; set; } +#else + public byte[]? Magic { get; set; } +#endif + + /// + /// Version + /// + public uint Version { get; set; } + + /// + /// Absolute start offset of key_table + /// + public uint KeyTableStart { get; set; } + + /// + /// Absolute start offset of data_table + /// + public uint DataTableStart { get; set; } + + /// + /// Number of entries in index_table, key_table, and data_table + /// + public uint TablesEntries { get; set; } + } +} diff --git a/PlayStation3/SFOIndexTableEntry.cs b/PlayStation3/SFOIndexTableEntry.cs new file mode 100644 index 0000000..f4b6e9d --- /dev/null +++ b/PlayStation3/SFOIndexTableEntry.cs @@ -0,0 +1,33 @@ +namespace SabreTools.Models.PlayStation3 +{ + /// + public class SFOIndexTableEntry + { + /// + /// Key relative offset. + /// (Absolute start offset of key) - (Absolute start offset of key_table) + /// + public ushort KeyOffset { get; set; } + + /// + /// Data type + /// + public DataFormat DataFormat { get; set; } + + /// + /// Data used length + /// + public uint DataLength { get; set; } + + /// + /// Data total length. TITLE_ID is always = 16 bytes + /// + public uint DataMaxLength { get; set; } + + /// + /// Data relative offset. + /// (Absolute start offset of data_1) - (Absolute start offset of data_table) + /// + public uint DataOffset { get; set; } + } +}