chore(replay): scaffold project with machine builder and frame types
This commit is contained in:
1 parent
f7f26720cb
commit
247e896815
5 files changed
+124
No files matched your search
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>disable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>Chip8.Replay</RootNamespace>
|
||||
<AssemblyName>Chip8.Replay</AssemblyName>
|
||||
<LangVersion>10</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Chip8.Core\Chip8.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,31 @@
|
||||
using Chip8.Core;
|
||||
|
||||
namespace Chip8.Replay;
|
||||
|
||||
public static class MachineBuilder
|
||||
{
|
||||
public static Machine fromMovie(InputMovie movie)
|
||||
{
|
||||
return new Machine(QuirksCodec.clone(movie.quirks), movie.randomSeed, movie.platform);
|
||||
}
|
||||
|
||||
public static Machine fromMovie(InputMovie movie, byte[] rom)
|
||||
{
|
||||
var machine = fromMovie(movie);
|
||||
machine.loadRom(rom);
|
||||
return machine;
|
||||
}
|
||||
|
||||
public static InputMovie headerFor(Machine machine, byte[] rom, string romName, int instructionsPerFrame, int? randomSeed)
|
||||
{
|
||||
var movie = new InputMovie
|
||||
{
|
||||
platform = machine.platform,
|
||||
quirks = QuirksCodec.clone(machine.quirks),
|
||||
randomSeed = randomSeed,
|
||||
instructionsPerFrame = instructionsPerFrame,
|
||||
};
|
||||
movie.setRom(rom, romName);
|
||||
return movie;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
|
||||
namespace Chip8.Replay;
|
||||
|
||||
public readonly struct MovieFrame : IEquatable<MovieFrame>
|
||||
{
|
||||
public int index { get; }
|
||||
public KeyMask keys { get; }
|
||||
|
||||
public MovieFrame(int index, KeyMask keys)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(index), "movie frame index cannot be negative");
|
||||
}
|
||||
this.index = index;
|
||||
this.keys = keys;
|
||||
}
|
||||
|
||||
public MovieFrame(int index, ushort keyBits)
|
||||
: this(index, new KeyMask(keyBits))
|
||||
{
|
||||
}
|
||||
|
||||
public bool Equals(MovieFrame other) => index == other.index && keys == other.keys;
|
||||
|
||||
public override bool Equals(object? obj) => obj is MovieFrame other && Equals(other);
|
||||
|
||||
public override int GetHashCode() => (index * 397) ^ keys.bits;
|
||||
|
||||
public override string ToString() => "frame " + index + " " + keys.toKeyList();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Chip8.Replay;
|
||||
|
||||
public static class RomHash
|
||||
{
|
||||
const ulong fnvOffsetBasis = 14695981039346656037UL;
|
||||
const ulong fnvPrime = 1099511628211UL;
|
||||
|
||||
public static ulong compute(byte[] rom)
|
||||
{
|
||||
ulong hash = fnvOffsetBasis;
|
||||
foreach (byte value in rom)
|
||||
{
|
||||
hash ^= value;
|
||||
hash *= fnvPrime;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
public static string toHex(byte[] rom) => format(compute(rom));
|
||||
|
||||
public static string format(ulong hash) => hash.ToString("X16", CultureInfo.InvariantCulture);
|
||||
|
||||
public static ulong parse(string hex) =>
|
||||
ulong.Parse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Chip8.Replay;
|
||||
|
||||
public sealed class TimelineSnapshot
|
||||
{
|
||||
public int frameIndex { get; }
|
||||
public byte[] state { get; }
|
||||
|
||||
public TimelineSnapshot(int frameIndex, byte[] state)
|
||||
{
|
||||
this.frameIndex = frameIndex;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public int stateSize => state.Length;
|
||||
|
||||
public override string ToString() => "snapshot frame=" + frameIndex + " bytes=" + state.Length;
|
||||
}
|
||||
Reference in new issue
Block a user