add an IStatable extension method that will return a byte array that's safe to hold on to, but isn't optimized for speed, to be used in basic situations where we are making movies from savestate or getting a savestate length

This commit is contained in:
adelikat 2020-05-17 10:08:00 -05:00
parent 0154222737
commit 04aab3c41b
6 changed files with 22 additions and 8 deletions

View File

@ -47,7 +47,7 @@ namespace BizHawk.Client.Common
_decay = new StateManagerDecay(_movie, this); _decay = new StateManagerDecay(_movie, this);
_expectedStateSize = (ulong)Core.SaveStateBinary().Length; _expectedStateSize = (ulong)Core.CloneSavestate().Length; // TODO: why do we store this in a ulong?
if (_expectedStateSize == 0) if (_expectedStateSize == 0)
{ {
throw new InvalidOperationException("Savestate size can not be zero!"); throw new InvalidOperationException("Savestate size can not be zero!");

View File

@ -42,7 +42,7 @@ namespace BizHawk.Client.EmuHawk
RewindSpeedNumeric.Value = _config.Rewind.SpeedMultiplier; RewindSpeedNumeric.Value = _config.Rewind.SpeedMultiplier;
DiskBufferCheckbox.Checked = _config.Rewind.OnDisk; DiskBufferCheckbox.Checked = _config.Rewind.OnDisk;
RewindIsThreadedCheckbox.Checked = _config.Rewind.IsThreaded; RewindIsThreadedCheckbox.Checked = _config.Rewind.IsThreaded;
_stateSize = _statableCore.SaveStateBinary().Length; _stateSize = _statableCore.CloneSavestate().Length;
BufferSizeUpDown.Value = Math.Max(_config.Rewind.BufferSize, BufferSizeUpDown.Minimum); BufferSizeUpDown.Value = Math.Max(_config.Rewind.BufferSize, BufferSizeUpDown.Minimum);
_mediumStateSize = _config.Rewind.MediumStateSize; _mediumStateSize = _config.Rewind.MediumStateSize;

View File

@ -109,7 +109,7 @@ namespace BizHawk.Client.EmuHawk
if (_config.SaveStateType == SaveStateTypeE.Binary) if (_config.SaveStateType == SaveStateTypeE.Binary)
{ {
movieToRecord.BinarySavestate = (byte[])core.SaveStateBinary().Clone(); movieToRecord.BinarySavestate = core.CloneSavestate();
} }
else else
{ {

View File

@ -82,7 +82,7 @@ namespace BizHawk.Client.EmuHawk
private void MemStateGapDivider_ValueChanged(object sender, EventArgs e) private void MemStateGapDivider_ValueChanged(object sender, EventArgs e)
{ {
int val = (int)(Statable.SaveStateBinary().Length / MemStateGapDividerNumeric.Value / 1024); int val = (int)(Statable.CloneSavestate().Length / MemStateGapDividerNumeric.Value / 1024);
if (val <= 1) if (val <= 1)
MemStateGapDividerNumeric.Maximum = MemStateGapDividerNumeric.Value; MemStateGapDividerNumeric.Maximum = MemStateGapDividerNumeric.Value;

View File

@ -7,6 +7,7 @@ using System.Windows.Forms;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Client.Common.MovieConversionExtensions; using BizHawk.Client.Common.MovieConversionExtensions;
using BizHawk.Client.EmuHawk.ToolExtensions; using BizHawk.Client.EmuHawk.ToolExtensions;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -38,10 +39,8 @@ namespace BizHawk.Client.EmuHawk
{ {
if (AskSaveChanges()) if (AskSaveChanges())
{ {
int index = Emulator.Frame;
var newProject = CurrentTasMovie.ConvertToSavestateAnchoredMovie( var newProject = CurrentTasMovie.ConvertToSavestateAnchoredMovie(
index, (byte[])StatableEmulator.SaveStateBinary().Clone()); Emulator.Frame, StatableEmulator.CloneSavestate());
MainForm.PauseEmulator(); MainForm.PauseEmulator();
LoadFile(new FileInfo(newProject.Filename), true); LoadFile(new FileInfo(newProject.Filename), true);
@ -752,7 +751,7 @@ namespace BizHawk.Client.EmuHawk
if (CurrentTasMovie.TasStateManager.HasState(Emulator.Frame)) if (CurrentTasMovie.TasStateManager.HasState(Emulator.Frame))
{ {
byte[] state = (byte[])StatableEmulator.SaveStateBinary().Clone(); byte[] state = StatableEmulator.CloneSavestate();
byte[] greenZone = CurrentTasMovie.TasStateManager[Emulator.Frame]; byte[] greenZone = CurrentTasMovie.TasStateManager[Emulator.Frame];
if (!state.SequenceEqual(greenZone)) if (!state.SequenceEqual(greenZone))

View File

@ -87,5 +87,20 @@ namespace BizHawk.Emulation.Common
using var br = new BinaryReader(ms); using var br = new BinaryReader(ms);
core.LoadStateBinary(br); core.LoadStateBinary(br);
} }
/// <summary>
/// Creates a byte array copy of the core's current state
/// This creates a new buffer, and should not be used in performance sensitive situations
/// </summary>
public static byte[] CloneSavestate(this IStatable core)
{
using var ms = new MemoryStream();
using var bw = new BinaryWriter(ms);
core.SaveStateBinary(bw);
bw.Flush();
var stateBuffer = ms.ToArray();
bw.Close();
return stateBuffer;
}
} }
} }