add some real versioning to binary savestates. also make binary savestates able to store text savestate data as well, so they're more accurately called "zip" savestates. at the moment, zip savestates are always binary, but the code exists for future use.

This commit is contained in:
goyuken 2013-12-07 21:23:23 +00:00
parent ba2c345608
commit d0cb81fbfc
2 changed files with 54 additions and 7 deletions

View File

@ -10,9 +10,12 @@ namespace BizHawk.Client.Common
public const string Corestate = "Core"; public const string Corestate = "Core";
public const string Framebuffer = "Framebuffer"; public const string Framebuffer = "Framebuffer";
public const string Input = "Input Log"; public const string Input = "Input Log";
public const string CorestateText = "CoreText";
} }
/// <summary>
/// more accurately should be called ZipStateLoader, as it supports both text and binary core data
/// </summary>
public class BinaryStateLoader : IDisposable public class BinaryStateLoader : IDisposable
{ {
private bool isDisposed; private bool isDisposed;
@ -36,11 +39,25 @@ namespace BizHawk.Client.Common
} }
ZipFile zip; ZipFile zip;
Version ver;
private BinaryStateLoader() private BinaryStateLoader()
{ {
} }
private void ReadVersion(Stream s)
{
// the "BizState 1.0" tag contains an integer in it describing the sub version.
if (s.Length == 0)
ver = new Version(1, 0, 0); // except for the first release, which doesn't
else
{
StreamReader sr = new StreamReader(s);
ver = new Version(1, 0, int.Parse(sr.ReadLine()));
}
Console.WriteLine("Read a zipstate of version {0}", ver.ToString());
}
public static BinaryStateLoader LoadAndDetect(string Filename) public static BinaryStateLoader LoadAndDetect(string Filename)
{ {
BinaryStateLoader ret = new BinaryStateLoader(); BinaryStateLoader ret = new BinaryStateLoader();
@ -59,7 +76,7 @@ namespace BizHawk.Client.Common
{ {
ret.zip = new ZipFile(Filename); ret.zip = new ZipFile(Filename);
var e = ret.zip.GetEntry(BinaryStateFileNames.Versiontag); var e = ret.zip.GetEntry(BinaryStateFileNames.Versiontag);
if (e == null) if (!ret.GetFileByName(BinaryStateFileNames.Versiontag, false, ret.ReadVersion))
{ {
ret.zip.Close(); ret.zip.Close();
return null; return null;
@ -93,9 +110,11 @@ namespace BizHawk.Client.Common
} }
} }
public void GetCoreState(Action<Stream> callback) public void GetCoreState(Action<Stream> callbackBinary, Action<Stream> callbackText)
{ {
GetFileByName(BinaryStateFileNames.Corestate, true, callback); if (!GetFileByName(BinaryStateFileNames.Corestate, false, callbackBinary)
&& !GetFileByName(BinaryStateFileNames.CorestateText, false, callbackText))
throw new Exception("Couldn't find Binary or Text savestate");
} }
public bool GetFrameBuffer(Action<Stream> callback) public bool GetFrameBuffer(Action<Stream> callback)
@ -113,6 +132,13 @@ namespace BizHawk.Client.Common
{ {
private readonly ZipOutputStream zip; private readonly ZipOutputStream zip;
private void WriteVersion(Stream s)
{
StreamWriter sw = new StreamWriter(s);
sw.WriteLine("1"); // version 1.0.1
sw.Flush();
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@ -126,7 +152,7 @@ namespace BizHawk.Client.Common
}; };
zip.SetLevel(0); zip.SetLevel(0);
PutFileByName(BinaryStateFileNames.Versiontag, ss => { }); PutFileByName(BinaryStateFileNames.Versiontag, WriteVersion);
} }
void PutFileByName(string Name, Action<Stream> callback) void PutFileByName(string Name, Action<Stream> callback)
@ -137,11 +163,16 @@ namespace BizHawk.Client.Common
zip.CloseEntry(); zip.CloseEntry();
} }
public void PutCoreState(Action<Stream> callback) public void PutCoreStateBinary(Action<Stream> callback)
{ {
PutFileByName(BinaryStateFileNames.Corestate, callback); PutFileByName(BinaryStateFileNames.Corestate, callback);
} }
public void PutCoreStateText(Action<Stream> callback)
{
PutFileByName(BinaryStateFileNames.CorestateText, callback);
}
public void PutFrameBuffer(Action<Stream> callback) public void PutFrameBuffer(Action<Stream> callback)
{ {
PutFileByName(BinaryStateFileNames.Framebuffer, callback); PutFileByName(BinaryStateFileNames.Framebuffer, callback);

View File

@ -29,13 +29,24 @@ namespace BizHawk.Client.Common
using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write)) using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
using (BinaryStateSaver bs = new BinaryStateSaver(fs)) using (BinaryStateSaver bs = new BinaryStateSaver(fs))
{ {
bs.PutCoreState( #if true
bs.PutCoreStateBinary(
delegate(Stream s) delegate(Stream s)
{ {
BinaryWriter bw = new BinaryWriter(s); BinaryWriter bw = new BinaryWriter(s);
Global.Emulator.SaveStateBinary(bw); Global.Emulator.SaveStateBinary(bw);
bw.Flush(); bw.Flush();
}); });
#else
// this would put text states inside the zipfile
bs.PutCoreStateText(
delegate(Stream s)
{
StreamWriter sw = new StreamWriter(s);
Global.Emulator.SaveStateText(sw);
sw.Flush();
});
#endif
if (Global.Config.SaveScreenshotWithStates) if (Global.Config.SaveScreenshotWithStates)
{ {
bs.PutFrameBuffer( bs.PutFrameBuffer(
@ -92,6 +103,11 @@ namespace BizHawk.Client.Common
{ {
BinaryReader br = new BinaryReader(s); BinaryReader br = new BinaryReader(s);
Global.Emulator.LoadStateBinary(br); Global.Emulator.LoadStateBinary(br);
},
delegate(Stream s)
{
StreamReader sr = new StreamReader(s);
Global.Emulator.LoadStateText(sr);
}); });
bw.GetFrameBuffer( bw.GetFrameBuffer(