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:
adelikat 2014-11-30 16:42:58 +00:00
parent 230cd3fb6a
commit 76148ae111
35 changed files with 200 additions and 242 deletions

View File

@ -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)
{

View File

@ -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;

View File

@ -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))
{

View File

@ -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));
}
}
}
}

View File

@ -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)
{

View File

@ -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

View File

@ -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();
}
}

View File

@ -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 ?

View File

@ -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);

View File

@ -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)
{

View File

@ -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" />

View File

@ -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;

View File

@ -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>

View File

@ -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; }
}
}

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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()

View File

@ -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()
{

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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];

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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];

View File

@ -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; } }

View File

@ -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