Break off savestate functionality from IEmulator into IStatable and refactor things accordingly. Still todo (a big todo): EmuHawk should gracefully handle a core that is not an IStatable by disabling functionality dependent upon it (Savestates, Rewind, Tastudio, etc)
This commit is contained in:
parent
230cd3fb6a
commit
76148ae111
|
@ -1,9 +1,10 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Common.BufferExtensions;
|
||||
using BizHawk.Common.IOExtensions;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
|
@ -11,22 +12,23 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public static void SaveStateFile(string filename, string name)
|
||||
{
|
||||
var core = Global.Emulator as IStatable;
|
||||
// the old method of text savestate save is now gone.
|
||||
// a text savestate is just like a binary savestate, but with a different core lump
|
||||
using (var bs = new BinaryStateSaver(filename))
|
||||
{
|
||||
if (Global.Config.SaveStateType == Config.SaveStateTypeE.Text ||
|
||||
(Global.Config.SaveStateType == Config.SaveStateTypeE.Default && !Global.Emulator.BinarySaveStatesPreferred))
|
||||
(Global.Config.SaveStateType == Config.SaveStateTypeE.Default && !core.BinarySaveStatesPreferred))
|
||||
{
|
||||
// text savestate format
|
||||
using (new SimpleTime("Save Core"))
|
||||
bs.PutLump(BinaryStateLump.CorestateText, (tw) => Global.Emulator.SaveStateText(tw));
|
||||
bs.PutLump(BinaryStateLump.CorestateText, (tw) => core.SaveStateText(tw));
|
||||
}
|
||||
else
|
||||
{
|
||||
// binary core lump format
|
||||
using (new SimpleTime("Save Core"))
|
||||
bs.PutLump(BinaryStateLump.Corestate, bw => Global.Emulator.SaveStateBinary(bw));
|
||||
bs.PutLump(BinaryStateLump.Corestate, bw => core.SaveStateBinary(bw));
|
||||
}
|
||||
|
||||
if (Global.Config.SaveScreenshotWithStates)
|
||||
|
@ -75,6 +77,8 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public static bool LoadStateFile(string path, string name)
|
||||
{
|
||||
var core = Global.Emulator as IStatable;
|
||||
|
||||
// try to detect binary first
|
||||
var bl = BinaryStateLoader.LoadAndDetect(path);
|
||||
if (bl != null)
|
||||
|
@ -99,7 +103,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
using (new SimpleTime("Load Core"))
|
||||
bl.GetCoreState(br => Global.Emulator.LoadStateBinary(br), tr => Global.Emulator.LoadStateText(tr));
|
||||
bl.GetCoreState(br => core.LoadStateBinary(br), tr => core.LoadStateText(tr));
|
||||
|
||||
bl.GetLump(BinaryStateLump.Framebuffer, false, PopulateFramebuffer);
|
||||
}
|
||||
|
@ -120,7 +124,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
using (var reader = new StreamReader(path))
|
||||
{
|
||||
Global.Emulator.LoadStateText(reader);
|
||||
core.LoadStateText(reader);
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
|
@ -24,7 +25,15 @@ namespace BizHawk.Client.Common
|
|||
public TasMovie(string path, bool startsFromSavestate = false) : base(path)
|
||||
{
|
||||
// TODO: how to call the default constructor AND the base(path) constructor? And is base(path) calling base() ?
|
||||
StateManager = new TasStateManager(this);
|
||||
|
||||
if (!Global.Emulator.HasSavestates())
|
||||
{
|
||||
throw new InvalidOperationException("Cannot create a TasMovie against a core that does not implement IStatable");
|
||||
}
|
||||
|
||||
var core = (IStatable)Global.Emulator;
|
||||
|
||||
StateManager = new TasStateManager(this, core);
|
||||
Header[HeaderKeys.MOVIEVERSION] = "BizHawk v2.0 Tasproj v1.0";
|
||||
Markers = new TasMovieMarkerList(this);
|
||||
Markers.CollectionChanged += Markers_CollectionChanged;
|
||||
|
@ -34,7 +43,14 @@ namespace BizHawk.Client.Common
|
|||
public TasMovie(bool startsFromSavestate = false)
|
||||
: base()
|
||||
{
|
||||
StateManager = new TasStateManager(this);
|
||||
if (!Global.Emulator.HasSavestates())
|
||||
{
|
||||
throw new InvalidOperationException("Cannot create a TasMovie against a core that does not implement IStatable");
|
||||
}
|
||||
|
||||
var core = (IStatable)Global.Emulator;
|
||||
|
||||
StateManager = new TasStateManager(this, core);
|
||||
Header[HeaderKeys.MOVIEVERSION] = "BizHawk v2.0 Tasproj v1.0";
|
||||
Markers = new TasMovieMarkerList(this);
|
||||
Markers.CollectionChanged += Markers_CollectionChanged;
|
||||
|
|
|
@ -5,6 +5,9 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -13,6 +16,7 @@ namespace BizHawk.Client.Common
|
|||
/// </summary>
|
||||
public class TasStateManager
|
||||
{
|
||||
private readonly IStatable Core;
|
||||
private readonly SortedList<int, byte[]> States = new SortedList<int, byte[]>();
|
||||
|
||||
private readonly TasMovie _movie;
|
||||
|
@ -40,17 +44,19 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
public TasStateManager(TasMovie movie)
|
||||
public TasStateManager(TasMovie movie, IStatable core)
|
||||
{
|
||||
_movie = movie;
|
||||
Core = core;
|
||||
|
||||
Settings = new TasStateManagerSettings(Global.Config.DefaultTasProjSettings);
|
||||
|
||||
var cap = Settings.Cap;
|
||||
|
||||
int limit = 0;
|
||||
if (Global.Emulator != null)
|
||||
if (!Global.Emulator.IsNull())
|
||||
{
|
||||
_expectedStateSize = Global.Emulator.SaveStateBinary().Length;
|
||||
_expectedStateSize = Core.SaveStateBinary().Length;
|
||||
|
||||
if (_expectedStateSize > 0)
|
||||
{
|
||||
|
@ -131,7 +137,7 @@ namespace BizHawk.Client.Common
|
|||
if (shouldCapture)
|
||||
{
|
||||
var frame = Global.Emulator.Frame;
|
||||
var state = (byte[])Global.Emulator.SaveStateBinary().Clone();
|
||||
var state = (byte[])Core.SaveStateBinary().Clone();
|
||||
|
||||
if (States.ContainsKey(frame))
|
||||
{
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
public class Rewinder
|
||||
|
@ -51,78 +54,84 @@ namespace BizHawk.Client.Common
|
|||
// TOOD: this should not be parameterless?! It is only possible due to passing a static context in
|
||||
public void CaptureRewindState()
|
||||
{
|
||||
if (_rewindImpossible)
|
||||
if (Global.Emulator.HasSavestates())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_rewindImpossible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_lastState == null)
|
||||
{
|
||||
DoRewindSettings();
|
||||
}
|
||||
if (_lastState == null)
|
||||
{
|
||||
DoRewindSettings();
|
||||
}
|
||||
|
||||
// log a frame
|
||||
if (_lastState != null && Global.Emulator.Frame % _rewindFrequency == 0)
|
||||
{
|
||||
_rewindThread.Capture(Global.Emulator.SaveStateBinary());
|
||||
// log a frame
|
||||
if (_lastState != null && Global.Emulator.Frame % _rewindFrequency == 0)
|
||||
{
|
||||
_rewindThread.Capture(((IStatable)Global.Emulator).SaveStateBinary());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DoRewindSettings()
|
||||
{
|
||||
// This is the first frame. Capture the state, and put it in LastState for future deltas to be compared against.
|
||||
_lastState = (byte[])Global.Emulator.SaveStateBinary().Clone();
|
||||
if (Global.Emulator.HasSavestates())
|
||||
{
|
||||
// This is the first frame. Capture the state, and put it in LastState for future deltas to be compared against.
|
||||
_lastState = (byte[]) ((IStatable)Global.Emulator).SaveStateBinary().Clone();
|
||||
|
||||
int state_size;
|
||||
if (_lastState.Length >= Global.Config.Rewind_LargeStateSize)
|
||||
{
|
||||
SetRewindParams(Global.Config.RewindEnabledLarge, Global.Config.RewindFrequencyLarge);
|
||||
state_size = 3;
|
||||
}
|
||||
else if (_lastState.Length >= Global.Config.Rewind_MediumStateSize)
|
||||
{
|
||||
SetRewindParams(Global.Config.RewindEnabledMedium, Global.Config.RewindFrequencyMedium);
|
||||
state_size = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRewindParams(Global.Config.RewindEnabledSmall, Global.Config.RewindFrequencySmall);
|
||||
state_size = 1;
|
||||
}
|
||||
|
||||
var rewind_enabled = false;
|
||||
if (state_size == 1)
|
||||
{
|
||||
rewind_enabled = Global.Config.RewindEnabledSmall;
|
||||
}
|
||||
else if (state_size == 2)
|
||||
{
|
||||
rewind_enabled = Global.Config.RewindEnabledMedium;
|
||||
}
|
||||
else if (state_size == 3)
|
||||
{
|
||||
rewind_enabled = Global.Config.RewindEnabledLarge;
|
||||
}
|
||||
|
||||
_rewindDeltaEnable = Global.Config.Rewind_UseDelta;
|
||||
|
||||
if (rewind_enabled)
|
||||
{
|
||||
var cap = Global.Config.Rewind_BufferSize * (long)1024 * 1024;
|
||||
|
||||
if (_rewindBuffer != null)
|
||||
int state_size;
|
||||
if (_lastState.Length >= Global.Config.Rewind_LargeStateSize)
|
||||
{
|
||||
_rewindBuffer.Dispose();
|
||||
SetRewindParams(Global.Config.RewindEnabledLarge, Global.Config.RewindFrequencyLarge);
|
||||
state_size = 3;
|
||||
}
|
||||
else if (_lastState.Length >= Global.Config.Rewind_MediumStateSize)
|
||||
{
|
||||
SetRewindParams(Global.Config.RewindEnabledMedium, Global.Config.RewindFrequencyMedium);
|
||||
state_size = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRewindParams(Global.Config.RewindEnabledSmall, Global.Config.RewindFrequencySmall);
|
||||
state_size = 1;
|
||||
}
|
||||
|
||||
_rewindBuffer = new StreamBlobDatabase(Global.Config.Rewind_OnDisk, cap, BufferManage);
|
||||
|
||||
if (_rewindThread != null)
|
||||
var rewind_enabled = false;
|
||||
if (state_size == 1)
|
||||
{
|
||||
_rewindThread.Dispose();
|
||||
rewind_enabled = Global.Config.RewindEnabledSmall;
|
||||
}
|
||||
else if (state_size == 2)
|
||||
{
|
||||
rewind_enabled = Global.Config.RewindEnabledMedium;
|
||||
}
|
||||
else if (state_size == 3)
|
||||
{
|
||||
rewind_enabled = Global.Config.RewindEnabledLarge;
|
||||
}
|
||||
|
||||
_rewindThread = new RewindThreader(this, Global.Config.Rewind_IsThreaded);
|
||||
_rewindDeltaEnable = Global.Config.Rewind_UseDelta;
|
||||
|
||||
if (rewind_enabled)
|
||||
{
|
||||
var cap = Global.Config.Rewind_BufferSize * (long)1024 * 1024;
|
||||
|
||||
if (_rewindBuffer != null)
|
||||
{
|
||||
_rewindBuffer.Dispose();
|
||||
}
|
||||
|
||||
_rewindBuffer = new StreamBlobDatabase(Global.Config.Rewind_OnDisk, cap, BufferManage);
|
||||
|
||||
if (_rewindThread != null)
|
||||
{
|
||||
_rewindThread.Dispose();
|
||||
}
|
||||
|
||||
_rewindThread = new RewindThreader(this, Global.Config.Rewind_IsThreaded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,29 +355,32 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private void RewindDelta(bool isSmall)
|
||||
{
|
||||
var ms = _rewindBuffer.PopMemoryStream();
|
||||
var reader = new BinaryReader(ms);
|
||||
var fullstate = reader.ReadBoolean();
|
||||
if (fullstate)
|
||||
if (Global.Emulator.HasSavestates())
|
||||
{
|
||||
Global.Emulator.LoadStateBinary(reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
var output = new MemoryStream(_lastState);
|
||||
while (ms.Position < ms.Length)
|
||||
var ms = _rewindBuffer.PopMemoryStream();
|
||||
var reader = new BinaryReader(ms);
|
||||
var fullstate = reader.ReadBoolean();
|
||||
if (fullstate)
|
||||
{
|
||||
var len = reader.ReadByte();
|
||||
int offset = isSmall ? reader.ReadUInt16() : reader.ReadInt32();
|
||||
|
||||
output.Position = offset;
|
||||
output.Write(ms.GetBuffer(), (int)ms.Position, len);
|
||||
ms.Position += len;
|
||||
((IStatable)Global.Emulator).LoadStateBinary(reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
var output = new MemoryStream(_lastState);
|
||||
while (ms.Position < ms.Length)
|
||||
{
|
||||
var len = reader.ReadByte();
|
||||
int offset = isSmall ? reader.ReadUInt16() : reader.ReadInt32();
|
||||
|
||||
reader.Close();
|
||||
output.Position = 0;
|
||||
Global.Emulator.LoadStateBinary(new BinaryReader(output));
|
||||
output.Position = offset;
|
||||
output.Write(ms.GetBuffer(), (int)ms.Position, len);
|
||||
ms.Position += len;
|
||||
}
|
||||
|
||||
reader.Close();
|
||||
output.Position = 0;
|
||||
((IStatable)Global.Emulator).LoadStateBinary(new BinaryReader(output));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Windows.Forms;
|
|||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES;
|
||||
using BizHawk.Emulation.Cores.Nintendo.NES;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES9X;
|
||||
|
@ -46,15 +47,15 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
Global.Config.RecentMovies.Add(movie.Filename);
|
||||
|
||||
if (movie.StartsFromSavestate)
|
||||
if (Global.Emulator.HasSavestates() && movie.StartsFromSavestate)
|
||||
{
|
||||
if (movie.TextSavestate != null)
|
||||
{
|
||||
Global.Emulator.LoadStateText(new StringReader(movie.TextSavestate));
|
||||
(Global.Emulator as IStatable).LoadStateText(new StringReader(movie.TextSavestate));
|
||||
}
|
||||
else
|
||||
{
|
||||
Global.Emulator.LoadStateBinary(new BinaryReader(new MemoryStream(movie.BinarySavestate, false)));
|
||||
(Global.Emulator as IStatable).LoadStateBinary(new BinaryReader(new MemoryStream(movie.BinarySavestate, false)));
|
||||
}
|
||||
if (movie.SavestateFramebuffer != null)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Windows.Forms;
|
|||
using System.Drawing;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
@ -33,7 +34,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
DiskBufferCheckbox.Checked = Global.Config.Rewind_OnDisk;
|
||||
RewindIsThreadedCheckbox.Checked = Global.Config.Rewind_IsThreaded;
|
||||
_stateSize = Global.Emulator.SaveStateBinary().Length;
|
||||
_stateSize = ((IStatable)Global.Emulator).SaveStateBinary().Length;
|
||||
BufferSizeUpDown.Value = Global.Config.Rewind_BufferSize;
|
||||
|
||||
_mediumStateSize = Global.Config.Rewind_MediumStateSize;
|
||||
|
@ -295,7 +296,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
avg_state_size = Global.Emulator.SaveStateBinary().Length;
|
||||
avg_state_size = _stateSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Linq;
|
|||
|
||||
using BizHawk.Common.ReflectionExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Client.Common.MovieConversionExtensions;
|
||||
|
||||
|
@ -69,19 +70,21 @@ namespace BizHawk.Client.EmuHawk
|
|||
Directory.CreateDirectory(fileInfo.DirectoryName);
|
||||
}
|
||||
|
||||
if (StartFromCombo.SelectedItem.ToString() == "Now")
|
||||
if (StartFromCombo.SelectedItem.ToString() == "Now" && Global.Emulator.HasSavestates())
|
||||
{
|
||||
var core = Global.Emulator as IStatable;
|
||||
|
||||
movieToRecord.StartsFromSavestate = true;
|
||||
|
||||
if (Global.Emulator.BinarySaveStatesPreferred)
|
||||
if (core.BinarySaveStatesPreferred)
|
||||
{
|
||||
movieToRecord.BinarySavestate = (byte[])Global.Emulator.SaveStateBinary().Clone();
|
||||
movieToRecord.BinarySavestate = (byte[])core.SaveStateBinary().Clone();
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var sw = new StringWriter())
|
||||
{
|
||||
Global.Emulator.SaveStateText(sw);
|
||||
core.SaveStateText(sw);
|
||||
movieToRecord.TextSavestate = sw.ToString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
|
@ -23,7 +24,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void GreenzoneSettings_Load(object sender, EventArgs e)
|
||||
{
|
||||
_stateSizeMb = Global.Emulator.SaveStateBinary().Length / (decimal)1024 / (decimal)1024;
|
||||
_stateSizeMb = ((IStatable)Global.Emulator).SaveStateBinary().Length / (decimal)1024 / (decimal)1024;
|
||||
|
||||
SaveGreenzoneCheckbox.Checked = Settings.SaveGreenzone;
|
||||
CapacityNumeric.Value = Settings.Capacitymb == 0 ? 1 : Settings.Capacitymb < CapacityNumeric.Maximum ?
|
||||
|
|
|
@ -10,6 +10,7 @@ using BizHawk.Client.Common;
|
|||
using BizHawk.Client.Common.MovieConversionExtensions;
|
||||
using BizHawk.Client.EmuHawk.ToolExtensions;
|
||||
using BizHawk.Client.EmuHawk.WinFormExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
@ -507,7 +508,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
if (CurrentTasMovie.TasStateManager.HasState(frame))
|
||||
{
|
||||
var state = (byte[])Global.Emulator.SaveStateBinary().Clone();
|
||||
var state = (byte[])(((IStatable)Global.Emulator).SaveStateBinary().Clone());
|
||||
var greenzone = CurrentTasMovie.TasStateManager[frame];
|
||||
|
||||
if (!state.SequenceEqual(greenzone.Value))
|
||||
|
@ -749,7 +750,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
var newProject = CurrentTasMovie.ConvertToSavestateAnchoredMovie(
|
||||
index,
|
||||
(byte[])Global.Emulator.SaveStateBinary().Clone());
|
||||
(byte[])((IStatable)Global.Emulator).SaveStateBinary().Clone());
|
||||
|
||||
GlobalWin.MainForm.PauseEmulator();
|
||||
LoadProject(newProject.Filename);
|
||||
|
|
|
@ -5,6 +5,8 @@ using System.Linq;
|
|||
using System.Windows.Forms;
|
||||
using System.ComponentModel;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Client.Common.MovieConversionExtensions;
|
||||
|
||||
|
@ -313,7 +315,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void LoadState(KeyValuePair<int, byte[]> state)
|
||||
{
|
||||
Global.Emulator.LoadStateBinary(new BinaryReader(new MemoryStream(state.Value.ToArray())));
|
||||
((IStatable)Global.Emulator).LoadStateBinary(new BinaryReader(new MemoryStream(state.Value.ToArray())));
|
||||
|
||||
if (state.Key == 0 && CurrentTasMovie.StartsFromSavestate)
|
||||
{
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
<Compile Include="Interfaces\ISaveRam.cs" />
|
||||
<Compile Include="Interfaces\ISettable.cs" />
|
||||
<Compile Include="Interfaces\ISoundProvider.cs" />
|
||||
<Compile Include="Interfaces\IStatable.cs" />
|
||||
<Compile Include="Interfaces\ISyncSoundProvider.cs" />
|
||||
<Compile Include="Interfaces\IVideoProvider.cs" />
|
||||
<Compile Include="MemoryDomain.cs" />
|
||||
|
|
|
@ -22,6 +22,11 @@ namespace BizHawk.Emulation.Common.IEmulatorExtensions
|
|||
return core is ISaveRam;
|
||||
}
|
||||
|
||||
public static bool HasSavestates(this IEmulator core)
|
||||
{
|
||||
return core is IStatable;
|
||||
}
|
||||
|
||||
public static bool IsNull(this IEmulator core)
|
||||
{
|
||||
return core == null || core is NullEmulator;
|
||||
|
|
|
@ -83,25 +83,6 @@ namespace BizHawk.Emulation.Common
|
|||
/// </summary>
|
||||
void ResetCounters();
|
||||
|
||||
/// <summary>
|
||||
/// Savestate handling methods
|
||||
/// </summary>
|
||||
/// <param name="writer"></param>
|
||||
void SaveStateText(TextWriter writer);
|
||||
void LoadStateText(TextReader reader);
|
||||
void SaveStateBinary(BinaryWriter writer);
|
||||
void LoadStateBinary(BinaryReader reader);
|
||||
/// <summary>
|
||||
/// save state binary to a byte buffer
|
||||
/// </summary>
|
||||
/// <returns>you may NOT modify this. if you call SaveStateBinary() again with the same core, the old data MAY be overwritten.</returns>
|
||||
byte[] SaveStateBinary();
|
||||
|
||||
/// <summary>
|
||||
/// true if the core would rather give a binary savestate than a text one. both must function regardless
|
||||
/// </summary>
|
||||
bool BinarySaveStatesPreferred { get; }
|
||||
|
||||
/// <summary>
|
||||
/// the corecomm module in use by this core.
|
||||
/// </summary>
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
using System.IO;
|
||||
|
||||
namespace BizHawk.Emulation.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Savestate handling methods
|
||||
/// </summary>
|
||||
public interface IStatable : ICoreService, IEmulator
|
||||
{
|
||||
void SaveStateText(TextWriter writer);
|
||||
void LoadStateText(TextReader reader);
|
||||
|
||||
void SaveStateBinary(BinaryWriter writer);
|
||||
void LoadStateBinary(BinaryReader reader);
|
||||
|
||||
/// <summary>
|
||||
/// save state binary to a byte buffer
|
||||
/// </summary>
|
||||
/// <returns>you may NOT modify this. if you call SaveStateBinary() again with the same core, the old data MAY be overwritten.</returns>
|
||||
byte[] SaveStateBinary();
|
||||
|
||||
/// <summary>
|
||||
/// true if the core would rather give a binary savestate than a text one. both must function regardless
|
||||
/// </summary>
|
||||
bool BinarySaveStatesPreferred { get; }
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
isPorted: false,
|
||||
isReleased: true
|
||||
)]
|
||||
public partial class TI83 : IEmulator, IMemoryDomains, IDebuggable, ISettable<TI83.TI83Settings, object>
|
||||
public partial class TI83 : IEmulator, IMemoryDomains, IStatable, IDebuggable, ISettable<TI83.TI83Settings, object>
|
||||
{
|
||||
//hardware
|
||||
private readonly Z80A cpu = new Z80A();
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
isPorted: false,
|
||||
isReleased: false
|
||||
)]
|
||||
sealed public partial class C64 : IEmulator, IMemoryDomains
|
||||
sealed public partial class C64 : IEmulator, IMemoryDomains, IStatable
|
||||
{
|
||||
// internal variables
|
||||
private bool _islag = true;
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
isPorted: false,
|
||||
isReleased: true
|
||||
)]
|
||||
public partial class Atari2600 : IEmulator, IMemoryDomains, IDebuggable, ISettable<Atari2600.A2600Settings, Atari2600.A2600SyncSettings>
|
||||
public partial class Atari2600 : IEmulator, IMemoryDomains, IStatable, IDebuggable, ISettable<Atari2600.A2600Settings, Atari2600.A2600SyncSettings>
|
||||
{
|
||||
private readonly GameInfo _game;
|
||||
private bool _islag = true;
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
|
|||
portedVersion: "v1.5",
|
||||
portedUrl: "http://emu7800.sourceforge.net/"
|
||||
)]
|
||||
public partial class Atari7800 : IEmulator, IMemoryDomains, ISaveRam, IDebuggable
|
||||
public partial class Atari7800 : IEmulator, IMemoryDomains, ISaveRam, IDebuggable, IStatable
|
||||
{
|
||||
// TODO:
|
||||
// some things don't work when you try to plug in a 2600 game
|
||||
|
|
|
@ -12,7 +12,7 @@ using Newtonsoft.Json;
|
|||
namespace BizHawk.Emulation.Cores.Atari.Lynx
|
||||
{
|
||||
[CoreAttributes("Handy", "K. Wilkins", true, true, "mednafen 0-9-34-1", "http://mednafen.sourceforge.net/")]
|
||||
public class Lynx : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains, ISaveRam
|
||||
public class Lynx : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains, ISaveRam, IStatable
|
||||
{
|
||||
IntPtr Core;
|
||||
|
||||
|
|
|
@ -159,38 +159,6 @@ namespace BizHawk.Emulation.Cores.Intellivision
|
|||
//IsLagFrame = false;
|
||||
}
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void SaveStateText(TextWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void LoadStateText(TextReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void SaveStateBinary(BinaryWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void LoadStateBinary(BinaryReader reader)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public byte[] SaveStateBinary()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool BinarySaveStatesPreferred { get { return false; } }
|
||||
|
||||
public CoreComm CoreComm { get; private set; }
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
|||
isPorted: true,
|
||||
isReleased: false
|
||||
)]
|
||||
public class GBA : IEmulator, IVideoProvider, ISyncSoundProvider, IGBAGPUViewable, IMemoryDomains, ISaveRam, IDebuggable
|
||||
public class GBA : IEmulator, IVideoProvider, ISyncSoundProvider, IGBAGPUViewable, IMemoryDomains, ISaveRam, IDebuggable, IStatable
|
||||
{
|
||||
public IDictionary<string, int> GetCpuFlagsAndRegisters()
|
||||
{
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
|||
{
|
||||
[CoreAttributes("VBA-Next", "many authors", true, true, "cd508312a29ed8c29dacac1b11c2dce56c338a54", "https://github.com/libretro/vba-next")]
|
||||
public class VBANext : IEmulator, IVideoProvider, ISyncSoundProvider,
|
||||
IGBAGPUViewable, IMemoryDomains, ISaveRam, IDebuggable, ISettable<object, VBANext.SyncSettings>
|
||||
IGBAGPUViewable, IMemoryDomains, ISaveRam, IStatable, IDebuggable, ISettable<object, VBANext.SyncSettings>
|
||||
{
|
||||
IntPtr Core;
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
|||
portedVersion: "SVN 344",
|
||||
portedUrl: "http://gambatte.sourceforge.net/"
|
||||
)]
|
||||
public class Gameboy : IEmulator, IVideoProvider, ISyncSoundProvider, ISaveRam,
|
||||
public class Gameboy : IEmulator, IVideoProvider, ISyncSoundProvider, ISaveRam, IStatable,
|
||||
IMemoryDomains, IDebuggable, ISettable<Gameboy.GambatteSettings, Gameboy.GambatteSyncSettings>
|
||||
{
|
||||
#region ALL SAVESTATEABLE STATE GOES HERE
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
|
|||
portedVersion: "2.0",
|
||||
portedUrl: "https://code.google.com/p/mupen64plus/"
|
||||
)]
|
||||
public partial class N64 : IEmulator, IMemoryDomains, ISaveRam, IDebuggable,
|
||||
public partial class N64 : IEmulator, IMemoryDomains, ISaveRam, IDebuggable, IStatable,
|
||||
ISettable<N64Settings, N64SyncSettings>
|
||||
{
|
||||
private readonly N64Input _inputProvider;
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
isPorted: false,
|
||||
isReleased: true
|
||||
)]
|
||||
public partial class NES : IEmulator, IMemoryDomains, ISaveRam, IDebuggable,
|
||||
public partial class NES : IEmulator, IMemoryDomains, ISaveRam, IDebuggable, IStatable,
|
||||
ISettable<NES.NESSettings, NES.NESSyncSettings>
|
||||
{
|
||||
static readonly bool USE_DATABASE = true;
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
|
|||
portedVersion: "0.7.0",
|
||||
portedUrl: "https://github.com/kode54/QuickNES"
|
||||
)]
|
||||
public class QuickNES : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains, ISaveRam,
|
||||
public class QuickNES : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains, ISaveRam, IStatable,
|
||||
IDebuggable, ISettable<QuickNES.QuickNESSettings, QuickNES.QuickNESSyncSettings>
|
||||
{
|
||||
#region FPU precision
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
|||
portedVersion: "v87",
|
||||
portedUrl: "http://byuu.org/"
|
||||
)]
|
||||
public unsafe class LibsnesCore : IEmulator, IVideoProvider, IMemoryDomains, ISaveRam,
|
||||
public unsafe class LibsnesCore : IEmulator, IVideoProvider, IMemoryDomains, ISaveRam, IStatable,
|
||||
IDebuggable, ISettable<LibsnesCore.SnesSettings, LibsnesCore.SnesSyncSettings>
|
||||
{
|
||||
public LibsnesCore(GameInfo game, byte[] romData, bool deterministicEmulation, byte[] xmlData, CoreComm comm, object Settings, object SyncSettings)
|
||||
|
|
|
@ -61,33 +61,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
|
|||
public string BoardName { get { return null; } }
|
||||
public CoreComm CoreComm { get; private set; }
|
||||
|
||||
#region savestates
|
||||
|
||||
public void SaveStateText(System.IO.TextWriter writer)
|
||||
{
|
||||
}
|
||||
|
||||
public void LoadStateText(System.IO.TextReader reader)
|
||||
{
|
||||
}
|
||||
|
||||
public void SaveStateBinary(System.IO.BinaryWriter writer)
|
||||
{
|
||||
}
|
||||
|
||||
public void LoadStateBinary(System.IO.BinaryReader reader)
|
||||
{
|
||||
}
|
||||
|
||||
public byte[] SaveStateBinary()
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
public bool BinarySaveStatesPreferred { get { return true; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region IVideoProvider
|
||||
|
||||
private int[] _vbuff = new int[512 * 480];
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace BizHawk.Emulation.Cores.PCEngine
|
|||
isPorted: false,
|
||||
isReleased: true
|
||||
)]
|
||||
public sealed partial class PCEngine : IEmulator, IMemoryDomains, ISaveRam,
|
||||
public sealed partial class PCEngine : IEmulator, IMemoryDomains, ISaveRam, IStatable,
|
||||
IDebuggable, ISettable<PCEngine.PCESettings, PCEngine.PCESyncSettings>
|
||||
{
|
||||
// ROM
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace BizHawk.Emulation.Cores.Sega.Genesis
|
|||
isPorted: false,
|
||||
isReleased: false
|
||||
)]
|
||||
public sealed partial class Genesis : IEmulator, IMemoryDomains, IDebuggable, ISaveRam
|
||||
public sealed partial class Genesis : IEmulator, IMemoryDomains, IDebuggable, ISaveRam, IStatable
|
||||
{
|
||||
private int _lagcount = 0;
|
||||
private bool lagged = true;
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn
|
|||
portedVersion: "9.12",
|
||||
portedUrl: "http://yabause.org"
|
||||
)]
|
||||
public class Yabause : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains, ISaveRam,
|
||||
public class Yabause : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains, ISaveRam, IStatable,
|
||||
ISettable<object, Yabause.SaturnSyncSettings>
|
||||
{
|
||||
public static ControllerDefinition SaturnController = new ControllerDefinition
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
portedVersion: "r874",
|
||||
portedUrl: "https://code.google.com/p/genplus-gx/"
|
||||
)]
|
||||
public class GPGX : IEmulator, ISyncSoundProvider, IVideoProvider, IMemoryDomains, ISaveRam,
|
||||
public class GPGX : IEmulator, ISyncSoundProvider, IVideoProvider, IMemoryDomains, ISaveRam, IStatable,
|
||||
IDebuggable, ISettable<GPGX.GPGXSettings, GPGX.GPGXSyncSettings>
|
||||
{
|
||||
static GPGX AttachedCore = null;
|
||||
|
|
|
@ -43,7 +43,6 @@ namespace BizHawk.Emulation.Cores.Sony.PSP
|
|||
public IController Controller { get; set; }
|
||||
public bool DeterministicEmulation { get { return true; } }
|
||||
public string SystemId { get { return "PSP"; } }
|
||||
public bool BinarySaveStatesPreferred { get { return true; } }
|
||||
public CoreComm CoreComm { get; private set; }
|
||||
|
||||
public string BoardName { get { return null; } }
|
||||
|
@ -149,32 +148,6 @@ namespace BizHawk.Emulation.Cores.Sony.PSP
|
|||
{
|
||||
}
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void SaveStateText(System.IO.TextWriter writer)
|
||||
{
|
||||
}
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void LoadStateText(System.IO.TextReader reader)
|
||||
{
|
||||
}
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void SaveStateBinary(System.IO.BinaryWriter writer)
|
||||
{
|
||||
}
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void LoadStateBinary(System.IO.BinaryReader reader)
|
||||
{
|
||||
}
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public byte[] SaveStateBinary()
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
const int screenwidth = 480;
|
||||
const int screenheight = 272;
|
||||
readonly int[] screenbuffer = new int[screenwidth * screenheight];
|
||||
|
|
|
@ -285,23 +285,6 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
|||
[FeatureNotImplemented]
|
||||
public bool DeterministicEmulation { get { return true; } }
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void SaveStateText(TextWriter writer) { }
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void LoadStateText(TextReader reader) { }
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void SaveStateBinary(BinaryWriter writer) { }
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void LoadStateBinary(BinaryReader reader) { }
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public byte[] SaveStateBinary() { return new byte[1]; }
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public bool BinarySaveStatesPreferred { get { return false; } }
|
||||
public int[] GetVideoBuffer() { return frameBuffer; }
|
||||
public int VirtualWidth { get; private set; }
|
||||
public int VirtualHeight { get { return BufferHeight; } }
|
||||
|
|
|
@ -12,7 +12,7 @@ using System.Runtime.InteropServices;
|
|||
namespace BizHawk.Emulation.Cores.WonderSwan
|
||||
{
|
||||
[CoreAttributes("Cygne/Mednafen", "Dox", true, true, "0.9.36.5", "http://mednafen.sourceforge.net/")]
|
||||
public class WonderSwan : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains, ISaveRam,
|
||||
public class WonderSwan : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains, ISaveRam, IStatable,
|
||||
IDebuggable, ISettable<WonderSwan.Settings, WonderSwan.SyncSettings>
|
||||
{
|
||||
#region Controller
|
||||
|
|
Loading…
Reference in New Issue