mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-09-21 14:25:03 +00:00
Add A78 cart writer
This commit is contained in:
24
SabreTools.Serialization.Writers.Test/Atari7800CartTests.cs
Normal file
24
SabreTools.Serialization.Writers.Test/Atari7800CartTests.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.IO;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Writers.Test
|
||||
{
|
||||
public class Atari7800CartTests
|
||||
{
|
||||
[Fact]
|
||||
public void SerializeArray_Null_Null()
|
||||
{
|
||||
var serializer = new Atari7800Cart();
|
||||
byte[]? actual = serializer.SerializeArray(null);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SerializeStream_Null_Null()
|
||||
{
|
||||
var serializer = new Atari7800Cart();
|
||||
Stream? actual = serializer.SerializeStream(null);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
165
SabreTools.Serialization.Writers/Atari7800Cart.cs
Normal file
165
SabreTools.Serialization.Writers/Atari7800Cart.cs
Normal file
@@ -0,0 +1,165 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.Data.Models.Atari7800;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Numerics.Extensions;
|
||||
|
||||
namespace SabreTools.Serialization.Writers
|
||||
{
|
||||
public class Atari7800Cart : BaseBinaryWriter<Cart>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override Stream? SerializeStream(Cart? obj)
|
||||
{
|
||||
// If the metadata file is null
|
||||
if (obj is null)
|
||||
return null;
|
||||
|
||||
// Setup the writer and output
|
||||
var stream = new MemoryStream();
|
||||
|
||||
// Write header
|
||||
if (!WriteHeader(obj.Header, stream))
|
||||
return null;
|
||||
|
||||
// Write data
|
||||
if (!WriteRom(obj.Data, stream))
|
||||
return null;
|
||||
|
||||
// Return the stream
|
||||
stream.SeekIfPossible(0, SeekOrigin.Begin);
|
||||
return stream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write header data to the stream
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream to write to</param>
|
||||
/// <returns>True if the writing was successful, false otherwise</returns>
|
||||
public bool WriteHeader(Header? obj, Stream stream)
|
||||
{
|
||||
if (obj is null)
|
||||
{
|
||||
if (Debug) Console.WriteLine("Header was invalid!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to write the data
|
||||
try
|
||||
{
|
||||
if (Debug) Console.WriteLine("Attempting to write header data");
|
||||
|
||||
// Byte 0
|
||||
stream.Write(obj.HeaderVersion);
|
||||
stream.Flush();
|
||||
|
||||
// Bytes 1-16
|
||||
stream.Write(obj.MagicText);
|
||||
stream.Flush();
|
||||
|
||||
// Bytes 17-48
|
||||
stream.Write(obj.CartTitle);
|
||||
stream.Flush();
|
||||
|
||||
// Bytes 49-52
|
||||
stream.Write(obj.RomSizeWithoutHeader);
|
||||
stream.Flush();
|
||||
|
||||
// Bytes 53-54
|
||||
stream.Write((ushort)obj.CartType);
|
||||
stream.Flush();
|
||||
|
||||
// Bytes 55-56
|
||||
stream.Write((byte)obj.Controller1Type);
|
||||
stream.Write((byte)obj.Controller2Type);
|
||||
stream.Flush();
|
||||
|
||||
// Byte 57
|
||||
stream.Write((byte)obj.TVType);
|
||||
stream.Flush();
|
||||
|
||||
// Byte 58
|
||||
stream.Write((byte)obj.SaveDevice);
|
||||
stream.Flush();
|
||||
|
||||
// Bytes 59-62
|
||||
stream.Write(obj.Reserved);
|
||||
stream.Flush();
|
||||
|
||||
// Byte 63
|
||||
stream.Write((byte)obj.SlotPassthroughDevice);
|
||||
stream.Flush();
|
||||
|
||||
if (obj.HeaderVersion >= 4)
|
||||
{
|
||||
// Byte 64
|
||||
stream.Write((byte)obj.Mapper);
|
||||
stream.Flush();
|
||||
|
||||
// Byte 65
|
||||
stream.Write((byte)obj.MapperOptions);
|
||||
stream.Flush();
|
||||
|
||||
// Byte 66-67
|
||||
stream.Write((ushort)obj.AudioDevice);
|
||||
stream.Flush();
|
||||
|
||||
// Byte 68-69
|
||||
stream.Write((ushort)obj.Interrupt);
|
||||
stream.Flush();
|
||||
|
||||
// Bytes 70-99
|
||||
stream.Write(obj.Padding);
|
||||
stream.Flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bytes 64-99
|
||||
stream.Write(obj.Padding);
|
||||
stream.Flush();
|
||||
}
|
||||
|
||||
// Bytes 100-127
|
||||
stream.Write(obj.EndMagicText);
|
||||
stream.Flush();
|
||||
|
||||
// Header extracted
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (Debug) Console.Error.WriteLine(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write rom data to the stream
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream to write to</param>
|
||||
/// <returns>True if the writing was successful, false otherwise</returns>
|
||||
public bool WriteRom(byte[]? obj, Stream stream)
|
||||
{
|
||||
if (obj is null || obj.Length == 0)
|
||||
{
|
||||
if (Debug) Console.WriteLine("ROM data was invalid!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to write the data
|
||||
try
|
||||
{
|
||||
if (Debug) Console.WriteLine("Attempting to write ROM data");
|
||||
|
||||
stream.Write(obj, 0, obj.Length);
|
||||
stream.Flush();
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (Debug) Console.Error.WriteLine(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,9 @@ namespace SabreTools.Wrappers
|
||||
: Path.GetFileNameWithoutExtension(Filename);
|
||||
string basePath = Path.Combine(outputDirectory, baseFilename);
|
||||
|
||||
// Create the writer
|
||||
var writer = new Serialization.Writers.Atari7800Cart { Debug = includeDebug };
|
||||
|
||||
// Check if any data was extracted successfully
|
||||
bool success = false;
|
||||
|
||||
@@ -27,7 +30,7 @@ namespace SabreTools.Wrappers
|
||||
try
|
||||
{
|
||||
using var fs = File.Open(headerPath, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
success |= WriteHeader(fs, includeDebug);
|
||||
success |= writer.WriteHeader(Header, fs);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -45,7 +48,7 @@ namespace SabreTools.Wrappers
|
||||
try
|
||||
{
|
||||
using var fs = File.Open(romPath, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
success |= WriteRom(fs, includeDebug);
|
||||
success |= writer.WriteRom(Model.Data, fs);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.Data.Models.Atari7800;
|
||||
using SabreTools.Numerics.Extensions;
|
||||
|
||||
namespace SabreTools.Wrappers
|
||||
{
|
||||
@@ -26,145 +24,9 @@ namespace SabreTools.Wrappers
|
||||
return false;
|
||||
}
|
||||
|
||||
// Open the output file for writing
|
||||
using var fs = File.Open(outputPath, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
|
||||
// Header data
|
||||
if (!WriteHeader(fs, includeDebug))
|
||||
return false;
|
||||
|
||||
// ROM data
|
||||
if (!WriteRom(fs, includeDebug))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write header data to the stream
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if the writing was successful, false otherwise</returns>
|
||||
private bool WriteHeader(Stream stream, bool includeDebug)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine("Attempting to write header data");
|
||||
|
||||
if (Header is null)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine("Header was invalid!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to write the data
|
||||
try
|
||||
{
|
||||
// Byte 0
|
||||
stream.Write(Header.HeaderVersion);
|
||||
stream.Flush();
|
||||
|
||||
// Bytes 1-16
|
||||
stream.Write(Header.MagicText);
|
||||
stream.Flush();
|
||||
|
||||
// Bytes 17-48
|
||||
stream.Write(Header.CartTitle);
|
||||
stream.Flush();
|
||||
|
||||
// Bytes 49-52
|
||||
stream.Write(Header.RomSizeWithoutHeader);
|
||||
stream.Flush();
|
||||
|
||||
// Bytes 53-54
|
||||
stream.Write((ushort)Header.CartType);
|
||||
stream.Flush();
|
||||
|
||||
// Bytes 55-56
|
||||
stream.Write((byte)Header.Controller1Type);
|
||||
stream.Write((byte)Header.Controller2Type);
|
||||
stream.Flush();
|
||||
|
||||
// Byte 57
|
||||
stream.Write((byte)Header.TVType);
|
||||
stream.Flush();
|
||||
|
||||
// Byte 58
|
||||
stream.Write((byte)Header.SaveDevice);
|
||||
stream.Flush();
|
||||
|
||||
// Bytes 59-62
|
||||
stream.Write(Header.Reserved);
|
||||
stream.Flush();
|
||||
|
||||
// Byte 63
|
||||
stream.Write((byte)Header.SlotPassthroughDevice);
|
||||
stream.Flush();
|
||||
|
||||
if (HeaderVersion >= 4)
|
||||
{
|
||||
// Byte 64
|
||||
stream.Write((byte)Header.Mapper);
|
||||
stream.Flush();
|
||||
|
||||
// Byte 65
|
||||
stream.Write((byte)Header.MapperOptions);
|
||||
stream.Flush();
|
||||
|
||||
// Byte 66-67
|
||||
stream.Write((ushort)Header.AudioDevice);
|
||||
stream.Flush();
|
||||
|
||||
// Byte 68-69
|
||||
stream.Write((ushort)Header.Interrupt);
|
||||
stream.Flush();
|
||||
|
||||
// Bytes 70-99
|
||||
stream.Write(Header.Padding);
|
||||
stream.Flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bytes 64-99
|
||||
stream.Write(Header.Padding);
|
||||
stream.Flush();
|
||||
}
|
||||
|
||||
// Bytes 100-127
|
||||
stream.Write(Header.EndMagicText);
|
||||
stream.Flush();
|
||||
|
||||
// Header extracted
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.Error.WriteLine(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write rom data to the stream
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if the writing was successful, false otherwise</returns>
|
||||
private bool WriteRom(Stream stream, bool includeDebug)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine("Attempting to write ROM data");
|
||||
|
||||
// Try to write the data
|
||||
try
|
||||
{
|
||||
stream.Write(Model.Data, 0, Model.Data.Length);
|
||||
stream.Flush();
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.Error.WriteLine(ex);
|
||||
return false;
|
||||
}
|
||||
// Create and use the writer
|
||||
var writer = new Serialization.Writers.Atari7800Cart { Debug = includeDebug };
|
||||
return writer.SerializeFile(Model, outputPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
<ProjectReference Include="..\SabreTools.Data.Models\SabreTools.Data.Models.csproj" />
|
||||
<ProjectReference Include="..\SabreTools.ObjectIdentifier\SabreTools.ObjectIdentifier.csproj" />
|
||||
<ProjectReference Include="..\SabreTools.Serialization.Readers\SabreTools.Serialization.Readers.csproj" />
|
||||
<ProjectReference Include="..\SabreTools.Serialization.Writers\SabreTools.Serialization.Writers.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user