rewind: work with variable length savestates without shitting a brick. this won't give good performance, though

This commit is contained in:
goyuken 2012-10-10 15:04:13 +00:00
parent b28b677be2
commit f32f74eb1d
1 changed files with 104 additions and 74 deletions

View File

@ -39,12 +39,18 @@ namespace BizHawk.MultiClient
void CaptureRewindState64K()
{
byte[] CurrentState = Global.Emulator.SaveStateBinary();
if (CurrentState.Length != LastState.Length)
throw new System.Exception(string.Format("Rewind error: Savestate size mismatch:{0} old {1} new", LastState.Length, CurrentState.Length));
int beginChangeSequence = -1;
bool inChangeSequence = false;
var ms = new MemoryStream();
var writer = new BinaryWriter(ms);
if (CurrentState.Length != LastState.Length)
{
writer.Write(true); // full state
writer.Write(CurrentState);
}
else
{
writer.Write(false); // delta state
for (int i = 0; i < CurrentState.Length; i++)
{
if (inChangeSequence == false)
@ -76,6 +82,7 @@ namespace BizHawk.MultiClient
inChangeSequence = false;
}
}
}
LastState = CurrentState;
ms.Position = 0;
RewindBuf.Push(ms);
@ -85,12 +92,18 @@ namespace BizHawk.MultiClient
void CaptureRewindStateLarge()
{
byte[] CurrentState = Global.Emulator.SaveStateBinary();
if (CurrentState.Length != LastState.Length)
throw new System.Exception(string.Format("Rewind error: Savestate size mismatch:{0} old {1} new", LastState.Length, CurrentState.Length));
int beginChangeSequence = -1;
bool inChangeSequence = false;
var ms = new MemoryStream();
var writer = new BinaryWriter(ms);
if (CurrentState.Length != LastState.Length)
{
writer.Write(true); // full state
writer.Write(CurrentState);
}
else
{
writer.Write(false); // delta state
for (int i = 0; i < CurrentState.Length; i++)
{
if (inChangeSequence == false)
@ -122,6 +135,7 @@ namespace BizHawk.MultiClient
inChangeSequence = false;
}
}
}
LastState = CurrentState;
ms.Position = 0;
RewindBuf.Push(ms);
@ -131,6 +145,13 @@ namespace BizHawk.MultiClient
{
var ms = RewindBuf.Pop();
var reader = new BinaryReader(ms);
bool fullstate = reader.ReadBoolean();
if (fullstate)
{
Global.Emulator.LoadStateBinary(reader);
}
else
{
var output = new MemoryStream(LastState);
while (ms.Position < ms.Length - 1)
{
@ -144,11 +165,19 @@ namespace BizHawk.MultiClient
output.Position = 0;
Global.Emulator.LoadStateBinary(new BinaryReader(output));
}
}
void RewindLarge()
{
var ms = RewindBuf.Pop();
var reader = new BinaryReader(ms);
bool fullstate = reader.ReadBoolean();
if (fullstate)
{
Global.Emulator.LoadStateBinary(reader);
}
else
{
var output = new MemoryStream(LastState);
while (ms.Position < ms.Length - 1)
{
@ -162,6 +191,7 @@ namespace BizHawk.MultiClient
output.Position = 0;
Global.Emulator.LoadStateBinary(new BinaryReader(output));
}
}
public void Rewind(int frames)
{