Migrate support file models from Models

This commit is contained in:
Matt Nadareski
2025-09-26 11:42:28 -04:00
parent 3af19510a8
commit c6082fa7c7
210 changed files with 4185 additions and 272 deletions

View File

@@ -2,7 +2,7 @@ using System.Collections.Generic;
using System.IO;
using System.Text;
using SabreTools.IO.Extensions;
using SabreTools.Models.AACS;
using SabreTools.Serialization.Models.AACS;
namespace SabreTools.Serialization.Deserializers
{

View File

@@ -1,14 +1,14 @@
using System.IO;
using System.Text;
using SabreTools.IO.Extensions;
using static SabreTools.Models.PlayStation4.Constants;
using static SabreTools.Serialization.Models.PlayStation4.Constants;
namespace SabreTools.Serialization.Deserializers
{
public class AppPkgHeader : BaseBinaryDeserializer<SabreTools.Models.PlayStation4.AppPkgHeader>
public class AppPkgHeader : BaseBinaryDeserializer<SabreTools.Serialization.Models.PlayStation4.AppPkgHeader>
{
/// <inheritdoc/>
public override SabreTools.Models.PlayStation4.AppPkgHeader? Deserialize(Stream? data)
public override SabreTools.Serialization.Models.PlayStation4.AppPkgHeader? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || !data.CanRead)
@@ -17,7 +17,7 @@ namespace SabreTools.Serialization.Deserializers
try
{
// Create a new app.pkg header to fill
var appPkgHeader = new SabreTools.Models.PlayStation4.AppPkgHeader();
var appPkgHeader = new SabreTools.Serialization.Models.PlayStation4.AppPkgHeader();
appPkgHeader.Magic = data.ReadUInt32BigEndian();
if (appPkgHeader.Magic != AppPkgMagic)

View File

@@ -1,8 +1,8 @@
using System.IO;
using System.Text;
using SabreTools.IO.Extensions;
using SabreTools.Models.BDPlus;
using static SabreTools.Models.BDPlus.Constants;
using SabreTools.Serialization.Models.BDPlus;
using static SabreTools.Serialization.Models.BDPlus.Constants;
namespace SabreTools.Serialization.Deserializers
{

View File

@@ -3,12 +3,12 @@ using System.Text;
namespace SabreTools.Serialization.Deserializers
{
public class Catalog : JsonFile<SabreTools.Models.Xbox.Catalog>
public class Catalog : JsonFile<SabreTools.Serialization.Models.Xbox.Catalog>
{
#region IByteDeserializer
/// <remarks>Catalog.js file is encoded as UTF-16 LE</remarks>
public override SabreTools.Models.Xbox.Catalog? Deserialize(byte[]? data, int offset)
public override SabreTools.Serialization.Models.Xbox.Catalog? Deserialize(byte[]? data, int offset)
=> Deserialize(data, offset, new UnicodeEncoding());
#endregion
@@ -16,7 +16,7 @@ namespace SabreTools.Serialization.Deserializers
#region IFileDeserializer
/// <remarks>Catalog.js file is encoded as UTF-16 LE</remarks>
public override SabreTools.Models.Xbox.Catalog? Deserialize(string? path)
public override SabreTools.Serialization.Models.Xbox.Catalog? Deserialize(string? path)
=> Deserialize(path, new UnicodeEncoding());
#endregion
@@ -24,7 +24,7 @@ namespace SabreTools.Serialization.Deserializers
#region IStreamDeserializer
/// <remarks>Catalog.js file is encoded as UTF-16 LE</remarks>
public override SabreTools.Models.Xbox.Catalog? Deserialize(Stream? data)
public override SabreTools.Serialization.Models.Xbox.Catalog? Deserialize(Stream? data)
=> Deserialize(data, new UnicodeEncoding());
#endregion

View File

@@ -3,14 +3,14 @@ using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using SabreTools.Models.CueSheets;
using SabreTools.Serialization.Models.CueSheets;
namespace SabreTools.Serialization.Deserializers
{
public class CueSheet : BaseBinaryDeserializer<SabreTools.Models.CueSheets.CueSheet>
public class CueSheet : BaseBinaryDeserializer<SabreTools.Serialization.Models.CueSheets.CueSheet>
{
/// <inheritdoc/>
public override SabreTools.Models.CueSheets.CueSheet? Deserialize(Stream? data)
public override SabreTools.Serialization.Models.CueSheets.CueSheet? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || !data.CanRead)
@@ -20,7 +20,7 @@ namespace SabreTools.Serialization.Deserializers
{
// Setup the reader and output
var reader = new StreamReader(data, Encoding.UTF8);
var cueSheet = new SabreTools.Models.CueSheets.CueSheet();
var cueSheet = new SabreTools.Serialization.Models.CueSheets.CueSheet();
var cueFiles = new List<CueFile>();
// Read the next line from the input

View File

@@ -4,10 +4,10 @@ using SabreTools.IO.Extensions;
namespace SabreTools.Serialization.Deserializers
{
public class IRD : BaseBinaryDeserializer<SabreTools.Models.IRD.File>
public class IRD : BaseBinaryDeserializer<SabreTools.Serialization.Models.IRD.File>
{
/// <inheritdoc/>
public override SabreTools.Models.IRD.File? Deserialize(Stream? data)
public override SabreTools.Serialization.Models.IRD.File? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || !data.CanRead)
@@ -16,7 +16,7 @@ namespace SabreTools.Serialization.Deserializers
try
{
// Deserialize the IRD
var ird = new SabreTools.Models.IRD.File();
var ird = new SabreTools.Serialization.Models.IRD.File();
ird.Magic = data.ReadBytes(4);
string magic = Encoding.ASCII.GetString(ird.Magic);

View File

@@ -2,8 +2,8 @@ using System.Collections.Generic;
using System.IO;
using System.Text;
using SabreTools.IO.Extensions;
using SabreTools.Models.PIC;
using static SabreTools.Models.PIC.Constants;
using SabreTools.Serialization.Models.PIC;
using static SabreTools.Serialization.Models.PIC.Constants;
namespace SabreTools.Serialization.Deserializers
{

View File

@@ -1,14 +1,14 @@
using System.IO;
using System.Text;
using SabreTools.IO.Extensions;
using static SabreTools.Models.PlayStation3.Constants;
using static SabreTools.Serialization.Models.PlayStation3.Constants;
namespace SabreTools.Serialization.Deserializers
{
public class SFB : BaseBinaryDeserializer<SabreTools.Models.PlayStation3.SFB>
public class SFB : BaseBinaryDeserializer<SabreTools.Serialization.Models.PlayStation3.SFB>
{
/// <inheritdoc/>
public override SabreTools.Models.PlayStation3.SFB? Deserialize(Stream? data)
public override SabreTools.Serialization.Models.PlayStation3.SFB? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || !data.CanRead)
@@ -17,7 +17,7 @@ namespace SabreTools.Serialization.Deserializers
try
{
// Deserialize the SFB
var sfb = new SabreTools.Models.PlayStation3.SFB();
var sfb = new SabreTools.Serialization.Models.PlayStation3.SFB();
sfb.Magic = data.ReadUInt32BigEndian();
if (sfb.Magic != SFBMagic)

View File

@@ -1,14 +1,14 @@
using System.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.PlayStation3;
using static SabreTools.Models.PlayStation3.Constants;
using SabreTools.Serialization.Models.PlayStation3;
using static SabreTools.Serialization.Models.PlayStation3.Constants;
namespace SabreTools.Serialization.Deserializers
{
public class SFO : BaseBinaryDeserializer<SabreTools.Models.PlayStation3.SFO>
public class SFO : BaseBinaryDeserializer<SabreTools.Serialization.Models.PlayStation3.SFO>
{
/// <inheritdoc/>
public override SabreTools.Models.PlayStation3.SFO? Deserialize(Stream? data)
public override SabreTools.Serialization.Models.PlayStation3.SFO? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || !data.CanRead)
@@ -17,7 +17,7 @@ namespace SabreTools.Serialization.Deserializers
try
{
// Create a new SFO to fill
var sfo = new SabreTools.Models.PlayStation3.SFO();
var sfo = new SabreTools.Serialization.Models.PlayStation3.SFO();
#region Header

View File

@@ -2,17 +2,17 @@ using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Deserializers
{
public partial class XMID : IStringDeserializer<SabreTools.Models.Xbox.XMID>
public partial class XMID : IStringDeserializer<SabreTools.Serialization.Models.Xbox.XMID>
{
/// <inheritdoc cref="IStringDeserializer.Deserialize(string?)"/>
public static SabreTools.Models.Xbox.XMID? DeserializeString(string? str)
public static SabreTools.Serialization.Models.Xbox.XMID? DeserializeString(string? str)
{
var deserializer = new XMID();
return deserializer.Deserialize(str);
}
/// <inheritdoc/>
public SabreTools.Models.Xbox.XMID? Deserialize(string? str)
public SabreTools.Serialization.Models.Xbox.XMID? Deserialize(string? str)
{
if (string.IsNullOrEmpty(str))
return null;
@@ -29,12 +29,12 @@ namespace SabreTools.Serialization.Deserializers
/// </summary>
/// <param name="xmidString">XMID string to attempt to parse</param>
/// <returns>Filled XMID on success, null on error</returns>
private static SabreTools.Models.Xbox.XMID? ParseXMID(string? xmidString)
private static SabreTools.Serialization.Models.Xbox.XMID? ParseXMID(string? xmidString)
{
if (xmidString == null || xmidString.Length != 8)
return null;
var xmid = new SabreTools.Models.Xbox.XMID();
var xmid = new SabreTools.Serialization.Models.Xbox.XMID();
xmid.PublisherIdentifier = xmidString.Substring(0, 2);
xmid.GameID = xmidString.Substring(2, 3);

View File

@@ -2,17 +2,17 @@ using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Deserializers
{
public partial class XeMID : IStringDeserializer<SabreTools.Models.Xbox.XeMID>
public partial class XeMID : IStringDeserializer<SabreTools.Serialization.Models.Xbox.XeMID>
{
/// <inheritdoc cref="IStringDeserializer.Deserialize(string?)"/>
public static SabreTools.Models.Xbox.XeMID? DeserializeString(string? str)
public static SabreTools.Serialization.Models.Xbox.XeMID? DeserializeString(string? str)
{
var deserializer = new XeMID();
return deserializer.Deserialize(str);
}
/// <inheritdoc/>
public SabreTools.Models.Xbox.XeMID? Deserialize(string? str)
public SabreTools.Serialization.Models.Xbox.XeMID? Deserialize(string? str)
{
if (string.IsNullOrEmpty(str))
return null;
@@ -29,14 +29,14 @@ namespace SabreTools.Serialization.Deserializers
/// </summary>
/// <param name="xemidString">XeMID string to attempt to parse</param>
/// <returns>Filled XeMID on success, null on error</returns>
private static SabreTools.Models.Xbox.XeMID? ParseXeMID(string? xemidString)
private static SabreTools.Serialization.Models.Xbox.XeMID? ParseXeMID(string? xemidString)
{
if (xemidString == null)
return null;
if (!(xemidString.Length == 13 || xemidString.Length == 14 || xemidString.Length == 21 || xemidString.Length == 22))
return null;
var xemid = new SabreTools.Models.Xbox.XeMID();
var xemid = new SabreTools.Serialization.Models.Xbox.XeMID();
xemid.PublisherIdentifier = xemidString.Substring(0, 2);
xemid.PlatformIdentifier = xemidString[2];

View File

@@ -0,0 +1,16 @@
using System.Runtime.InteropServices;
namespace SabreTools.Serialization.Models.AACS
{
/// <summary>
/// This record type is undocumented but found in real media key blocks
/// </summary>
public sealed class CopyrightRecord : Record
{
/// <summary>
/// Null-terminated ASCII string representing the copyright
/// </summary>
[MarshalAs(UnmanagedType.LPStr)]
public string? Copyright;
}
}

View File

@@ -0,0 +1,25 @@
using System.Runtime.InteropServices;
namespace SabreTools.Serialization.Models.AACS
{
/// <see href="https://aacsla.com/wp-content/uploads/2019/02/AACS_Spec_Common_Final_0953.pdf"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class DriveRevocationListEntry
{
/// <summary>
/// A 2-byte Range value indicates the range of revoked IDs starting
/// from the ID contained in the record. A value of zero in the Range
/// field indicates that only one ID is being revoked, a value of one
/// in the Range field indicates two IDs are being revoked, and so on.
/// </summary>
public ushort Range;
/// <summary>
/// A 6-byte Drive ID value identifying the Licensed Drive being revoked
/// (or the first in a range of Licensed Drives being revoked, in the
/// case of a non-zero Range value).
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[]? DriveID;
}
}

View File

@@ -0,0 +1,26 @@
namespace SabreTools.Serialization.Models.AACS
{
/// <summary>
/// A properly formatted type 3 or type 4 Media Key Block contains exactly
/// one Drive Revocation List Record. It follows the Host Revocation List
/// Record, although it may not immediately follow it.
///
/// The Drive Revocation List Record is identical to the Host Revocation
/// List Record, except it has type 2016, and it contains Drive Revocation
/// List Entries, not Host Revocation List Entries. The Drive Revocation List
/// Entries refer to Drive IDs in the Drive Certificates.
/// </summary>
/// <see href="https://aacsla.com/wp-content/uploads/2019/02/AACS_Spec_Common_Final_0953.pdf"/>
public sealed class DriveRevocationListRecord : Record
{
/// <summary>
/// The total number of Drive Revocation List Entry fields that follow.
/// </summary>
public uint TotalNumberOfEntries { get; set; }
/// <summary>
/// Revocation list entries
/// </summary>
public DriveRevocationSignatureBlock[]? SignatureBlocks { get; set; }
}
}

View File

@@ -0,0 +1,17 @@
namespace SabreTools.Serialization.Models.AACS
{
/// <see href="https://aacsla.com/wp-content/uploads/2019/02/AACS_Spec_Common_Final_0953.pdf"/>
public sealed class DriveRevocationSignatureBlock
{
/// <summary>
/// The number of Drive Revocation List Entry fields in the signature block.
/// </summary>
public uint NumberOfEntries { get; set; }
/// <summary>
/// A list of 8-byte Host Drive List Entry fields, the length of this
/// list being equal to the number in the signature block.
/// </summary>
public DriveRevocationListEntry[]? EntryFields { get; set; }
}
}

View File

@@ -0,0 +1,23 @@
namespace SabreTools.Serialization.Models.AACS
{
/// <summary>
/// A properly formatted MKB shall contain an End of Media Key Block Record.
/// When a device encounters this Record it stops processing the MKB, using
/// whatever Km value it has calculated up to that point as the final Km for
/// that MKB (pending possible checks for correctness of the key, as
/// described previously).
/// </summary>
/// <see href="https://aacsla.com/wp-content/uploads/2019/02/AACS_Spec_Common_Final_0953.pdf"/>
public sealed class EndOfMediaKeyBlockRecord : Record
{
/// <summary>
/// AACS LAs signature on the data in the Media Key Block up to,
/// but not including, this record. Devices depending on the Version
/// Number in the Type and Version Record must verify the signature.
/// Other devices may ignore the signature data. If any device
/// determines that the signature does not verify or is omitted, it
/// must refuse to use the Media Key.
/// </summary>
public byte[]? SignatureData { get; set; }
}
}

View File

@@ -0,0 +1,69 @@
namespace SabreTools.Serialization.Models.AACS
{
public enum MediaKeyBlockType : uint
{
/// <summary>
/// (Type 3). This is a normal Media Key Block suitable for being recorded
/// on a AACS Recordable Media. Both Class I and Class II Licensed Products
/// use it to directly calculate the Media Key.
/// </summary>
Type3 = 0x00031003,
/// <summary>
/// (Type 4). This is a Media Key Block that has been designed to use Key
/// Conversion Data (KCD). Thus, it is suitable only for pre-recorded media
/// from which the KCD is derived. Both Class I and Class II Licensed Products
/// use it to directly calculate the Media Key.
/// </summary>
Type4 = 0x00041003,
/// <summary>
/// (Type 10). This is a Class II Media Key Block (one that has the functionality
/// of a Sequence Key Block). This can only be processed by Class II Licensed
/// Products; Class I Licensed Products are revoked in Type 10 Media Key Blocks
/// and cannot process them. This type does not contain the Host Revocation List
/// Record, the Drive Revocation List Record, and the Media Key Data Record, as
/// described in the following sections. It does contain the records shown in
/// Section 3.2.5.2, which are only processed by Class II Licensed Products.
/// </summary>
Type10 = 0x000A1003,
/// <summary>
/// Type 2.0 Category C.
/// This is the Media Key Block Type found on "UHD" media (AACS v2.0)
/// </summary>
/// <see href="https://code.videolan.org/videolan/libaacs/-/blob/master/src/libaacs/mkb.h"/>
Type20 = 0x48141003,
/// <summary>
/// Type 2.1 Category C.
/// This is the Media Key Block Type found on "UHD" media (AACS v2.1)
/// </summary>
/// <see href="https://code.videolan.org/videolan/libaacs/-/blob/master/src/libaacs/mkb.h"/>
Type21 = 0x48151003,
}
public enum RecordType : byte
{
EndOfMediaKeyBlock = 0x02,
ExplicitSubsetDifference = 0x04,
MediaKeyData = 0x05,
SubsetDifferenceIndex = 0x07,
MediaKeyVariantData = 0x0C,
TypeAndVersion = 0x10,
DriveRevocationList = 0x20,
HostRevocationList = 0x21,
VerifyMediaKey = 0x81,
// Not documented
Copyright = 0x7F,
// Record types only found in UHD media (AACS v2)
// <see href="https://code.videolan.org/videolan/libaacs/-/blob/master/src/devtools/mkb_dump.c"/>
Unknown0x28_AACS2 = 0x28,
DriveRevocationList_AACS2 = 0x30,
HostRevocationList_AACS2 = 0x31,
VerifyMediaKey_AACS2 = 0x86,
EmptyRecord0xF8_AACS2 = 0xF8,
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Serialization.Models.AACS
{
/// <see href="https://aacsla.com/wp-content/uploads/2019/02/AACS_Spec_Common_Final_0953.pdf"/>
public sealed class ExplicitSubsetDifferenceRecord : Record
{
/// <summary>
/// In this record, each subset-difference is encoded with 5 bytes.
/// </summary>
public SubsetDifference[]? SubsetDifferences { get; set; }
}
}

View File

@@ -0,0 +1,13 @@
namespace SabreTools.Serialization.Models.AACS
{
/// <summary>
/// This represents any record that does not have a concrete model yet
/// </summary>
public sealed class GenericRecord : Record
{
/// <summary>
/// Unparsed data comprising the record after the header
/// </summary>
public byte[]? Data { get; set; }
}
}

View File

@@ -0,0 +1,25 @@
using System.Runtime.InteropServices;
namespace SabreTools.Serialization.Models.AACS
{
/// <see href="https://aacsla.com/wp-content/uploads/2019/02/AACS_Spec_Common_Final_0953.pdf"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class HostRevocationListEntry
{
/// <summary>
/// A 2-byte Range value indicates the range of revoked IDs starting
/// from the ID contained in the record. A value of zero in the Range
/// field indicates that only one ID is being revoked, a value of one
/// in the Range field indicates two IDs are being revoked, and so on.
/// </summary>
public ushort Range;
/// <summary>
/// A 6-byte Host ID value identifying the host being revoked (or the
/// first in a range of hosts being revoked, in the case of a non-zero
/// Range value).
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[]? HostID;
}
}

View File

@@ -0,0 +1,29 @@
namespace SabreTools.Serialization.Models.AACS
{
/// <summary>
/// A properly formatted type 3 or type 4 Media Key Block shall have exactly
/// one Host Revocation List Record as its second record. This record provides
/// a list of hosts that have been revoked by the AACS LA. The AACS specification
/// is applicable to PC-based system where a Licensed Drive and PC Host act
/// together as the Recording Device and/or Playback Device for AACS Content.
/// AACS uses a drive-host authentication protocol for the host to verify the
/// integrity of the data received from the Licensed Drive, and for the Licensed
/// Drive to check the validity of the host application. The Type and Version
/// Record and the Host Revocation List Record are guaranteed to be the first two
/// records of a Media Key Block, to make it easier for Licensed Drives to extract
/// this data from an arbitrary Media Key Block.
/// </summary>
/// <see href="https://aacsla.com/wp-content/uploads/2019/02/AACS_Spec_Common_Final_0953.pdf"/>
public sealed class HostRevocationListRecord : Record
{
/// <summary>
/// The total number of Host Revocation List Entry fields that follow.
/// </summary>
public uint TotalNumberOfEntries { get; set; }
/// <summary>
/// Revocation list entries
/// </summary>
public HostRevocationSignatureBlock[]? SignatureBlocks { get; set; }
}
}

View File

@@ -0,0 +1,17 @@
namespace SabreTools.Serialization.Models.AACS
{
/// <see href="https://aacsla.com/wp-content/uploads/2019/02/AACS_Spec_Common_Final_0953.pdf"/>
public sealed class HostRevocationSignatureBlock
{
/// <summary>
/// The number of Host Revocation List Entry fields in the signature block.
/// </summary>
public uint NumberOfEntries { get; set; }
/// <summary>
/// A list of 8-byte Host Revocation List Entry fields, the length of this
/// list being equal to the number in the signature block.
/// </summary>
public HostRevocationListEntry[]? EntryFields { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
namespace SabreTools.Serialization.Models.AACS
{
/// <summary>
/// A Media Key Block is formatted as a sequence of contiguous Records.
/// </summary>
/// <see href="https://aacsla.com/wp-content/uploads/2019/02/AACS_Spec_Common_Final_0953.pdf"/>
public sealed class MediaKeyBlock
{
/// <summary>
/// Records
/// </summary>
public Record[]? Records { get; set; }
}
}

View File

@@ -0,0 +1,18 @@
namespace SabreTools.Serialization.Models.AACS
{
/// <summary>
/// This record gives the associated encrypted media key data for the
/// subset-differences identified in the Explicit Subset-Difference Record.
/// </summary>
/// <see href="https://aacsla.com/wp-content/uploads/2019/02/AACS_Spec_Common_Final_0953.pdf"/>
public sealed class MediaKeyDataRecord : Record
{
/// <summary>
/// Each subset difference has its associated 16 bytes in this
/// record, in the same order it is encountered in the subset-difference
/// record. This 16 bytes is the ciphertext value C in the media
/// key calculation.
/// </summary>
public byte[][]? MediaKeyData { get; set; }
}
}

View File

@@ -0,0 +1,28 @@
namespace SabreTools.Serialization.Models.AACS
{
/// <summary>
/// Each Record begins with a one-byte Record Type field, followed by a
/// three-byte Record Length field.
///
/// The following subsections describe the currently defined Record types,
/// and how a device processes each. All multi-byte integers, including
/// the length field, are “Big Endian”; in other words, the most significant
/// byte comes first in the record.
/// </summary>
/// <see href="https://aacsla.com/wp-content/uploads/2019/02/AACS_Spec_Common_Final_0953.pdf"/>
public abstract class Record
{
/// <summary>
/// The Record Type field value indicates the type of the Record.
/// </summary>
public RecordType RecordType { get; set; }
/// <summary>
/// The Record Length field value indicates the number of bytes in
/// the Record, including the Record Type and the Record Length
/// fields themselves. Record lengths are always multiples of 4 bytes.
/// </summary>
// <remarks>UInt24 not UInt32</remarks>
public uint RecordLength { get; set; }
}
}

View File

@@ -0,0 +1,23 @@
using System.Runtime.InteropServices;
namespace SabreTools.Serialization.Models.AACS
{
/// <see href="https://aacsla.com/wp-content/uploads/2019/02/AACS_Spec_Common_Final_0953.pdf"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class SubsetDifference
{
/// <summary>
/// The mask for u is given by the first byte. That byte is
/// treated as a number, the number of low-order 0-bits in
/// the mask. For example, the value 0x01 denotes a mask of
/// 0xFFFFFFFE; value 0x0A denotes a mask of 0xFFFFFC00.
/// </summary>
public byte Mask;
/// <summary>
/// The last 4 bytes are the uv number, most significant
/// byte first.
/// </summary>
public uint Number;
}
}

View File

@@ -0,0 +1,26 @@
namespace SabreTools.Serialization.Models.AACS
{
/// <summary>
/// This is a speed-up record which can be ignored by devices not wishing to
/// take advantage of it. It is a lookup table which allows devices to quickly
/// find their subset-difference in the Explicit Subset-Difference record,
/// without processing the entire record. This Subset-Difference Index record
/// is always present, and always precedes the Explicit Subset-Difference record
/// in the MKB, although it does not necessarily immediately precede it.
/// </summary>
/// <see href="https://aacsla.com/wp-content/uploads/2019/02/AACS_Spec_Common_Final_0953.pdf"/>
public sealed class SubsetDifferenceIndexRecord : Record
{
/// <summary>
/// The number of devices per index offset.
/// </summary>
public uint Span { get; set; }
/// <summary>
/// These offsets refer to the offset within the following Explicit
/// Subset-Difference record, with 0 being the start of the record.
/// </summary>
// <remarks>UInt24 not UInt32</remarks>
public uint[]? Offsets { get; set; }
}
}

View File

@@ -0,0 +1,32 @@
namespace SabreTools.Serialization.Models.AACS
{
/// <summary>
/// Devices, except for recording devices which are writing Media Key Block
/// Extensions, may ignore this record. Recording devices shall verify the
/// signature (see End of Media Key Block record) and use the Version Number
/// in this record to determine if a new Media Key BLock Extension is, in
/// fact, more recent than the Media Key Block Extension that is currently
/// on the media.
/// </summary>
/// <see href="https://aacsla.com/wp-content/uploads/2019/02/AACS_Spec_Common_Final_0953.pdf"/>
public sealed class TypeAndVersionRecord : Record
{
/// <summary>
/// For AACS applications, the MKBType field is one of three values.
/// It is not an error for a Type 3 Media Key Block to be used for
/// controlling access to AACS Content on pre- recorded media. In
/// this case, the device shall not use the KCD.
/// </summary>
public MediaKeyBlockType MediaKeyBlockType { get; set; }
/// <summary>
/// The Version Number is a 32-bit unsigned integer. Each time the
/// licensing agency changes the revocation, it increments the version
/// number and inserts the new value in subsequent Media Key Blocks.
/// Thus, larger values indicate more recent Media Key Blocks. The
/// Version Numbers begin at 1; 0 is a special value used for test
/// Media Key Blocks.
/// </summary>
public uint VersionNumber { get; set; }
}
}

View File

@@ -0,0 +1,24 @@
namespace SabreTools.Serialization.Models.AACS
{
/// <summary>
/// A properly formatted MKB shall have exactly one Verify Media Key Record
/// as its first record. The presence of the Verify Media Key Record in an MKB
/// is mandatory, but the use of the Record by a device is not mandatory. The
/// device may use the Verify Media Key Record to verify the correctness of a
/// given MKB, or of its processing of it. If everything is correct, the device
/// should observe the condition:
/// [AES_128D(vKm, C]msb_64 == 0x0123456789ABCDEF)]
/// where Km is the Media Key value.
/// </summary>
/// <see href="https://aacsla.com/wp-content/uploads/2019/02/AACS_Spec_Common_Final_0953.pdf"/>
public sealed class VerifyMediaKeyRecord : Record
{
/// <summary>
/// Bytes 4 through 19 of the Record contain the ciphertext value
/// Cv = AES-128E (Km, 0x0123456789ABCDEF || 0xXXXXXXXXXXXXXXXX)
/// where 0xXXXXXXXXXXXXXXXX is an arbitrary 8-byte value, and Km is
/// the correct final Media Key value.
/// </summary>
public byte[]? CiphertextValue { get; set; }
}
}

View File

@@ -5,7 +5,7 @@ namespace SabreTools.Serialization.Models.AttractMode
/// </summary>
public class MetadataFile
{
[SabreTools.Models.Required]
[Required]
public string[]? Header { get; set; }
public Row[]? Row { get; set; }

View File

@@ -3,7 +3,7 @@ namespace SabreTools.Serialization.Models.AttractMode
public class Row
{
/// <remarks>Also called Romname</remarks>
[SabreTools.Models.Required]
[Required]
public string? Name { get; set; }
public string? Title { get; set; }

View File

@@ -0,0 +1,9 @@
namespace SabreTools.Serialization.Models.BDPlus
{
public static class Constants
{
public static readonly byte[] SignatureBytes = [0x42, 0x44, 0x53, 0x56, 0x4D, 0x5F, 0x43, 0x43];
public const string SignatureString = "BDSVM_CC";
}
}

View File

@@ -0,0 +1,50 @@
using System.Runtime.InteropServices;
namespace SabreTools.Serialization.Models.BDPlus
{
/// <see href="https://github.com/mwgoldsmith/bdplus/blob/master/src/libbdplus/bdsvm/loader.c"/>
public sealed class SVM
{
/// <summary>
/// "BDSVM_CC"
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string? Signature;
/// <summary>
/// Unknown data
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[]? Unknown1 = new byte[5];
/// <summary>
/// Version year
/// </summary>
public ushort Year;
/// <summary>
/// Version month
/// </summary>
public byte Month;
/// <summary>
/// Version day
/// </summary>
public byte Day;
/// <summary>
/// Unknown data
/// </summary>
public uint Unknown2;
/// <summary>
/// Length
/// </summary>
public uint Length;
/// <summary>
/// Length bytes of data
/// </summary>
public byte[]? Data { get; set; }
}
}

View File

@@ -0,0 +1,621 @@
using System;
namespace SabreTools.Serialization.Models.Charts
{
/// <see href="https://github.com/TheNathannator/GuitarGame_ChartFormats/tree/main/doc/FileFormats/song.ini"/>
/// <remarks>[song]/[Song]</remarks>
public class SongIni
{
#region Song/Chart Metadata
/// <summary>
/// Title of the song.
/// </summary>
/// <remarks>name</remarks>
public string? Name { get; set; }
/// <summary>
/// Artist(s) or band(s) behind the song.
/// </summary>
/// <remarks>artist</remarks>
public string? Artist { get; set; }
/// <summary>
/// Title of the album the song is featured in.
/// </summary>
/// <remarks>album</remarks>
public string? Album { get; set; }
/// <summary>
/// Genre of the song.
/// </summary>
/// <remarks>genre</remarks>
public string? Genre { get; set; }
/// <summary>
/// Sub-genre for the song.
/// </summary>
/// <remarks>sub_genre</remarks>
public string? SubGenre { get; set; }
/// <summary>
/// Year of the songs release.
/// </summary>
/// <remarks>year</remarks>
public string? Year { get; set; }
/// <summary>
/// Community member responsible for charting the song.
/// </summary>
/// <remarks>charter, frets</remarks>
public string? Charter { get; set; }
/// <summary>
/// Version number for the song.
/// </summary>
/// <remarks>version</remarks>
public long? Version { get; set; }
/// <summary>
/// Track number of the song within the album it's from.
/// </summary>
/// <remarks>album_track, track</remarks>
public long? AlbumTrack { get; set; }
/// <summary>
/// Track number of the song within the playlist/setlist it's from.
/// </summary>
/// <remarks>playlist_track</remarks>
public long? PlaylistTrack { get; set; }
/// <summary>
/// Length of the song's audio in milliseconds.
/// </summary>
/// <remarks>song_length</remarks>
public long? SongLength { get; set; }
/// <summary>
/// Timestamp in milliseconds where the song preview starts.
/// </summary>
/// <remarks>preview_start_time</remarks>
public long? PreviewStartTime { get; set; }
/// <summary>
/// Timestamp in milliseconds that the preview should stop at.
/// </summary>
/// <remarks>preview_end_time</remarks>
public long? PreviewEndTime { get; set; }
/// <summary>
/// Flavor text for this song, usually shown after picking the song or during loading.
/// </summary>
/// <remarks>loading_phrase</remarks>
public string? LoadingPhrase { get; set; }
#endregion
#region Song/Chart Metadata (Game-Specific)
/// <summary>
/// (FoFiX) Hex color to use in the song screen for the cassette.
/// </summary>
/// <remarks>cassettecolor</remarks>
public string? CassetteColor { get; set; }
/// <summary>
/// (FoFiX) Miscellaneous tags for the chart.
/// Only known valid value is `cover`.
/// </summary>
/// <remarks>tags</remarks>
public string? Tags { get; set; }
/// <summary>
/// (PS) Two timestamps in milliseconds for preview start and end time.
/// Example: `55000 85000`
/// </summary>
/// <remarks>preview</remarks>
public long[]? Preview { get; set; }
/// <summary>
/// (CH) Playlist that the song should show up in.
/// </summary>
/// <remarks>playlist</remarks>
public string? Playlist { get; set; }
/// <summary>
/// (CH) Sub-playlist that the song should show up in.
/// </summary>
/// <remarks>sub_playlist</remarks>
public string? SubPlaylist { get; set; }
/// <summary>
/// (CH) Indicates if this song is a modchart.
/// Meant for sorting purposes only.
/// </summary>
/// <remarks>modchart</remarks>
public bool? Modchart { get; set; }
/// <summary>
/// (CH) Indicates if the song has lyrics or not.
/// Meant for sorting purposes only.
/// </summary>
/// <remarks>lyrics</remarks>
public bool? Lyrics { get; set; }
#endregion
#region Track Difficulties
/// <summary>
/// Overall difficulty of the song.
/// </summary>
/// <remarks>diff_band</remarks>
public long? DiffBand { get; set; }
/// <summary>
/// Difficulty of the Lead Guitar track.
/// </summary>
/// <remarks>diff_guitar</remarks>
public long? DiffGuitar { get; set; }
/// <summary>
/// Difficulty of the 6-Fret Lead track.
/// </summary>
/// <remarks>diff_guitarghl</remarks>
public long? DiffGuitarGHL { get; set; }
/// <summary>
/// Difficulty of the Guitar Co-op track.
/// </summary>
/// <remarks>diff_guitar_coop</remarks>
public long? DiffGuitarCoop { get; set; }
/// <summary>
/// Difficulty of the 6-Fret Guitar Co-op track.
/// </summary>
/// <remarks>diff_guitar_coop_ghl</remarks>
public long? DiffGuitarCoopGHL { get; set; }
/// <summary>
/// Difficulty of the Pro Guitar track.
/// </summary>
/// <remarks>diff_guitar_real</remarks>
public long? DiffGuitarReal { get; set; }
/// <summary>
/// Difficulty of the Pro Guitar 22-fret track.
/// </summary>
/// <remarks>diff_guitar_real_22</remarks>
public long? DiffGuitarReal22 { get; set; }
/// <summary>
/// Difficulty of the Rhythm Guitar track.
/// </summary>
/// <remarks>diff_rhythm</remarks>
public long? DiffRhythm { get; set; }
/// <summary>
/// Difficulty of the 6-Fret Rhythm Guitar track.
/// </summary>
/// <remarks>diff_rhythm_ghl</remarks>
public long? DiffRhythmGHL { get; set; }
/// <summary>
/// Difficulty of the Bass Guitar track.
/// </summary>
/// <remarks>diff_bass</remarks>
public long? DiffBass { get; set; }
/// <summary>
/// Difficulty of the 6-Fret Bass track.
/// </summary>
/// <remarks>diff_bassghl</remarks>
public long? DiffBassGHL { get; set; }
/// <summary>
/// Difficulty of the Pro Bass track.
/// </summary>
/// <remarks>diff_bass_real</remarks>
public long? DiffBassReal { get; set; }
/// <summary>
/// Difficulty of the Pro Bass 22-fret track.
/// </summary>
/// <remarks>diff_bass_real_22</remarks>
public long? DiffBassReal22 { get; set; }
/// <summary>
/// Difficulty of the Drums track.
/// </summary>
/// <remarks>diff_drums</remarks>
public long? DiffDrums { get; set; }
/// <summary>
/// Difficulty of the Pro Drums track.
/// </summary>
/// <remarks>diff_drums_real</remarks>
public long? DiffDrumsReal { get; set; }
/// <summary>
/// Difficulty of the Drums Real track.
/// </summary>
/// <remarks>diff_drums_real_ps</remarks>
public long? DiffDrumsRealPS { get; set; }
/// <summary>
/// Difficulty of the Keys track.
/// </summary>
/// <remarks>diff_keys</remarks>
public long? DiffKeys { get; set; }
/// <summary>
/// Difficulty of the Pro Keys track.
/// </summary>
/// <remarks>diff_keys_real</remarks>
public long? DiffKeysReal { get; set; }
/// <summary>
/// Difficulty of the Keys Real track.
/// </summary>
/// <remarks>diff_keys_real_ps</remarks>
public long? DiffKeysRealPS { get; set; }
/// <summary>
/// Difficulty of the Vocals track.
/// </summary>
/// <remarks>diff_vocals</remarks>
public long? DiffVocals { get; set; }
/// <summary>
/// Difficulty of the Harmonies track.
/// </summary>
/// <remarks>diff_vocals_harm</remarks>
public long? DiffVocalsHarm { get; set; }
/// <summary>
/// Difficulty of the Dance track.
/// </summary>
/// <remarks>diff_dance</remarks>
public long? DiffDance { get; set; }
#endregion
#region Chart Properties
/// <summary>
/// Forces the Drums track to be Pro Drums.
/// </summary>
/// <remarks>pro_drums, pro_drum (FoFiX)</remarks>
public bool? ProDrums { get; set; }
/// <summary>
/// Forces the Drums track to be 5-lane.
/// </summary>
/// <remarks>five_lane_drums</remarks>
public bool? FiveLaneDrums { get; set; }
/// <summary>
/// Specifies a voice type for the singer (either "male" or "female").
/// </summary>
/// <remarks>vocal_gender</remarks>
public string? VocalGender { get; set; }
/// <summary>
/// Specifies a tuning for 17-fret Pro Guitar.
/// </summary>
/// <remarks>real_guitar_tuning</remarks>
public string? RealGuitarTuning { get; set; }
/// <summary>
/// Specifies a tuning for 22-fret Pro Guitar.
/// </summary>
/// <remarks>real_guitar_22_tuning</remarks>
public string? RealGuitar22Tuning { get; set; }
/// <summary>
/// Specifies a tuning for 17-fret Pro Bass.
/// </summary>
/// <remarks>real_bass_tuning</remarks>
public string? RealBassTuning { get; set; }
/// <summary>
/// Specifies a tuning for 22-fret Pro Bass.
/// </summary>
/// <remarks>real_bass_22_tuning</remarks>
public string? RealBass22Tuning { get; set; }
/// <summary>
/// Specifies the number of lanes for the right hand in Real Keys.
/// </summary>
/// <remarks>real_keys_lane_count_right</remarks>
public long? RealKeysLaneCountRight { get; set; }
/// <summary>
/// Specifies the number of lanes for the left hand in Real Keys.
/// </summary>
/// <remarks>real_keys_lane_count_left</remarks>
public long? RealKeysLaneCountLeft { get; set; }
/// <summary>
/// Delays the chart relative to the audio by the specified number of milliseconds.
/// Higher = later notes. Can be negative.
/// </summary>
/// <remarks>delay</remarks>
[Obsolete]
public long? Delay { get; set; }
/// <summary>
/// Overrides the default sustain cutoff threshold with a specified value in ticks.
/// </summary>
/// <remarks>sustain_cutoff_threshold</remarks>
[Obsolete]
public long? SustainCutoffThreshold { get; set; }
/// <summary>
/// Overrides the default HOPO threshold with a specified value in ticks.
/// </summary>
/// <remarks>hopo_frequency</remarks>
[Obsolete]
public long? HopoFrequency { get; set; }
/// <summary>
/// Sets the HOPO threshold to be a 1/8th step.
/// </summary>
/// <remarks>eighthnote_hopo</remarks>
[Obsolete]
public bool? EighthNoteHopo { get; set; }
/// <summary>
/// Overrides the .mid note number for Star Power on 5-Fret Guitar.
/// Valid values are 103 and 116.
/// </summary>
/// <remarks>multiplier_note, star_power_note (PS)</remarks>
[Obsolete]
public long? MultiplierNote { get; set; }
#endregion
#region Chart Properties (Game-Specific)
/// <summary>
/// (PS) Sets 5 to 4 Lane Drums Fallback Note
/// </summary>
/// <remarks>drum_fallback_blue</remarks>
public bool? DrumFallbackBlue { get; set; }
/// <summary>
/// (FoFiX) Marks a song as a tutorial and hides it from Quickplay.
/// </summary>
/// <remarks>tutorial</remarks>
public bool? Tutorial { get; set; }
/// <summary>
/// (FoFiX) Marks a song as a boss battle.
/// </summary>
/// <remarks>boss_battle</remarks>
public bool? BossBattle { get; set; }
/// <summary>
/// (FoFiX) Overrides the natural HOPO threshold using numbers from 0 to 5.
/// </summary>
/// <remarks>hopofreq</remarks>
[Obsolete]
public long? HopoFreq { get; set; }
/// <summary>
/// (FoFiX) Sets the "early hit window" size.
/// Valid values are "none", "half", or "full".
/// </summary>
/// <remarks>early_hit_window_size</remarks>
public string? EarlyHitWindowSize { get; set; }
/// <summary>
/// (CH) Sets whether or not end events in the chart will be respected.
/// </summary>
/// <remarks>end_events</remarks>
public bool? EndEvents { get; set; }
/// <summary>
/// (PS) Enables .mid SysEx events for guitar sliders/tap notes.
/// </summary>
/// <remarks>sysex_slider</remarks>
public bool? SysExSlider { get; set; }
/// <summary>
/// (PS) Enables .mid SysEx events for Real Drums hi-hat pedal control.
/// </summary>
/// <remarks>sysex_high_hat_ctrl</remarks>
public bool? SysExHighHatCtrl { get; set; }
/// <summary>
/// (PS) Enables .mid SysEx events for Real Drums rimshot hits.
/// </summary>
/// <remarks>sysex_rimshot</remarks>
public bool? SysExRimshot { get; set; }
/// <summary>
/// (PS) Enables .mid SysEx events for guitar open notes.
/// </summary>
/// <remarks>sysex_open_bass</remarks>
public bool? SysExOpenBass { get; set; }
/// <summary>
/// (PS) Enables .mid SysEx events for Pro Guitar/Bass slide directions.
/// </summary>
/// <remarks>sysex_pro_slide</remarks>
public bool? SysExProSlide { get; set; }
/// <summary>
/// (PS) Sound sample set index for guitar.
/// </summary>
/// <remarks>guitar_type</remarks>
public long? GuitarType { get; set; }
/// <summary>
/// (PS) Sound sample set index for bass.
/// </summary>
/// <remarks>bass_type</remarks>
public long? BassType { get; set; }
/// <summary>
/// (PS) Sound sample set index for drums.
/// </summary>
/// <remarks>kit_type</remarks>
public long? KitType { get; set; }
/// <summary>
/// (PS) Sound sample set index for keys.
/// </summary>
/// <remarks>keys_type</remarks>
public long? KeysType { get; set; }
/// <summary>
/// (PS) Sound sample set index for dance.
/// </summary>
/// <remarks>dance_type</remarks>
public long? DanceType { get; set; }
#endregion
#region Images and Other Resources
/// <summary>
/// Name of an icon image to display for this song.
/// Included in either the chart folder or the game the chart was made for, or sourced from this repository of icons.
/// </summary>
/// <remarks>icon</remarks>
public string? Icon { get; set; }
/// <summary>
/// Name for a background image file.
/// </summary>
/// <remarks>background</remarks>
public string? Background { get; set; }
/// <summary>
/// Name for a background video file.
/// </summary>
/// <remarks>video</remarks>
public string? Video { get; set; }
/// <summary>
/// Name for a background video file.
/// </summary>
/// <remarks>video_loop</remarks>
public bool? VideoLoop { get; set; }
/// <summary>
/// Timestamp in milliseconds where playback of an included video will start. Can be negative.
/// This tag controls the time relative to the video, not relative to the chart. Negative values will delay the video, positive values will make the video be at a further point in when the chart starts.
/// </summary>
/// <remarks>video_start_time</remarks>
public long? VideoStartTime { get; set; }
/// <summary>
/// Timestamp in milliseconds where playback of an included video will end. -1 means no time is specified.
/// This is assumed to also be relative to the video, not the chart.
/// </summary>
/// <remarks>video_end_time</remarks>
public long? VideoEndTime { get; set; }
/// <summary>
/// Name for a cover image file.
/// </summary>
/// <remarks>cover</remarks>
public string? Cover { get; set; }
#endregion
#region Images and Other Resources (Game-Specific)
/// <summary>
/// (PS) Name for banner A.
/// </summary>
/// <remarks>link_name_a</remarks>
public string? LinkNameA { get; set; }
/// <summary>
/// (PS) Name for banner B.
/// </summary>
/// <remarks>link_name_b</remarks>
public string? LinkNameB { get; set; }
/// <summary>
/// (PS) Link that clicking banner A will open.
/// </summary>
/// <remarks>banner_link_a</remarks>
public string? BannerLinkA { get; set; }
/// <summary>
/// (PS) Link that clicking banner B will open.
/// </summary>
/// <remarks>banner_link_b</remarks>
public string? BannerLinkB { get; set; }
#endregion
#region Miscellaneous (Game-Specific)
/// <summary>
/// (FoFiX) High score data.
/// </summary>
/// <remarks>scores</remarks>
public string? Scores { get; set; }
/// <summary>
/// (FoFiX) Additional score data.
/// </summary>
/// <remarks>scores_ext</remarks>
public string? ScoresExt { get; set; }
/// <summary>
/// (FoFiX) Play count.
/// </summary>
/// <remarks>count</remarks>
public long? Count { get; set; }
/// <summary>
/// (PS) Player's rating of the song
/// </summary>
/// <remarks>rating</remarks>
public long? Rating { get; set; }
/// <summary>
/// (FoFiX) Career ID for this song.
/// </summary>
/// <remarks>unlock_id</remarks>
public string? UnlockId { get; set; }
/// <summary>
/// (FoFiX) The career ID that must be completed to unlock this song.
/// </summary>
/// <remarks>unlock_require</remarks>
public string? UnlockRequire { get; set; }
/// <summary>
/// (FoFiX) Text to display if the song is locked.
/// </summary>
/// <remarks>unlock_text</remarks>
public string? UnlockText { get; set; }
/// <summary>
/// (FoFiX) Indicates if the song is unlocked.
/// </summary>
/// <remarks>unlock_completed</remarks>
public long? UnlockCompleted { get; set; }
/// <summary>
/// (Editor on Fire) Sets a velocity number for drums accent notes.
/// </summary>
/// <remarks>eof_midi_import_drum_accent_velocity</remarks>
public long? EoFMidiImportDrumAccentVelocity { get; set; }
/// <summary>
/// (Editor on Fire) Sets a velocity number for drums ghost notes.
/// </summary>
/// <remarks>eof_midi_import_drum_ghost_velocity</remarks>
public long? EoFMidiImportDrumGhostVelocity { get; set; }
#endregion
}
}

View File

@@ -0,0 +1,16 @@
namespace SabreTools.Serialization.Models.Charts
{
/// <see href="https://github.com/TheNathannator/GuitarGame_ChartFormats/blob/main/doc/FileFormats/Other/Frets%20on%20Fire%20X/Careers.md"/>
public class Tier
{
/// <summary>
/// Display name of the tier.
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Name used for associating a song with this tier, and for checking unlock requirements.
/// </summary>
public string? UnlockId { get; set; }
}
}

View File

@@ -0,0 +1,18 @@
namespace SabreTools.Serialization.Models.Charts
{
/// <see href="https://github.com/TheNathannator/GuitarGame_ChartFormats/blob/main/doc/FileFormats/Other/Frets%20on%20Fire%20X/Careers.md"/>
/// <remarks>[titles]</remarks>
public class TitlesIni
{
/// <summary>
/// A space-separated list of .ini sections to include in the career.
/// </summary>
/// <remarks>sections</remarks>
public string[]? SectionList { get; set; }
/// <summary>
/// This entry points to other sections that should be used as part of the career.
/// </summary>
public Tier[]? Sections { get; set; }
}
}

View File

@@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro
public class Archive
{
/// <remarks>name</remarks>
[SabreTools.Models.Required]
[Required]
public string? Name { get; set; }
}
}

View File

@@ -4,11 +4,11 @@ namespace SabreTools.Serialization.Models.ClrMamePro
public class BiosSet
{
/// <remarks>name</remarks>
[SabreTools.Models.Required]
[Required]
public string? Name { get; set; }
/// <remarks>description</remarks>
[SabreTools.Models.Required]
[Required]
public string? Description { get; set; }
/// <remarks>default</remarks>

View File

@@ -4,11 +4,11 @@ namespace SabreTools.Serialization.Models.ClrMamePro
public class Chip
{
/// <remarks>type, (cpu|audio)</remarks>
[SabreTools.Models.Required]
[Required]
public string? Type { get; set; }
/// <remarks>name</remarks>
[SabreTools.Models.Required]
[Required]
public string? Name { get; set; }
/// <remarks>flags</remarks>

View File

@@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro
public class DipSwitch
{
/// <remarks>name</remarks>
[SabreTools.Models.Required]
[Required]
public string? Name { get; set; }
/// <remarks>entry</remarks>

View File

@@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro
public class Disk
{
/// <remarks>name</remarks>
[SabreTools.Models.Required]
[Required]
public string? Name { get; set; }
/// <remarks>md5</remarks>

View File

@@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro
public class Driver
{
/// <remarks>status, (good|imperfect|preliminary)</remarks>
[SabreTools.Models.Required]
[Required]
public string? Status { get; set; }
/// <remarks>color, (good|imperfect|preliminary)</remarks>

View File

@@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro
public abstract class GameBase
{
/// <remarks>name</remarks>
[SabreTools.Models.Required]
[Required]
public string? Name { get; set; }
/// <remarks>description</remarks>

View File

@@ -4,14 +4,14 @@ namespace SabreTools.Serialization.Models.ClrMamePro
public class Input
{
/// <remarks>players, Numeric/remarks>
[SabreTools.Models.Required]
[Required]
public string? Players { get; set; }
/// <remarks>control</remarks>
public string? Control { get; set; }
/// <remarks>buttons, Numeric</remarks>
[SabreTools.Models.Required]
[Required]
public string? Buttons { get; set; }
/// <remarks>coins, Numeric</remarks>

View File

@@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro
public class Media
{
/// <remarks>name</remarks>
[SabreTools.Models.Required]
[Required]
public string? Name { get; set; }
/// <remarks>md5</remarks>

View File

@@ -4,11 +4,11 @@ namespace SabreTools.Serialization.Models.ClrMamePro
public class Release
{
/// <remarks>name</remarks>
[SabreTools.Models.Required]
[Required]
public string? Name { get; set; }
/// <remarks>region</remarks>
[SabreTools.Models.Required]
[Required]
public string? Region { get; set; }
/// <remarks>language</remarks>

View File

@@ -4,11 +4,11 @@ namespace SabreTools.Serialization.Models.ClrMamePro
public class Rom
{
/// <remarks>name</remarks>
[SabreTools.Models.Required]
[Required]
public string? Name { get; set; }
/// <remarks>size, Numeric</remarks>
[SabreTools.Models.Required]
[Required]
public string? Size { get; set; }
/// <remarks>crc</remarks>

View File

@@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro
public class Sample
{
/// <remarks>name</remarks>
[SabreTools.Models.Required]
[Required]
public string? Name { get; set; }
}
}

View File

@@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro
public class Sound
{
/// <remarks>channels, Numeric?</remarks>
[SabreTools.Models.Required]
[Required]
public string? Channels { get; set; }
}
}

View File

@@ -4,11 +4,11 @@ namespace SabreTools.Serialization.Models.ClrMamePro
public class Video
{
/// <remarks>screen, (raster|vector)</remarks>
[SabreTools.Models.Required]
[Required]
public string? Screen { get; set; }
/// <remarks>orientation, (vertical|horizontal)</remarks>
[SabreTools.Models.Required]
[Required]
public string? Orientation { get; set; }
/// <remarks>x, Numeric?</remarks>

View File

@@ -0,0 +1,26 @@
/// <remarks>
/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf
/// </remarks>
namespace SabreTools.Serialization.Models.CueSheets
{
/// <summary>
/// Represents a single FILE in a cuesheet
/// </summary>
public class CueFile
{
/// <summary>
/// filename
/// </summary>
public string? FileName { get; set; }
/// <summary>
/// filetype
/// </summary>
public CueFileType FileType { get; set; }
/// <summary>
/// List of TRACK in FILE
/// </summary>
public CueTrack[]? Tracks { get; set; }
}
}

View File

@@ -0,0 +1,33 @@
/// <remarks>
/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf
/// </remarks>
namespace SabreTools.Serialization.Models.CueSheets
{
/// <summary>
/// Represents a single INDEX in a TRACK
/// </summary>
public class CueIndex
{
/// <summary>
/// INDEX number, between 0 and 99
/// </summary>
public int Index { get; set; }
/// <summary>
/// Starting time of INDEX in minutes
/// </summary>
public int Minutes { get; set; }
/// <summary>
/// Starting time of INDEX in seconds
/// </summary>
/// <remarks>There are 60 seconds in a minute</remarks>
public int Seconds { get; set; }
/// <summary>
/// Starting time of INDEX in frames.
/// </summary>
/// <remarks>There are 75 frames per second</remarks>
public int Frames { get; set; }
}
}

View File

@@ -0,0 +1,41 @@
/// <remarks>
/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf
/// </remarks>
namespace SabreTools.Serialization.Models.CueSheets
{
/// <summary>
/// Represents a single cuesheet
/// </summary>
public class CueSheet
{
/// <summary>
/// CATALOG
/// </summary>
public string? Catalog { get; set; }
/// <summary>
/// CDTEXTFILE
/// </summary>
public string? CdTextFile { get; set; }
/// <summary>
/// PERFORMER
/// </summary>
public string? Performer { get; set; }
/// <summary>
/// SONGWRITER
/// </summary>
public string? Songwriter { get; set; }
/// <summary>
/// TITLE
/// </summary>
public string? Title { get; set; }
/// <summary>
/// List of FILE in cuesheet
/// </summary>
public CueFile[]? Files { get; set; }
}
}

View File

@@ -0,0 +1,63 @@
/// <remarks>
/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf
/// </remarks>
namespace SabreTools.Serialization.Models.CueSheets
{
/// <summary>
/// Represents a single TRACK in a FILE
/// </summary>
public class CueTrack
{
/// <summary>
/// Track number. The range is 1 to 99.
/// </summary>
public int Number { get; set; }
/// <summary>
/// Track datatype
/// </summary>
public CueTrackDataType DataType { get; set; }
/// <summary>
/// FLAGS
/// </summary>
public CueTrackFlag Flags { get; set; }
/// <summary>
/// ISRC
/// </summary>
/// <remarks>12 characters in length</remarks>
public string? ISRC { get; set; }
/// <summary>
/// PERFORMER
/// </summary>
public string? Performer { get; set; }
/// <summary>
/// SONGWRITER
/// </summary>
public string? Songwriter { get; set; }
/// <summary>
/// TITLE
/// </summary>
public string? Title { get; set; }
/// <summary>
/// PREGAP
/// </summary>
public PreGap? PreGap { get; set; }
/// <summary>
/// List of INDEX in TRACK
/// </summary>
/// <remarks>Must start with 0 or 1 and then sequential</remarks>
public CueIndex[]? Indices { get; set; }
/// <summary>
/// POSTGAP
/// </summary>
public PostGap? PostGap { get; set; }
}
}

View File

@@ -0,0 +1,116 @@
using System;
/// <remarks>
/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf
/// </remarks>
namespace SabreTools.Serialization.Models.CueSheets
{
/// <summary>
/// The audio or data files filetype
/// </summary>
public enum CueFileType
{
/// <summary>
/// Intel binary file (least significant byte first). Use for data files.
/// </summary>
BINARY,
/// <summary>
/// Motorola binary file (most significant byte first). Use for data files.
/// </summary>
MOTOROLA,
/// <summary>
/// Audio AIFF file (44.1KHz 16-bit stereo)
/// </summary>
AIFF,
/// <summary>
/// Audio WAVE file (44.1KHz 16-bit stereo)
/// </summary>
WAVE,
/// <summary>
/// Audio MP3 file (44.1KHz 16-bit stereo)
/// </summary>
MP3,
}
/// <summary>
/// Track datatype
/// </summary>
public enum CueTrackDataType
{
/// <summary>
/// AUDIO, Audio/Music (2352)
/// </summary>
AUDIO,
/// <summary>
/// CDG, Karaoke CD+G (2448)
/// </summary>
CDG,
/// <summary>
/// MODE1/2048, CD-ROM Mode1 Data (cooked)
/// </summary>
MODE1_2048,
/// <summary>
/// MODE1/2352 CD-ROM Mode1 Data (raw)
/// </summary>
MODE1_2352,
/// <summary>
/// MODE2/2336, CD-ROM XA Mode2 Data
/// </summary>
MODE2_2336,
/// <summary>
/// MODE2/2352, CD-ROM XA Mode2 Data
/// </summary>
MODE2_2352,
/// <summary>
/// CDI/2336, CD-I Mode2 Data
/// </summary>
CDI_2336,
/// <summary>
/// CDI/2352, CD-I Mode2 Data
/// </summary>
CDI_2352,
}
/// <summary>
/// Special subcode flags within a track
/// </summary>
[Flags]
public enum CueTrackFlag
{
/// <summary>
/// DCP, Digital copy permitted
/// </summary>
DCP = 1 << 0,
/// <summary>
/// 4CH, Four channel audio
/// </summary>
FourCH = 1 << 1,
/// <summary>
/// PRE, Pre-emphasis enabled (audio tracks only)
/// </summary>
PRE = 1 << 2,
/// <summary>
/// SCMS, Serial Copy Management System (not supported by all recorders)
/// </summary>
SCMS = 1 << 3,
/// <summary>
/// DATA, set for data files. This flag is set automatically based on the tracks filetype
/// </summary>
DATA = 1 << 4,
}
}

View File

@@ -0,0 +1,28 @@
/// <remarks>
/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf
/// </remarks>
namespace SabreTools.Serialization.Models.CueSheets
{
/// <summary>
/// Represents POSTGAP information of a track
/// </summary>
public class PostGap
{
/// <summary>
/// Length of POSTGAP in minutes
/// </summary>
public int Minutes { get; set; }
/// <summary>
/// Length of POSTGAP in seconds
/// </summary>
/// <remarks>There are 60 seconds in a minute</remarks>
public int Seconds { get; set; }
/// <summary>
/// Length of POSTGAP in frames.
/// </summary>
/// <remarks>There are 75 frames per second</remarks>
public int Frames { get; set; }
}
}

View File

@@ -0,0 +1,28 @@
/// <remarks>
/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf
/// </remarks>
namespace SabreTools.Serialization.Models.CueSheets
{
/// <summary>
/// Represents PREGAP information of a track
/// </summary>
public class PreGap
{
/// <summary>
/// Length of PREGAP in minutes
/// </summary>
public int Minutes { get; set; }
/// <summary>
/// Length of PREGAP in seconds
/// </summary>
/// <remarks>There are 60 seconds in a minute</remarks>
public int Seconds { get; set; }
/// <summary>
/// Length of PREGAP in frames.
/// </summary>
/// <remarks>There are 75 frames per second</remarks>
public int Frames { get; set; }
}
}

View File

@@ -0,0 +1,32 @@
namespace SabreTools.Serialization.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo_vmg.html"/>
public sealed class AudioSubPictureAttributesTable
{
/// <summary>
/// Number of title sets
/// </summary>
public ushort NumberOfTitleSets { get; set; }
/// <summary>
/// Reserved
/// </summary>
public ushort Reserved { get; set; }
/// <summary>
/// End address (last byte of last VTS_ATRT)
/// </summary>
public uint EndAddress { get; set; }
/// <summary>
/// Offset to VTS_ATRT n
/// </summary>
/// <remarks>NumberOfTitleSets entries</remarks>
public uint[]? Offsets { get; set; }
/// <summary>
/// Entries
/// </summary>
public AudioSubPictureAttributesTableEntry[]? Entries { get; set; }
}
}

View File

@@ -0,0 +1,23 @@
namespace SabreTools.Serialization.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo_vmg.html"/>
public sealed class AudioSubPictureAttributesTableEntry
{
/// <summary>
/// End address (EA)
/// </summary>
public uint EndAddress { get; set; }
/// <summary>
/// VTS_CAT (copy of offset 022-025 of the VTS IFO file)
/// 0=unspecified, 1=Karaoke
/// </summary>
public uint Category { get; set; }
/// <summary>
/// Copy of VTS attributes (offset 100 and on from the VTS IFO
/// file, usually 0x300 bytes long)
/// </summary>
public byte[]? AttributesCopy { get; set; }
}
}

View File

@@ -0,0 +1,27 @@
namespace SabreTools.Serialization.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo.html"/>
public sealed class CellAddressTable
{
/// <summary>
/// Number of VOB IDs
/// </summary>
public ushort NumberOfVOBIDs { get; set; }
/// <summary>
/// Reserved
/// </summary>
public ushort Reserved { get; set; }
/// <summary>
/// End address (last byte of last entry)
/// </summary>
public uint EndAddress { get; set; }
/// <summary>
/// 12-byte entries
/// </summary>
/// <remarks>NumberOfVOBIDs entries</remarks>
public CellAddressTableEntry[]? Entries { get; set; }
}
}

View File

@@ -0,0 +1,34 @@
using System.Runtime.InteropServices;
namespace SabreTools.Serialization.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo.html"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class CellAddressTableEntry
{
/// <summary>
/// VOBidn
/// </summary>
public ushort VOBIdentity;
/// <summary>
/// CELLidn
/// </summary>
public byte CellIdentity;
/// <summary>
/// Reserved
/// </summary>
public byte Reserved;
/// <summary>
/// Starting sector within VOB
/// </summary>
public uint StartingSectorWithinVOB;
/// <summary>
/// Ending sector within VOB
/// </summary>
public uint EndingSectorWithinVOB;
}
}

View File

@@ -0,0 +1,9 @@
namespace SabreTools.Serialization.Models.DVD
{
public static class Constants
{
public const string VideoManagerIFOSignature = "DVDVIDEO-VMG";
public const string VideoTitleSetIFOSignature = "DVDVIDEO-VTS";
}
}

View File

@@ -0,0 +1,56 @@
using System;
namespace SabreTools.Serialization.Models.DVD
{
[Flags]
public enum ProgramChainCategory : byte
{
MenuTypeTitle = 0x02,
Entry = 0x80,
}
[Flags]
public enum TitleType : byte
{
/// <summary>
/// Uop0 Time play or search
/// </summary>
Uop0TimePlayOrSearch = 0x01,
/// <summary>
/// Uop1 PTT play or search
/// </summary>
Uop1PTTPlayOrSearch = 0x02,
/// <summary>
/// Jump/Link/Call commands - exist
/// </summary>
JumpLinkCallExist = 0x04,
/// <summary>
/// Jump/Link/Call commands - button
/// </summary>
JumpLinkCallButton = 0x08,
/// <summary>
/// Jump/Link/Call commands - pre/post
/// </summary>
JumpLinkCallPrePost = 0x10,
/// <summary>
/// Jump/Link/Call commands - cell
/// </summary>
JumpLinkCallCell = 0x20,
/// <summary>
/// 0=one_sequential_pgc
/// 1=not one_sequential (random, shuffle, stills, loops, or more than one pgc)
/// </summary>
ComplexPGC = 0x40,
/// <summary>
/// Reserved
/// </summary>
Reserved = 0x80,
}
}

View File

@@ -0,0 +1,34 @@
namespace SabreTools.Serialization.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo_vmg.html"/>
public sealed class LanguageUnitTable
{
/// <summary>
/// Number of Language Units
/// </summary>
public ushort NumberOfLanguageUnits { get; set; }
/// <summary>
/// Reserved
/// </summary>
public ushort Reserved { get; set; }
/// <summary>
/// End address (last byte of last PGC in last LU)
/// relative to VMGM_PGCI_UT
/// </summary>
public uint EndAddress { get; set; }
/// <summary>
/// Language Units
/// </summary>
/// <remarks>NumberOfVOBIDs entries</remarks>
public LanguageUnitTableEntry[]? Entries { get; set; }
/// <summary>
/// Program Chains
/// </summary>
/// <remarks>NumberOfVOBIDs entries</remarks>
public ProgramChainTable[]? ProgramChains { get; set; }
}
}

View File

@@ -0,0 +1,29 @@
using System.Runtime.InteropServices;
namespace SabreTools.Serialization.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo_vmg.html"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class LanguageUnitTableEntry
{
/// <summary>
/// ISO639 language code
/// </summary>
public ushort ISO639LanguageCode;
/// <summary>
/// Reserved for language code extension
/// </summary>
public byte Reserved;
/// <summary>
/// Menu existence flag [80 = title]
/// </summary>
public byte MenuExistenceFlag;
/// <summary>
/// Offset to VMGM_LU, relative to VMGM_PGCI_UT
/// </summary>
public uint LanguageUnitOffset;
}
}

View File

@@ -0,0 +1,37 @@
namespace SabreTools.Serialization.Models.DVD
{
/// <summary>
/// The VMG_PTL_MAIT is searched by country, and points to
/// the table for each country.
/// </summary>
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo_vmg.html"/>
public sealed class ParentalManagementMasksTable
{
/// <summary>
/// Number of countries
/// </summary>
public ushort NumberOfCountries { get; set; }
/// <summary>
/// Number of title sets (NTs)
/// </summary>
public ushort NumberOfTitleSets { get; set; }
/// <summary>
/// End address (last byte of last PTL_MAIT)
/// </summary>
public uint EndAddress { get; set; }
/// <summary>
/// Entries
/// </summary>
public ParentalManagementMasksTableEntry[]? Entries { get; set; }
/// <summary>
/// The PTL_MAIT contains the 16-bit masks for the VMG and
/// all title sets for parental management level 8 followed
/// by the masks for level 7, and so on to level 1.
/// </summary>
public byte[][]? BitMasks { get; set; }
}
}

View File

@@ -0,0 +1,24 @@
using System.Runtime.InteropServices;
namespace SabreTools.Serialization.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo_vmg.html"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class ParentalManagementMasksTableEntry
{
/// <summary>
/// Country code
/// </summary>
public ushort CountryCode;
/// <summary>
/// Reserved
/// </summary>
public ushort Reserved;
/// <summary>
/// Offset to PTL_MAIT
/// </summary>
public uint Offset;
}
}

View File

@@ -0,0 +1,28 @@
namespace SabreTools.Serialization.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo_vmg.html"/>
public sealed class ProgramChainTable
{
/// <summary>
/// Number of Program Chains
/// </summary>
public ushort NumberOfProgramChains { get; set; }
/// <summary>
/// Reserved
/// </summary>
public ushort Reserved { get; set; }
/// <summary>
/// End address (last byte of last PGC in this LU)
/// relative to VMGM_LU
/// </summary>
public uint EndAddress { get; set; }
/// <summary>
/// Program Chains
/// </summary>
/// <remarks>NumberOfProgramChains entries</remarks>
public ProgramChainTableEntry[]? Entries { get; set; }
}
}

View File

@@ -0,0 +1,30 @@
using System.Runtime.InteropServices;
namespace SabreTools.Serialization.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo_vmg.html"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class ProgramChainTableEntry
{
/// <summary>
/// PGC category
/// </summary>
[MarshalAs(UnmanagedType.U1)]
public ProgramChainCategory Category;
/// <summary>
/// Unknown
/// </summary>
public byte Unknown;
/// <summary>
/// Parental management mask
/// </summary>
public ushort ParentalManagementMask;
/// <summary>
/// Offset to VMGM_PGC, relative to VMGM_LU
/// </summary>
public uint Offset;
}
}

View File

@@ -0,0 +1,27 @@
namespace SabreTools.Serialization.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo_vmg.html"/>
public sealed class TitlesTable
{
/// <summary>
/// Number of titles
/// </summary>
public ushort NumberOfTitles { get; set; }
/// <summary>
/// Reserved
/// </summary>
public ushort Reserved { get; set; }
/// <summary>
/// End address (last byte of last entry)
/// </summary>
public uint EndAddress { get; set; }
/// <summary>
/// 12-byte entries
/// </summary>
/// <remarks>NumberOfTitles entries</remarks>
public TitlesTableEntry[]? Entries { get; set; }
}
}

View File

@@ -0,0 +1,46 @@
using System.Runtime.InteropServices;
namespace SabreTools.Serialization.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo_vmg.html"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class TitlesTableEntry
{
/// <summary>
/// Title type
/// </summary>
[MarshalAs(UnmanagedType.U1)]
public TitleType TitleType;
/// <summary>
/// Number of angles
/// </summary>
public byte NumberOfAngles;
/// <summary>
/// Number of chapters (PTTs)
/// </summary>
public ushort NumberOfChapters;
/// <summary>
/// Parental management mask
/// </summary>
public ushort ParentalManagementMask;
/// <summary>
/// Video Title Set number (VTSN)
/// </summary>
public byte VideoTitleSetNumber;
/// <summary>
/// Title number within VTS (VTS_TTN)
/// </summary>
public byte TitleNumberWithinVTS;
/// <summary>
/// Start sector for VTS, referenced to whole disk
/// (video_ts.ifo starts at sector 00000000)
/// </summary>
public uint VTSStartSector;
}
}

View File

@@ -0,0 +1,16 @@
namespace SabreTools.Serialization.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo.html"/>
public sealed class VOBUAddressMap
{
/// <summary>
/// End address (last byte of last entry)
/// </summary>
public uint EndAddress { get; set; }
/// <summary>
/// Starting sector within VOB of nth VOBU
/// </summary>
public uint[]? StartingSectors { get; set; }
}
}

View File

@@ -0,0 +1,159 @@
using System.Runtime.InteropServices;
namespace SabreTools.Serialization.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo.html"/>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class VideoManagerIFO
{
/// <summary>
/// "DVDVIDEO-VMG"
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
public string? Signature;
/// <summary>
/// Last sector of VMG set (last sector of BUP)
/// </summary>
public uint LastVMGSetSector;
/// <summary>
/// Last sector of IFO
/// </summary>
public uint LastIFOSector;
/// <summary>
/// Version number
/// - Byte 0 - Reserved, should be 0
/// - Byte 1, Bits 7-4 - Major version number
/// - Byte 1, Bits 3-0 - Minor version number
/// </summary>
public ushort VersionNumber;
/// <summary>
/// VMG category
/// </summary>
/// <remarks>byte1=prohibited region mask</remarks>
public uint VMGCategory;
/// <summary>
/// Number of volumes
/// </summary>
public ushort NumberOfVolumes;
/// <summary>
/// Volume number
/// </summary>
public ushort VolumeNumber;
/// <summary>
/// Side ID
/// </summary>
public byte SideID;
/// <summary>
/// Number of title sets
/// </summary>
public ushort NumberOfTitleSets;
/// <summary>
/// Provider ID
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[]? ProviderID;
/// <summary>
/// VMG POS
/// </summary>
public ulong VMGPOS;
/// <summary>
/// End byte address of VMGI_MAT
/// </summary>
public uint InformationManagementTableEndByteAddress;
/// <summary>
/// Start address of FP_PGC (First Play program chain)
/// </summary>
public uint FirstPlayProgramChainStartAddress;
/// <summary>
/// Start sector of Menu VOB
/// </summary>
public uint MenuVOBStartSector;
/// <summary>
/// Sector pointer to TT_SRPT (table of titles)
/// </summary>
public uint TableOfTitlesSectorPointer;
/// <summary>
/// Sector pointer to VMGM_PGCI_UT (Menu Program Chain table)
/// </summary>
public uint MenuProgramChainTableSectorPointer;
/// <summary>
/// Sector pointer to VMG_PTL_MAIT (Parental Management masks)
/// </summary>
public uint ParentalManagementMasksSectorPointer;
/// <summary>
/// Sector pointer to VMG_VTS_ATRT (copies of VTS audio/sub-picture attributes)
/// </summary>
public uint AudioSubPictureAttributesSectorPointer;
/// <summary>
/// Sector pointer to VMG_TXTDT_MG (text data)
/// </summary>
public uint TextDataSectorPointer;
/// <summary>
/// Sector pointer to VMGM_C_ADT (menu cell address table)
/// </summary>
public uint MenuCellAddressTableSectorPointer;
/// <summary>
/// Sector pointer to VMGM_VOBU_ADMAP (menu VOBU address map)
/// </summary>
public uint MenuVOBUAddressMapSectorPointer;
/// <summary>
/// Video attributes of VMGM_VOBS
/// </summary>
public ushort VideoAttributes;
/// <summary>
/// Number of audio streams in VMGM_VOBS
/// </summary>
public ushort NumberOfAudioStreams;
/// <summary>
/// Audio attributes of VMGM_VOBS
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public ulong[]? AudioAttributes;
/// <summary>
/// Unknown
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[]? Unknown;
/// <summary>
/// Number of subpicture streams in VMGM_VOBS (0 or 1)
/// </summary>
public ushort NumberOfSubpictureStreams;
/// <summary>
/// Subpicture attributes of VMGM_VOBS
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[]? SubpictureAttributes;
/// <summary>
/// Reserved
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 164)]
public byte[]? Reserved;
}
}

View File

@@ -0,0 +1,169 @@
using System.Runtime.InteropServices;
namespace SabreTools.Serialization.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo.html"/>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class VideoTitleSetIFO
{
/// <summary>
/// "DVDVIDEO-VTS"
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
public string? Signature;
/// <summary>
/// Last sector of title set (last sector of BUP)
/// </summary>
public uint LastTitleSetSector;
/// <summary>
/// Last sector of IFO
/// </summary>
public uint LastIFOSector;
/// <summary>
/// Version number
/// - Byte 0 - Reserved, should be 0
/// - Byte 1, Bits 7-4 - Major version number
/// - Byte 1, Bits 3-0 - Minor version number
/// </summary>
public ushort VersionNumber;
/// <summary>
/// VTS category
/// </summary>
/// <remarks>0=unspecified, 1=Karaoke</remarks>
public uint VMGCategory;
/// <summary>
/// Number of volumes
/// </summary>
public ushort NumberOfVolumes;
/// <summary>
/// Volume number
/// </summary>
public ushort VolumeNumber;
/// <summary>
/// Side ID
/// </summary>
public byte SideID;
/// <summary>
/// Number of title sets
/// </summary>
public ushort NumberOfTitleSets;
/// <summary>
/// Provider ID
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[]? ProviderID;
/// <summary>
/// VMG POS
/// </summary>
public ulong VMGPOS;
/// <summary>
/// End byte address of VTS_MAT
/// </summary>
public uint InformationManagementTableEndByteAddress;
/// <summary>
/// Start address of FP_PGC (First Play program chain)
/// </summary>
public uint FirstPlayProgramChainStartAddress;
/// <summary>
/// Start sector of Menu VOB
/// </summary>
public uint MenuVOBStartSector;
/// <summary>
/// Start sector of Title VOB
/// </summary>
public uint TitleVOBStartSector;
/// <summary>
/// Sector pointer to VTS_PTT_SRPT (table of Titles and Chapters)
/// </summary>
public uint TableOfTitlesAndChaptersSectorPointer;
/// <summary>
/// Sector pointer to VTS_PGCI (Title Program Chain table)
/// </summary>
public uint TitleProgramChainTableSectorPointer;
/// <summary>
/// Sector pointer to VTSM_PGCI_UT (Menu Program Chain table)
/// </summary>
public uint MenuProgramChainTableSectorPointer;
/// <summary>
/// Sector pointer to VTS_TMAPTI (time map)
/// </summary>
public uint TimeMapSectorPointer;
/// <summary>
/// Sector pointer to VTSM_C_ADT (menu cell address table)
/// </summary>
public uint MenuCellAddressTableSectorPointer;
/// <summary>
/// Sector pointer to VTSM_VOBU_ADMAP (menu VOBU address map)
/// </summary>
public uint MenuVOBUAddressMapSectorPointer;
/// <summary>
/// Sector pointer to VTS_C_ADT (title set cell address table)
/// </summary>
public uint TitleSetCellAddressTableSectorPointer;
/// <summary>
/// Sector pointer to VTS_VOBU_ADMAP (title set VOBU address map)
/// </summary>
public uint TitleSetVOBUAddressMapSectorPointer;
/// <summary>
/// Video attributes of VTSM_VOBS
/// </summary>
public ushort VideoAttributes;
/// <summary>
/// Number of audio streams in VTSM_VOBS
/// </summary>
public ushort NumberOfAudioStreams;
/// <summary>
/// Audio attributes of VTSM_VOBS
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public ulong[]? AudioAttributes;
/// <summary>
/// Unknown
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[]? Unknown;
/// <summary>
/// Number of subpicture streams in VTSM_VOBS (0 or 1)
/// </summary>
public ushort NumberOfSubpictureStreams;
/// <summary>
/// Subpicture attributes of VTSM_VOBS
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[]? SubpictureAttributes;
/// <summary>
/// Reserved
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 164)]
public byte[]? Reserved;
}
}

View File

@@ -4,15 +4,15 @@ namespace SabreTools.Serialization.Models.DosCenter
public class File
{
/// <remarks>name, attribute</remarks>
[SabreTools.Models.Required]
[Required]
public string? Name { get; set; }
/// <remarks>size, attribute, numeric</remarks>
[SabreTools.Models.Required]
[Required]
public string? Size { get; set; }
/// <remarks>crc, attribute</remarks>
[SabreTools.Models.Required]
[Required]
public string? CRC { get; set; }
/// <remarks>sha1, attribute</remarks>

View File

@@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.DosCenter
public class Game
{
/// <remarks>name</remarks>
[SabreTools.Models.Required]
[Required]
public string? Name { get; set; }
/// <remarks>file</remarks>

View File

@@ -5,19 +5,19 @@ namespace SabreTools.Serialization.Models.EverdriveSMDB
/// </summary>
public class Row
{
[SabreTools.Models.Required]
[Required]
public string? SHA256 { get; set; }
[SabreTools.Models.Required]
[Required]
public string? Name { get; set; }
[SabreTools.Models.Required]
[Required]
public string? SHA1 { get; set; }
[SabreTools.Models.Required]
[Required]
public string? MD5 { get; set; }
[SabreTools.Models.Required]
[Required]
public string? CRC32 { get; set; }
public string? Size { get; set; }

View File

@@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile
/// </summary>
public class MD2
{
[SabreTools.Models.Required]
[Required]
public string? Hash { get; set; }
[SabreTools.Models.Required]
[Required]
public string? File { get; set; }
}
}

View File

@@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile
/// </summary>
public class MD4
{
[SabreTools.Models.Required]
[Required]
public string? Hash { get; set; }
[SabreTools.Models.Required]
[Required]
public string? File { get; set; }
}
}

View File

@@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile
/// </summary>
public class MD5
{
[SabreTools.Models.Required]
[Required]
public string? Hash { get; set; }
[SabreTools.Models.Required]
[Required]
public string? File { get; set; }
}
}

View File

@@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile
/// </summary>
public class RIPEMD128
{
[SabreTools.Models.Required]
[Required]
public string? Hash { get; set; }
[SabreTools.Models.Required]
[Required]
public string? File { get; set; }
}
}

View File

@@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile
/// </summary>
public class RIPEMD160
{
[SabreTools.Models.Required]
[Required]
public string? Hash { get; set; }
[SabreTools.Models.Required]
[Required]
public string? File { get; set; }
}
}

View File

@@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile
/// </summary>
public class SFV
{
[SabreTools.Models.Required]
[Required]
public string? File { get; set; }
[SabreTools.Models.Required]
[Required]
public string? Hash { get; set; }
}
}

View File

@@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile
/// </summary>
public class SHA1
{
[SabreTools.Models.Required]
[Required]
public string? Hash { get; set; }
[SabreTools.Models.Required]
[Required]
public string? File { get; set; }
}
}

View File

@@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile
/// </summary>
public class SHA256
{
[SabreTools.Models.Required]
[Required]
public string? Hash { get; set; }
[SabreTools.Models.Required]
[Required]
public string? File { get; set; }
}
}

View File

@@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile
/// </summary>
public class SHA384
{
[SabreTools.Models.Required]
[Required]
public string? Hash { get; set; }
[SabreTools.Models.Required]
[Required]
public string? File { get; set; }
}
}

View File

@@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile
/// </summary>
public class SHA512
{
[SabreTools.Models.Required]
[Required]
public string? Hash { get; set; }
[SabreTools.Models.Required]
[Required]
public string? File { get; set; }
}
}

View File

@@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile
/// </summary>
public class SpamSum
{
[SabreTools.Models.Required]
[Required]
public string? Hash { get; set; }
[SabreTools.Models.Required]
[Required]
public string? File { get; set; }
}
}

View File

@@ -0,0 +1,140 @@
namespace SabreTools.Serialization.Models.IRD
{
/// <see href="https://psdevwiki.com/ps3/Bluray_disc#IRD_file"/>
/// <see href="https://github.com/SabreTools/MPF/files/13062347/IRD.File.Format.pdf"/>
public class File
{
/// <summary>
/// "3IRD"
/// </summary>
public byte[]? Magic { get; set; }
/// <summary>
/// Version
/// </summary>
/// <remarks>Versions 6 - 9 are accepted</remarks>
public byte Version { get; set; }
/// <summary>
/// The same value stored in PARAM.SFO / TITLE_ID
/// </summary>
/// <remarks>9 bytes, ASCII, stored without dashes</remarks>
public string? TitleID { get; set; }
/// <summary>
/// Number of bytes that follow containing the title
/// </summary>
public byte TitleLength { get; set; }
/// <summary>
/// The same value stored in PARAM.SFO / TITLE
/// </summary>
/// <remarks><see cref="TitleLength"/> bytes, ASCII</remarks>
public string? Title { get; set; }
/// <summary>
/// The same value stored in PARAM.SFO / PS3_SYSTEM_VER
/// </summary>
/// <remarks>4 bytes, ASCII, missing uses "0000"</remarks>
public string? SystemVersion { get; set; }
/// <summary>
/// The same value stored in PARAM.SFO / VERSION
/// </summary>
/// <remarks>5 bytes, ASCII</remarks>
public string? GameVersion { get; set; }
/// <summary>
/// The same value stored in PARAM.SFO / APP_VER
/// </summary>
/// <remarks>5 bytes, ASCII</remarks>
public string? AppVersion { get; set; }
/// <summary>
/// Length of the gzip-compressed header data
/// </summary>
public uint HeaderLength { get; set; }
/// <summary>
/// Gzip-compressed header data
/// </summary>
public byte[]? Header { get; set; }
/// <summary>
/// Length of the gzip-compressed footer data
/// </summary>
public uint FooterLength { get; set; }
/// <summary>
/// Gzip-compressed footer data
/// </summary>
public byte[]? Footer { get; set; }
/// <summary>
/// Number of complete regions in the image
/// </summary>
public byte RegionCount { get; set; }
/// <summary>
/// MD5 hashes for all complete regions in the image
/// </summary>
/// <remarks><see cref="RegionCount"/> regions, 16-bytes per hash</remarks>
public byte[][]? RegionHashes { get; set; }
/// <summary>
/// Number of decrypted files in the image
/// </summary>
public uint FileCount { get; set; }
/// <summary>
/// Starting sector for each decrypted file
/// </summary>
/// <remarks><see cref="FileCount"/> files, alternating with each <see cref="FileHashes"/> entry</remarks>
public ulong[]? FileKeys { get; set; }
/// <summary>
/// MD5 hashes for all decrypted files in the image
/// </summary>
/// <remarks><see cref="FileCount"/> files, 16-bytes per hash, alternating with each <see cref="FileHashes"/> entry</remarks>
public byte[][]? FileHashes { get; set; }
/// <summary>
/// Extra Config, usually 0x0000
/// </summary>
public ushort ExtraConfig { get; set; }
/// <summary>
/// Attachments, usually 0x0000
/// </summary>
public ushort Attachments { get; set; }
/// <summary>
/// D1 key
/// </summary>
/// <remarks>16 bytes</remarks>
public byte[]? Data1Key { get; set; }
/// <summary>
/// D2 key
/// </summary>
/// <remarks>16 bytes</remarks>
public byte[]? Data2Key { get; set; }
/// <summary>
/// Uncompressed PIC data
/// </summary>
/// <remarks>115 bytes, before D1/D2 keys on version 9</remarks>
public byte[]? PIC { get; set; }
/// <summary>
/// Unique Identifier
/// </summary>
/// <remarks>Not present on version 6 and prior, after AppVersion on version 7</remarks>
public uint UID { get; set; }
/// <summary>
/// IRD content CRC
/// </summary>
public uint CRC { get; set; }
}
}

View File

@@ -14,7 +14,7 @@ namespace SabreTools.Serialization.Models.Listrom
/// </summary>
public class Row
{
[SabreTools.Models.Required]
[Required]
public string? Name { get; set; }
public string? Size { get; set; }

View File

@@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml
[XmlRoot("adjuster")]
public class Adjuster
{
[SabreTools.Models.Required]
[Required]
[XmlAttribute("name")]
public string? Name { get; set; }

View File

@@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml
[XmlRoot("analog")]
public class Analog
{
[SabreTools.Models.Required]
[Required]
[XmlAttribute("mask")]
public string? Mask { get; set; }
}

View File

@@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.Listxml
[XmlRoot("biosset")]
public class BiosSet
{
[SabreTools.Models.Required]
[Required]
[XmlAttribute("name")]
public string? Name { get; set; }
[SabreTools.Models.Required]
[Required]
[XmlAttribute("description")]
public string? Description { get; set; }

View File

@@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml
[XmlRoot("chip")]
public class Chip
{
[SabreTools.Models.Required]
[Required]
[XmlAttribute("name")]
public string? Name { get; set; }
@@ -14,7 +14,7 @@ namespace SabreTools.Serialization.Models.Listxml
public string? Tag { get; set; }
/// <remarks>(cpu|audio)</remarks>
[SabreTools.Models.Required]
[Required]
[XmlAttribute("type")]
public string? Type { get; set; }

View File

@@ -6,20 +6,20 @@ namespace SabreTools.Serialization.Models.Listxml
[XmlRoot("condition")]
public class Condition
{
[SabreTools.Models.Required]
[Required]
[XmlAttribute("tag")]
public string? Tag { get; set; }
[SabreTools.Models.Required]
[Required]
[XmlAttribute("mask")]
public string? Mask { get; set; }
/// <remarks>(eq|ne|gt|le|lt|ge)</remarks>
[SabreTools.Models.Required]
[Required]
[XmlAttribute("relation")]
public string? Relation { get; set; }
[SabreTools.Models.Required]
[Required]
[XmlAttribute("value")]
public string? Value { get; set; }
}

View File

@@ -6,12 +6,12 @@ namespace SabreTools.Serialization.Models.Listxml
[XmlRoot("conflocation")]
public class ConfLocation
{
[SabreTools.Models.Required]
[Required]
[XmlAttribute("name")]
public string? Name { get; set; }
/// <remarks>Numeric?</remarks>
[SabreTools.Models.Required]
[Required]
[XmlAttribute("number")]
public string? Number { get; set; }

View File

@@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.Listxml
[XmlRoot("confsetting")]
public class ConfSetting
{
[SabreTools.Models.Required]
[Required]
[XmlAttribute("name")]
public string? Name { get; set; }
[SabreTools.Models.Required]
[Required]
[XmlAttribute("value")]
public string? Value { get; set; }

View File

@@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.Listxml
[XmlRoot("configuration")]
public class Configuration
{
[SabreTools.Models.Required]
[Required]
[XmlAttribute("name")]
public string? Name { get; set; }
[SabreTools.Models.Required]
[Required]
[XmlAttribute("tag")]
public string? Tag { get; set; }

View File

@@ -7,7 +7,7 @@ namespace SabreTools.Serialization.Models.Listxml
public class Control
{
/// <remarks>(joy|stick|paddle|pedal|lightgun|positional|dial|trackball|mouse|only_buttons|keypad|keyboard|mahjong|hanafuda|gambling)</remarks>
[SabreTools.Models.Required]
[Required]
[XmlAttribute("type")]
public string? Type { get; set; }

View File

@@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml
[XmlRoot("device")]
public class Device
{
[SabreTools.Models.Required]
[Required]
[XmlAttribute("type")]
public string? Type { get; set; }

Some files were not shown because too many files have changed in this diff Show More