Files
Matt Nadareski 7689c6dd07 Libraries
This change looks dramatic, but it's just separating out the already-split namespaces into separate top-level folders. In theory, every single one could be built into their own Nuget package. `SabreTools.Serialization` still builds the normal Nuget package that is used by all other projects and includes all namespaces.
2026-03-21 16:26:56 -04:00

85 lines
2.6 KiB
C#

using System.Collections.Generic;
using SabreTools.Data.Models.NES;
namespace SabreTools.Serialization.CrossModel
{
/// <see href="https://www.nesdev.org/wiki/FDS_disk_format"/>
/// <see href="https://gist.github.com/einstein95/6545066905680466cdf200c4cc8ca4f0"/>
public partial class FamicomDiskSystem : ICrossModel<FDS, QD>
{
/// <inheritdoc/>
public bool Debug { get; set; } = false;
/// <inheritdoc/>
public FDS? Deserialize(QD? obj)
{
// Ignore invalid data
if (obj?.Data is null || obj.Data.Length == 0)
return null;
// Ignore incomplete data
if ((obj.Data.Length % 65536) != 0)
return null;
// Determine the number of sides
byte sides = (byte)(obj.Data.Length / 65536);
if (sides < 1)
return null;
// Create the FDS for output
var fds = new FDS
{
Header = new FDSHeader
{
IdentificationString = Constants.FDSSignatureBytes,
DiskSides = sides,
}
};
// Loop over the sides and convert
List<byte> converted = [];
for (int i = 0; i < sides; i++)
{
// Convert the data to manipulate
List<byte> data = [.. obj.Data];
// Delete block 01 checksum
data.RemoveRange(0x38, 2);
// Delete block 02 checksum
int pos = 0x3A;
data.RemoveRange(pos, 2);
// Loop while there are more files
while (data[pos] == 3)
{
// Get the filesize
ushort filesize = (ushort)((data[pos + 0x0E] << 8) | data[pos + 0x0D]);
// Delete block 03 checksum
data.RemoveRange(pos + 0x10, 2);
// Skip the file data
pos = pos + 0x10 + 1 + filesize;
// Delete block 04 checksum
data.RemoveRange(pos, 2);
}
// Ensure the data is correctly sized
if (data.Count > 65500)
data = data.GetRange(0, 65500);
else if (data.Count < 65500)
data.AddRange(new byte[65500 - data.Count]);
// Add the data to the output
converted.AddRange(data);
}
// Assign the converted data and return
fds.Data = [.. converted];
return fds;
}
}
}