TasMovie Branch internals
This commit is contained in:
parent
f5f4ded789
commit
e280e4f55c
|
@ -2,82 +2,134 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
using ICSharpCode.SharpZipLib.Zip;
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
//using Ionic.Zip;
|
//using Ionic.Zip;
|
||||||
|
|
||||||
namespace BizHawk.Client.Common
|
namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
public enum BinaryStateLump
|
public class BinaryStateLump
|
||||||
{
|
{
|
||||||
Versiontag,
|
[Name("BizState 1.0")]
|
||||||
Corestate,
|
public static BinaryStateLump Versiontag { get; private set; }
|
||||||
Framebuffer,
|
[Name("Core")]
|
||||||
Input,
|
public static BinaryStateLump Corestate { get; private set; }
|
||||||
CorestateText,
|
[Name("Framebuffer.bmp")]
|
||||||
|
public static BinaryStateLump Framebuffer { get; private set; }
|
||||||
|
[Name("Input Log.txt")]
|
||||||
|
public static BinaryStateLump Input { get; private set; }
|
||||||
|
[Name("CoreText.txt")]
|
||||||
|
public static BinaryStateLump CorestateText { get; private set; }
|
||||||
|
|
||||||
// Only for movies they probably shoudln't be leaching this stuff
|
// Only for movies they probably shoudln't be leaching this stuff
|
||||||
Movieheader,
|
[Name("Header.txt")]
|
||||||
Comments,
|
public static BinaryStateLump Movieheader { get; private set; }
|
||||||
Subtitles,
|
[Name("Comments.txt")]
|
||||||
SyncSettings,
|
public static BinaryStateLump Comments { get; private set; }
|
||||||
|
[Name("Subtitles.txt")]
|
||||||
|
public static BinaryStateLump Subtitles { get; private set; }
|
||||||
|
[Name("SyncSettings.json")]
|
||||||
|
public static BinaryStateLump SyncSettings { get; private set; }
|
||||||
|
|
||||||
// TasMovie
|
// TasMovie
|
||||||
LagLog,
|
[Name("LagLog")]
|
||||||
StateHistory,
|
public static BinaryStateLump LagLog { get; private set; }
|
||||||
StateHistorySettings,
|
[Name("GreenZone")]
|
||||||
Markers,
|
public static BinaryStateLump StateHistory { get; private set; }
|
||||||
ClientSettings,
|
[Name("GreenZoneSettings.txt")]
|
||||||
VerificationLog,
|
public static BinaryStateLump StateHistorySettings { get; private set; }
|
||||||
Branches,
|
[Name("Markers.txt")]
|
||||||
|
public static BinaryStateLump Markers { get; private set; }
|
||||||
|
[Name("ClientSettings.json")]
|
||||||
|
public static BinaryStateLump ClientSettings { get; private set; }
|
||||||
|
[Name("VerificationLog.txt")]
|
||||||
|
public static BinaryStateLump VerificationLog { get; private set; }
|
||||||
|
|
||||||
UserData
|
[Name("UserData.txt")]
|
||||||
|
public static BinaryStateLump UserData { get; private set; }
|
||||||
|
|
||||||
|
// branchstuff
|
||||||
|
[Name("Branches\\CoreData.bin")]
|
||||||
|
public static BinaryStateLump BranchCoreData { get; private set; }
|
||||||
|
[Name("Branches\\InputLog.txt")]
|
||||||
|
public static BinaryStateLump BranchInputLog { get; private set; }
|
||||||
|
[Name("Branches\\FrameBuffer.bmp")]
|
||||||
|
public static BinaryStateLump BranchFrameBuffer { get; private set; }
|
||||||
|
[Name("Branches\\LagLog.bin")]
|
||||||
|
public static BinaryStateLump BranchLagLog { get; private set; }
|
||||||
|
[Name("Branches\\Header.json")]
|
||||||
|
public static BinaryStateLump BranchHeader { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
|
private class NameAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string Name { get; private set; }
|
||||||
|
public NameAttribute(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BinaryStateFileNames
|
public virtual string ReadName { get; private set; }
|
||||||
{
|
public virtual string WriteName { get; private set; }
|
||||||
private static readonly Dictionary<BinaryStateLump, string> ReadNames;
|
|
||||||
private static readonly Dictionary<BinaryStateLump, string> WriteNames;
|
|
||||||
|
|
||||||
static void AddLumpName(BinaryStateLump token, string name)
|
private BinaryStateLump(string name)
|
||||||
{
|
{
|
||||||
ReadNames[token] = Path.GetFileNameWithoutExtension(name);
|
WriteName = name;
|
||||||
WriteNames[token] = name;
|
// for reading, all extensions are stripped
|
||||||
}
|
ReadName = Path.GetFileNameWithoutExtension(name);
|
||||||
static BinaryStateFileNames()
|
|
||||||
{
|
|
||||||
ReadNames = new Dictionary<BinaryStateLump, string>();
|
|
||||||
WriteNames = new Dictionary<BinaryStateLump, string>();
|
|
||||||
AddLumpName(BinaryStateLump.Versiontag, "BizState 1.0");
|
|
||||||
AddLumpName(BinaryStateLump.Corestate, "Core");
|
|
||||||
AddLumpName(BinaryStateLump.Framebuffer, "Framebuffer.bmp");
|
|
||||||
AddLumpName(BinaryStateLump.Input, "Input Log.txt");
|
|
||||||
AddLumpName(BinaryStateLump.CorestateText, "CoreText.txt");
|
|
||||||
AddLumpName(BinaryStateLump.Movieheader, "Header.txt");
|
|
||||||
|
|
||||||
// Only for movies they probably shoudln't be leaching this stuff
|
|
||||||
AddLumpName(BinaryStateLump.Comments, "Comments.txt");
|
|
||||||
AddLumpName(BinaryStateLump.Subtitles, "Subtitles.txt");
|
|
||||||
AddLumpName(BinaryStateLump.SyncSettings, "SyncSettings.json");
|
|
||||||
|
|
||||||
// TasMovie
|
|
||||||
AddLumpName(BinaryStateLump.LagLog, "LagLog");
|
|
||||||
AddLumpName(BinaryStateLump.StateHistory, "GreenZone");
|
|
||||||
AddLumpName(BinaryStateLump.StateHistorySettings, "GreenZoneSettings.txt");
|
|
||||||
AddLumpName(BinaryStateLump.Markers, "Markers.txt");
|
|
||||||
AddLumpName(BinaryStateLump.ClientSettings, "ClientSettings.json");
|
|
||||||
AddLumpName(BinaryStateLump.VerificationLog, "VerificationLog.txt");
|
|
||||||
AddLumpName(BinaryStateLump.UserData, "UserData.txt");
|
|
||||||
AddLumpName(BinaryStateLump.Branches, "Branches");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetReadName(BinaryStateLump lump)
|
protected BinaryStateLump() { }
|
||||||
|
|
||||||
|
static BinaryStateLump()
|
||||||
{
|
{
|
||||||
return ReadNames[lump];
|
foreach (var prop in typeof(BinaryStateLump).GetProperties(BindingFlags.Public | BindingFlags.Static))
|
||||||
|
{
|
||||||
|
string name = prop.GetCustomAttributes(false).OfType<NameAttribute>().Single().Name;
|
||||||
|
object value = new BinaryStateLump(name);
|
||||||
|
prop.SetValue(null, value, null);
|
||||||
}
|
}
|
||||||
public static string GetWriteName(BinaryStateLump lump)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// describes a BinaryStateLump virtual name that has a numerical index
|
||||||
|
/// </summary>
|
||||||
|
public class IndexedStateLump : BinaryStateLump
|
||||||
{
|
{
|
||||||
return WriteNames[lump];
|
private BinaryStateLump _root;
|
||||||
|
private int _idx;
|
||||||
|
public IndexedStateLump(BinaryStateLump root)
|
||||||
|
{
|
||||||
|
_root = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Increment()
|
||||||
|
{
|
||||||
|
_idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ReadName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return base.ReadName + _idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string WriteName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string fn = Path.GetFileNameWithoutExtension(base.WriteName);
|
||||||
|
string ext = Path.GetExtension(base.WriteName);
|
||||||
|
if (!string.IsNullOrEmpty(ext))
|
||||||
|
ext = ext.Substring(1);
|
||||||
|
return string.Format("{0}{1}.{2}", fn, _idx, ext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,9 +223,8 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
public bool HasLump(BinaryStateLump lump)
|
public bool HasLump(BinaryStateLump lump)
|
||||||
{
|
{
|
||||||
string name = BinaryStateFileNames.GetReadName(lump);
|
|
||||||
ZipEntry e;
|
ZipEntry e;
|
||||||
return _entriesbyname.TryGetValue(name, out e);
|
return _entriesbyname.TryGetValue(lump.ReadName, out e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -185,9 +236,8 @@ namespace BizHawk.Client.Common
|
||||||
/// <returns>true if callback was called and stream was loaded</returns>
|
/// <returns>true if callback was called and stream was loaded</returns>
|
||||||
public bool GetLump(BinaryStateLump lump, bool abort, Action<Stream, long> callback)
|
public bool GetLump(BinaryStateLump lump, bool abort, Action<Stream, long> callback)
|
||||||
{
|
{
|
||||||
string name = BinaryStateFileNames.GetReadName(lump);
|
|
||||||
ZipEntry e;
|
ZipEntry e;
|
||||||
if (_entriesbyname.TryGetValue(name, out e))
|
if (_entriesbyname.TryGetValue(lump.ReadName, out e))
|
||||||
{
|
{
|
||||||
using (var zs = _zip.GetInputStream(e))
|
using (var zs = _zip.GetInputStream(e))
|
||||||
{
|
{
|
||||||
|
@ -199,7 +249,7 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
if (abort)
|
if (abort)
|
||||||
{
|
{
|
||||||
throw new Exception("Essential zip section not found: " + name);
|
throw new Exception("Essential zip section not found: " + lump.ReadName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -279,8 +329,7 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
public void PutLump(BinaryStateLump lump, Action<Stream> callback)
|
public void PutLump(BinaryStateLump lump, Action<Stream> callback)
|
||||||
{
|
{
|
||||||
var name = BinaryStateFileNames.GetWriteName(lump);
|
_zip.WriteItem(lump.WriteName, callback);
|
||||||
_zip.WriteItem(name, callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PutLump(BinaryStateLump lump, Action<BinaryWriter> callback)
|
public void PutLump(BinaryStateLump lump, Action<BinaryWriter> callback)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
using System.Collections;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace BizHawk.Client.Common
|
namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
|
@ -17,14 +19,110 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
private List<TasBranch> Branches = new List<TasBranch>();
|
private List<TasBranch> Branches = new List<TasBranch>();
|
||||||
|
|
||||||
public void Save(BinaryWriter bw)
|
public void Save(BinaryStateSaver bs)
|
||||||
{
|
{
|
||||||
|
var nheader = new IndexedStateLump(BinaryStateLump.BranchHeader);
|
||||||
}
|
var ncore = new IndexedStateLump(BinaryStateLump.BranchCoreData);
|
||||||
|
var ninput = new IndexedStateLump(BinaryStateLump.BranchInputLog);
|
||||||
public void Load(BinaryReader br, long length)
|
var nframebuffer = new IndexedStateLump(BinaryStateLump.BranchFrameBuffer);
|
||||||
|
var nlaglog = new IndexedStateLump(BinaryStateLump.BranchLagLog);
|
||||||
|
foreach (var b in Branches)
|
||||||
{
|
{
|
||||||
|
bs.PutLump(nheader, delegate(TextWriter tw)
|
||||||
|
{
|
||||||
|
// if this header needs more stuff in it, handle it sensibly
|
||||||
|
tw.WriteLine(JsonConvert.SerializeObject(new { Frame = b.Frame }));
|
||||||
|
});
|
||||||
|
bs.PutLump(ncore, delegate(Stream s)
|
||||||
|
{
|
||||||
|
s.Write(b.CoreData, 0, b.CoreData.Length);
|
||||||
|
});
|
||||||
|
bs.PutLump(ninput, delegate(TextWriter tw)
|
||||||
|
{
|
||||||
|
foreach (var line in b.InputLog)
|
||||||
|
tw.WriteLine(line);
|
||||||
|
});
|
||||||
|
bs.PutLump(nframebuffer, delegate(Stream s)
|
||||||
|
{
|
||||||
|
// todo: do we want to do something more clever here?
|
||||||
|
byte[] buff = new byte[2048];
|
||||||
|
var src = b.OSDFrameBuffer;
|
||||||
|
for (int i = 0; i < src.Length; i += 512)
|
||||||
|
{
|
||||||
|
int n = Math.Min(512, src.Length - i);
|
||||||
|
Buffer.BlockCopy(src, i * 4, buff, 0, n * 4);
|
||||||
|
s.Write(buff, 0, n * 4);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
bs.PutLump(nframebuffer, delegate(BinaryWriter bw)
|
||||||
|
{
|
||||||
|
b.LagLog.Save(bw);
|
||||||
|
});
|
||||||
|
|
||||||
|
nheader.Increment();
|
||||||
|
ncore.Increment();
|
||||||
|
ninput.Increment();
|
||||||
|
nframebuffer.Increment();
|
||||||
|
nlaglog.Increment();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Load(BinaryStateLoader bl)
|
||||||
|
{
|
||||||
|
var nheader = new IndexedStateLump(BinaryStateLump.BranchHeader);
|
||||||
|
var ncore = new IndexedStateLump(BinaryStateLump.BranchCoreData);
|
||||||
|
var ninput = new IndexedStateLump(BinaryStateLump.BranchInputLog);
|
||||||
|
var nframebuffer = new IndexedStateLump(BinaryStateLump.BranchFrameBuffer);
|
||||||
|
var nlaglog = new IndexedStateLump(BinaryStateLump.BranchLagLog);
|
||||||
|
|
||||||
|
Branches.Clear();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var b = new TasBranch();
|
||||||
|
|
||||||
|
if (!bl.GetLump(nheader, false, delegate(TextReader tr)
|
||||||
|
{
|
||||||
|
b.Frame = (int)((dynamic)JsonConvert.DeserializeObject(tr.ReadLine())).Frame;
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bl.GetLump(ncore, true, delegate(Stream s, long length)
|
||||||
|
{
|
||||||
|
b.CoreData = new byte[length];
|
||||||
|
s.Read(b.CoreData, 0, b.CoreData.Length);
|
||||||
|
});
|
||||||
|
|
||||||
|
bl.GetLump(ninput, true, delegate(TextReader tr)
|
||||||
|
{
|
||||||
|
b.InputLog = new List<string>();
|
||||||
|
string line;
|
||||||
|
while ((line = tr.ReadLine()) != null)
|
||||||
|
b.InputLog.Add(line);
|
||||||
|
});
|
||||||
|
|
||||||
|
bl.GetLump(nframebuffer, true, delegate(Stream s, long length)
|
||||||
|
{
|
||||||
|
int[] dst = new int[length / 4];
|
||||||
|
byte[] buff = new byte[2048];
|
||||||
|
for (int i = 0; i < dst.Length; i++)
|
||||||
|
{
|
||||||
|
int n = Math.Min(512, dst.Length - i);
|
||||||
|
s.Read(buff, 0, n * 4);
|
||||||
|
Buffer.BlockCopy(buff, 0, dst, i * 4, n * 4);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bl.GetLump(nlaglog, true, delegate(BinaryReader br)
|
||||||
|
{
|
||||||
|
b.LagLog = new TasLagLog();
|
||||||
|
b.LagLog.Load(br);
|
||||||
|
});
|
||||||
|
|
||||||
|
Branches.Add(b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,7 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
if (Branches.Any())
|
if (Branches.Any())
|
||||||
{
|
{
|
||||||
bs.PutLump(BinaryStateLump.Branches, (BinaryWriter bw) => Branches.Save(bw));
|
Branches.Save(bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReportProgress(PROGRESS_STEP);
|
ReportProgress(PROGRESS_STEP);
|
||||||
|
@ -270,13 +270,7 @@ namespace BizHawk.Client.Common
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bl.HasLump(BinaryStateLump.Branches))
|
Branches.Load(bl);
|
||||||
{
|
|
||||||
bl.GetLump(BinaryStateLump.Branches, true, delegate(BinaryReader br, long length)
|
|
||||||
{
|
|
||||||
Branches.Load(br, length);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Changes = false;
|
Changes = false;
|
||||||
|
|
Loading…
Reference in New Issue