Skip to content

Commit

Permalink
fix: make endianness semantics consistent
Browse files Browse the repository at this point in the history
* also adjust some lingo io
  • Loading branch information
PaulusParssinen committed Jun 18, 2024
1 parent 62955b5 commit b7df0db
Show file tree
Hide file tree
Showing 16 changed files with 190 additions and 158 deletions.
18 changes: 9 additions & 9 deletions Shockky.Sandbox/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using Shockky.Resources.Types;

using System.CommandLine;

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;

Expand All @@ -20,17 +19,19 @@
}.ExistingOnly();

var outputOption = new Option<DirectoryInfo>("--output",
getDefaultValue: () => new DirectoryInfo("Output/"),
getDefaultValue: () => new DirectoryInfo("Output"),
description: "Directory for the extracted resources")
.LegalFilePathsOnly();

outputOption.AddAlias("-o");

var rootCommand = new RootCommand()
{
inputArgument,
outputOption
};

rootCommand.SetHandler(HandleExtractCommand,
rootCommand.SetHandler(HandleExtractCommand,
inputArgument, outputOption);

return rootCommand.Invoke(args);
Expand All @@ -54,11 +55,10 @@ static System.Drawing.Color[] ReadPalette(string fileName)
System.Drawing.Color[] colors = new System.Drawing.Color[input.ReadInt16()];
for (int i = 0; i < colors.Length; i++)
{
byte r = input.ReadByte();
byte g = input.ReadByte();
byte b = input.ReadByte();

colors[i] = System.Drawing.Color.FromArgb(r, g, b);
colors[i] = System.Drawing.Color.FromArgb(
red: input.ReadByte(),
green: input.ReadByte(),
blue: input.ReadByte());

input.ReadByte();
}
Expand Down Expand Up @@ -95,7 +95,7 @@ static void HandleExtractCommand(IEnumerable<System.IO.FileInfo> input, Director

Console.Write($"Disassembling file \"{file.Name}\"..");

var shockwaveFile = ShockwaveFile.Load(file.FullName);
var shockwaveFile = ShockwaveFile.Read(file.FullName);

if (shockwaveFile.Resources.Values
.FirstOrDefault(c => c.Kind == OsType.KEYPtr) is not KeyMap associationTable)
Expand Down
14 changes: 7 additions & 7 deletions Shockky/IO/ShockwaveReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public short ReadInt16BigEndian()
Advance(sizeof(short));

return ReverseEndianness ?
value : BinaryPrimitives.ReverseEndianness(value);
BinaryPrimitives.ReverseEndianness(value) : value;
}

public ushort ReadUInt16LittleEndian()
Expand All @@ -93,7 +93,7 @@ public ushort ReadUInt16BigEndian()
Advance(sizeof(ushort));

return ReverseEndianness ?
value : BinaryPrimitives.ReverseEndianness(value);
BinaryPrimitives.ReverseEndianness(value) : value;
}

public int ReadInt32LittleEndian()
Expand All @@ -110,7 +110,7 @@ public int ReadInt32BigEndian()
Advance(sizeof(int));

return ReverseEndianness ?
value : BinaryPrimitives.ReverseEndianness(value);
BinaryPrimitives.ReverseEndianness(value) : value;
}

public uint ReadUInt32LittleEndian()
Expand All @@ -130,21 +130,21 @@ public uint ReadUInt32BigEndian()
value : BinaryPrimitives.ReverseEndianness(value);
}

public ulong ReadUInt64()
public ulong ReadUInt64LittleEndian()
{
ulong value = BinaryPrimitives.ReadUInt64LittleEndian(CurrentSpan);
Advance(sizeof(ulong));

return ReverseEndianness ?
BinaryPrimitives.ReverseEndianness(value) : value;
}
public ulong ReadBEUInt64()
public ulong ReadUInt64BigEndian()
{
ulong value = BinaryPrimitives.ReadUInt64BigEndian(CurrentSpan);
Advance(sizeof(ulong));

return ReverseEndianness ?
value : BinaryPrimitives.ReverseEndianness(value);
BinaryPrimitives.ReverseEndianness(value) : value;
}
public double ReadDoubleLittleEndian()
{
Expand All @@ -155,7 +155,7 @@ public double ReadDoubleLittleEndian()
Advance(sizeof(double));
return value;
}
public double ReadBEDouble()
public double ReadDoubleBigEndian()
{
double value = ReverseEndianness ?
BinaryPrimitives.ReadDoubleLittleEndian(CurrentSpan) :
Expand Down
12 changes: 12 additions & 0 deletions Shockky/IO/ShockwaveWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ public void Write7BitEncodedUInt(uint value)

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetVarIntSize(int value) => GetVarUIntSize((uint)value);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetVarUIntSize(uint value)
{
Expand All @@ -179,13 +180,22 @@ public static int GetVarUIntSize(uint value)
return (x * 37) >> 8;
}

/// <summary>
/// Writes length-prefixed UTF-8 string.
/// </summary>
/// <param name="value">The UTF-8 string to write.</param>
public void WriteString(ReadOnlySpan<char> value)
{
Write7BitEncodedUInt((uint)value.Length);

int len = Encoding.UTF8.GetBytes(value, _data.Slice(_position));
_position += len;
}

/// <summary>
/// Writes a null-terminated UTF-8 string.
/// </summary>
/// <param name="value">The UTF-8 string to write.</param>
public void WriteCString(ReadOnlySpan<char> value)
{
int len = Encoding.UTF8.GetBytes(value, _data.Slice(_position));
Expand All @@ -210,6 +220,8 @@ public void WriteColor(byte r, byte g, byte b)

Advance(6);
}

// TODO: Endianness
public void WritePoint(Point value)
{
WriteInt16LittleEndian((short)value.X);
Expand Down
72 changes: 46 additions & 26 deletions Shockky/Lingo/LingoFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ namespace Shockky.Lingo;

public class LingoFunction : IShockwaveItem
{
public byte[] Bytecode { get; set; }
public List<short> Arguments { get; }
public List<short> Locals { get; }
public byte[] BytesPerLine { get; }

public short EnvironmentIndex { get; set; }
public LingoEventFlags EventKind { get; }
public LingoEventFlags EventFlags { get; set; }

public byte[] Bytecode { get; set; }
public List<short> Arguments { get; set; }
public List<short> Locals { get; set; }
public List<short> Globals { get; set; }
public byte[] BytesPerLine { get; set; }

public int ParserBytesRead { get; set; }
public int BodyLineNumber { get; set; }

public int StackHeight { get; set; }

Expand All @@ -19,34 +23,36 @@ public LingoFunction()
Bytecode = [];
Arguments = new List<short>();
Locals = new List<short>();
Globals = new List<short>();
BytesPerLine = [];
}
public LingoFunction(ref ShockwaveReader input)
{
EnvironmentIndex = input.ReadInt16LittleEndian();
EventKind = (LingoEventFlags)input.ReadInt16LittleEndian();
EnvironmentIndex = input.ReadInt16BigEndian();
EventFlags = (LingoEventFlags)input.ReadInt16BigEndian();

Bytecode = new byte[input.ReadInt32LittleEndian()];
int bytecodeOffset = input.ReadInt32LittleEndian();
Bytecode = new byte[input.ReadInt32BigEndian()];
int bytecodeOffset = input.ReadInt32BigEndian();

Arguments = new List<short>(input.ReadInt16LittleEndian());
int argumentsOffset = input.ReadInt32LittleEndian();
Arguments = new List<short>(input.ReadInt16BigEndian());
int argumentsOffset = input.ReadInt32BigEndian();

Locals = new List<short>(input.ReadInt16LittleEndian());
int localsOffset = input.ReadInt32LittleEndian();
Locals = new List<short>(input.ReadInt16BigEndian());
int localsOffset = input.ReadInt32BigEndian();

short globalsCount = input.ReadInt16LittleEndian(); //v5
int globalsOffset = input.ReadInt32LittleEndian(); //v5
Globals = new List<short>(input.ReadInt16BigEndian()); //v5
int globalsOffset = input.ReadInt32BigEndian(); //v5

int parserBytesRead = input.ReadInt32LittleEndian();
short bodyLineNumber = input.ReadInt16LittleEndian();
ParserBytesRead = input.ReadInt32BigEndian();
BodyLineNumber = input.ReadInt16BigEndian();

BytesPerLine = new byte[input.ReadInt16LittleEndian()];
int lineOffset = input.ReadInt32LittleEndian();
BytesPerLine = new byte[input.ReadInt16BigEndian()];
int lineOffset = input.ReadInt32BigEndian();

//if version > 0x800
StackHeight = input.ReadInt32LittleEndian();
StackHeight = input.ReadInt32BigEndian();

// TODO: Seperate "data" reading from handler body
int bodyEndOffset = input.Position;

input.Position = bytecodeOffset;
Expand All @@ -55,15 +61,21 @@ public LingoFunction(ref ShockwaveReader input)
input.Position = argumentsOffset;
for (int i = 0; i < Arguments.Capacity; i++)
{
Arguments.Add(input.ReadInt16LittleEndian());
Arguments.Add(input.ReadInt16BigEndian());
}

input.Position = localsOffset;
for (int i = 0; i < Locals.Capacity; i++)
{
Locals.Add(input.ReadInt16LittleEndian());
Locals.Add(input.ReadInt16BigEndian());
}

input.Position = globalsOffset;
for (int i = 0; i < Globals.Capacity; i++)
{
Globals.Add(input.ReadInt16BigEndian());
}

input.Position = lineOffset;
for (int i = 0; i < BytesPerLine.Length; i++)
{
Expand Down Expand Up @@ -97,8 +109,16 @@ public int GetBodySize(WriterOptions options)

public void WriteTo(ShockwaveWriter output, WriterOptions options)
{
throw new NotImplementedException();
output.WriteInt16LittleEndian(EnvironmentIndex);
output.WriteInt16LittleEndian((short)EventKind);
output.WriteInt16BigEndian(EnvironmentIndex);
output.WriteUInt16BigEndian((ushort)EventFlags);
output.WriteUInt16BigEndian((ushort)Bytecode.Length);
output.WriteUInt16BigEndian(0); // Reserve
output.WriteUInt16BigEndian((ushort)Arguments.Count);
output.WriteInt32BigEndian(0); // Reserve
output.WriteUInt16BigEndian((ushort)Locals.Count);
output.WriteInt32BigEndian(0); // Reserve
output.WriteUInt16BigEndian((ushort)Globals.Count);
output.WriteInt32BigEndian(0); // Reserve
output.WriteUInt16BigEndian((ushort)BytesPerLine.Length);
}
}
4 changes: 2 additions & 2 deletions Shockky/Lingo/LingoLiteral.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ public static LingoLiteral Read(ref ShockwaveReader input, VariantKind entryKind
{
input.Position = entryOffset;

int length = input.ReadInt32LittleEndian();
int length = input.ReadInt32BigEndian();
object value = entryKind switch
{
VariantKind.String => input.ReadString(length),
VariantKind.Float when length == 8 => input.ReadDoubleLittleEndian(),
VariantKind.Float when length == 8 => input.ReadDoubleBigEndian(),
VariantKind.Float when length == 10 => throw new NotSupportedException("The 80-bit double-extended precision is not supported, yet."),
VariantKind.CompiledJavascript => input.ReadBytes(length).ToArray(),

Expand Down
2 changes: 1 addition & 1 deletion Shockky/Resources/AfterBurner/AfterburnerMapEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public AfterburnerMapEntry(ZLibShockwaveReader input)
Length = input.Read7BitEncodedInt();
DecompressedLength = input.Read7BitEncodedInt();
CompressionTypeIndex = input.Read7BitEncodedInt();
Kind = (OsType)input.ReadInt32LittleEndian();
Kind = (OsType)input.ReadInt32BigEndian();
}

public int GetBodySize(WriterOptions options)
Expand Down
2 changes: 1 addition & 1 deletion Shockky/Resources/AfterBurner/FileCompressionTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public FileCompressionTypes(ref ShockwaveReader input, ReaderContext context)
{
using ZLibShockwaveReader decompressedInput = ZLib.CreateDeflateReaderUnsafe(ref input);

int compressionTypeCount = decompressedInput.ReadInt16LittleEndian();
int compressionTypeCount = decompressedInput.ReadInt16BigEndian();

Guid[] ids = new Guid[compressionTypeCount];
for (int i = 0; i < ids.Length; i++)
Expand Down
2 changes: 1 addition & 1 deletion Shockky/Resources/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public Config(ref ShockwaveReader input, ReaderContext context)
OriginalVersion = (DirectorVersion)input.ReadInt16LittleEndian();
MaxCastColorDepth = input.ReadInt16LittleEndian();
Flags = (ConfigFlags)input.ReadInt32LittleEndian();
ScoreUsedChannelsMask = input.ReadUInt64();
ScoreUsedChannelsMask = input.ReadUInt64LittleEndian();

Trial = input.ReadBoolean();
Field34 = input.ReadByte();
Expand Down
2 changes: 1 addition & 1 deletion Shockky/Resources/Enum/OsType.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
namespace Shockky.Resources;

/// <summary>
/// Represents all the resource types that Shockwave movies/casts can contain.
/// Represents the resource types that Director authored Shockwave movies/casts can contain.
/// <para/>
/// See: https://en.wikipedia.org/wiki/FourCC
/// </summary>
Expand Down
6 changes: 3 additions & 3 deletions Shockky/Resources/FileMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ public class FileMetadata
public CodecKind Codec { get; set; }

public int FileLength { get; }
public bool IsBigEndian => Kind == OsType.XFIR;
public bool IsLittleEndian => Kind == OsType.XFIR;

public FileMetadata(ref ShockwaveReader input)
{
Kind = (OsType)input.ReadInt32BigEndian();
FileLength = IsBigEndian ? input.ReadInt32LittleEndian() : input.ReadInt32BigEndian();
Codec = (CodecKind)(IsBigEndian ? input.ReadInt32LittleEndian() : input.ReadInt32BigEndian());
FileLength = IsLittleEndian ? input.ReadInt32LittleEndian() : input.ReadInt32BigEndian();
Codec = (CodecKind)(IsLittleEndian ? input.ReadInt32LittleEndian() : input.ReadInt32BigEndian());
}
}
Loading

0 comments on commit b7df0db

Please sign in to comment.