rewind: work with variable length savestates without shitting a brick. this won't give good performance, though
This commit is contained in:
parent
b28b677be2
commit
f32f74eb1d
|
@ -39,41 +39,48 @@ namespace BizHawk.MultiClient
|
||||||
void CaptureRewindState64K()
|
void CaptureRewindState64K()
|
||||||
{
|
{
|
||||||
byte[] CurrentState = Global.Emulator.SaveStateBinary();
|
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;
|
int beginChangeSequence = -1;
|
||||||
bool inChangeSequence = false;
|
bool inChangeSequence = false;
|
||||||
var ms = new MemoryStream();
|
var ms = new MemoryStream();
|
||||||
var writer = new BinaryWriter(ms);
|
var writer = new BinaryWriter(ms);
|
||||||
for (int i = 0; i < CurrentState.Length; i++)
|
if (CurrentState.Length != LastState.Length)
|
||||||
{
|
{
|
||||||
if (inChangeSequence == false)
|
writer.Write(true); // full state
|
||||||
|
writer.Write(CurrentState);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.Write(false); // delta state
|
||||||
|
for (int i = 0; i < CurrentState.Length; i++)
|
||||||
{
|
{
|
||||||
if (i >= LastState.Length)
|
if (inChangeSequence == false)
|
||||||
|
{
|
||||||
|
if (i >= LastState.Length)
|
||||||
|
continue;
|
||||||
|
if (CurrentState[i] == LastState[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
inChangeSequence = true;
|
||||||
|
beginChangeSequence = i;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i - beginChangeSequence == 254 || i == CurrentState.Length - 1)
|
||||||
|
{
|
||||||
|
writer.Write((byte)(i - beginChangeSequence + 1));
|
||||||
|
writer.Write((ushort)beginChangeSequence);
|
||||||
|
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence + 1);
|
||||||
|
inChangeSequence = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (CurrentState[i] == LastState[i])
|
if (CurrentState[i] == LastState[i])
|
||||||
continue;
|
{
|
||||||
|
writer.Write((byte)(i - beginChangeSequence));
|
||||||
inChangeSequence = true;
|
writer.Write((ushort)beginChangeSequence);
|
||||||
beginChangeSequence = i;
|
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence);
|
||||||
continue;
|
inChangeSequence = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i - beginChangeSequence == 254 || i == CurrentState.Length - 1)
|
|
||||||
{
|
|
||||||
writer.Write((byte)(i - beginChangeSequence + 1));
|
|
||||||
writer.Write((ushort)beginChangeSequence);
|
|
||||||
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence + 1);
|
|
||||||
inChangeSequence = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CurrentState[i] == LastState[i])
|
|
||||||
{
|
|
||||||
writer.Write((byte)(i - beginChangeSequence));
|
|
||||||
writer.Write((ushort)beginChangeSequence);
|
|
||||||
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence);
|
|
||||||
inChangeSequence = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LastState = CurrentState;
|
LastState = CurrentState;
|
||||||
|
@ -85,41 +92,48 @@ namespace BizHawk.MultiClient
|
||||||
void CaptureRewindStateLarge()
|
void CaptureRewindStateLarge()
|
||||||
{
|
{
|
||||||
byte[] CurrentState = Global.Emulator.SaveStateBinary();
|
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;
|
int beginChangeSequence = -1;
|
||||||
bool inChangeSequence = false;
|
bool inChangeSequence = false;
|
||||||
var ms = new MemoryStream();
|
var ms = new MemoryStream();
|
||||||
var writer = new BinaryWriter(ms);
|
var writer = new BinaryWriter(ms);
|
||||||
for (int i = 0; i < CurrentState.Length; i++)
|
if (CurrentState.Length != LastState.Length)
|
||||||
{
|
{
|
||||||
if (inChangeSequence == false)
|
writer.Write(true); // full state
|
||||||
|
writer.Write(CurrentState);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.Write(false); // delta state
|
||||||
|
for (int i = 0; i < CurrentState.Length; i++)
|
||||||
{
|
{
|
||||||
if (i >= LastState.Length)
|
if (inChangeSequence == false)
|
||||||
|
{
|
||||||
|
if (i >= LastState.Length)
|
||||||
|
continue;
|
||||||
|
if (CurrentState[i] == LastState[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
inChangeSequence = true;
|
||||||
|
beginChangeSequence = i;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i - beginChangeSequence == 254 || i == CurrentState.Length - 1)
|
||||||
|
{
|
||||||
|
writer.Write((byte)(i - beginChangeSequence + 1));
|
||||||
|
writer.Write(beginChangeSequence);
|
||||||
|
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence + 1);
|
||||||
|
inChangeSequence = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (CurrentState[i] == LastState[i])
|
if (CurrentState[i] == LastState[i])
|
||||||
continue;
|
{
|
||||||
|
writer.Write((byte)(i - beginChangeSequence));
|
||||||
inChangeSequence = true;
|
writer.Write(beginChangeSequence);
|
||||||
beginChangeSequence = i;
|
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence);
|
||||||
continue;
|
inChangeSequence = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i - beginChangeSequence == 254 || i == CurrentState.Length - 1)
|
|
||||||
{
|
|
||||||
writer.Write((byte)(i - beginChangeSequence + 1));
|
|
||||||
writer.Write(beginChangeSequence);
|
|
||||||
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence + 1);
|
|
||||||
inChangeSequence = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CurrentState[i] == LastState[i])
|
|
||||||
{
|
|
||||||
writer.Write((byte)(i - beginChangeSequence));
|
|
||||||
writer.Write(beginChangeSequence);
|
|
||||||
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence);
|
|
||||||
inChangeSequence = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LastState = CurrentState;
|
LastState = CurrentState;
|
||||||
|
@ -131,36 +145,52 @@ namespace BizHawk.MultiClient
|
||||||
{
|
{
|
||||||
var ms = RewindBuf.Pop();
|
var ms = RewindBuf.Pop();
|
||||||
var reader = new BinaryReader(ms);
|
var reader = new BinaryReader(ms);
|
||||||
var output = new MemoryStream(LastState);
|
bool fullstate = reader.ReadBoolean();
|
||||||
while (ms.Position < ms.Length - 1)
|
if (fullstate)
|
||||||
{
|
{
|
||||||
byte len = reader.ReadByte();
|
Global.Emulator.LoadStateBinary(reader);
|
||||||
ushort offset = reader.ReadUInt16();
|
}
|
||||||
output.Position = offset;
|
else
|
||||||
output.Write(ms.GetBuffer(), (int)ms.Position, len);
|
{
|
||||||
ms.Position += len;
|
var output = new MemoryStream(LastState);
|
||||||
|
while (ms.Position < ms.Length - 1)
|
||||||
|
{
|
||||||
|
byte len = reader.ReadByte();
|
||||||
|
ushort offset = reader.ReadUInt16();
|
||||||
|
output.Position = offset;
|
||||||
|
output.Write(ms.GetBuffer(), (int)ms.Position, len);
|
||||||
|
ms.Position += len;
|
||||||
|
}
|
||||||
|
reader.Close();
|
||||||
|
output.Position = 0;
|
||||||
|
Global.Emulator.LoadStateBinary(new BinaryReader(output));
|
||||||
}
|
}
|
||||||
reader.Close();
|
|
||||||
output.Position = 0;
|
|
||||||
Global.Emulator.LoadStateBinary(new BinaryReader(output));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RewindLarge()
|
void RewindLarge()
|
||||||
{
|
{
|
||||||
var ms = RewindBuf.Pop();
|
var ms = RewindBuf.Pop();
|
||||||
var reader = new BinaryReader(ms);
|
var reader = new BinaryReader(ms);
|
||||||
var output = new MemoryStream(LastState);
|
bool fullstate = reader.ReadBoolean();
|
||||||
while (ms.Position < ms.Length - 1)
|
if (fullstate)
|
||||||
{
|
{
|
||||||
byte len = reader.ReadByte();
|
Global.Emulator.LoadStateBinary(reader);
|
||||||
int offset = reader.ReadInt32();
|
}
|
||||||
output.Position = offset;
|
else
|
||||||
output.Write(ms.GetBuffer(), (int)ms.Position, len);
|
{
|
||||||
ms.Position += len;
|
var output = new MemoryStream(LastState);
|
||||||
|
while (ms.Position < ms.Length - 1)
|
||||||
|
{
|
||||||
|
byte len = reader.ReadByte();
|
||||||
|
int offset = reader.ReadInt32();
|
||||||
|
output.Position = offset;
|
||||||
|
output.Write(ms.GetBuffer(), (int)ms.Position, len);
|
||||||
|
ms.Position += len;
|
||||||
|
}
|
||||||
|
reader.Close();
|
||||||
|
output.Position = 0;
|
||||||
|
Global.Emulator.LoadStateBinary(new BinaryReader(output));
|
||||||
}
|
}
|
||||||
reader.Close();
|
|
||||||
output.Position = 0;
|
|
||||||
Global.Emulator.LoadStateBinary(new BinaryReader(output));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Rewind(int frames)
|
public void Rewind(int frames)
|
||||||
|
|
Loading…
Reference in New Issue