diff --git a/BizHawk.Emulation.Common/Interfaces/IEmulator.cs b/BizHawk.Emulation.Common/Interfaces/IEmulator.cs
index 21f48d5f11..80bb782845 100644
--- a/BizHawk.Emulation.Common/Interfaces/IEmulator.cs
+++ b/BizHawk.Emulation.Common/Interfaces/IEmulator.cs
@@ -10,14 +10,15 @@ namespace BizHawk.Emulation.Common
public interface IEmulator : IEmulatorService, IDisposable
{
///
- /// The intended mechanism to get services from a core
+ /// Gets the service provider.
+ /// This is the intended mechanism to get services from a core
/// Retrieves an IEmulatorService from the core,
/// if the core does not have the type specified, it will return null
///
IEmulatorServiceProvider ServiceProvider { get; }
///
- /// Defines all the possible inputs and types that the core can receive
+ /// Gets the definition that defines all the possible inputs and types that the core can receive
/// By design this should not change during the lifetime of the instance of the core
/// To change the definition, a new instance should be created
///
@@ -39,17 +40,18 @@ namespace BizHawk.Emulation.Common
void FrameAdvance(bool render, bool rendersound = true);
///
- /// The frame count
+ /// Gets the current frame count
///
int Frame { get; }
///
- /// The unique Id of the platform currently being emulated, for instance "NES"
+ /// Gets the unique Id of the platform currently being emulated, for instance "NES"
///
string SystemId { get; }
///
- /// This flag is a contract with the client.
+ /// Gets a value indicating whether the core is in deterministic mode.
+ /// This flag is a contract with the client.
/// If true, the core agrees to behave in a completely deterministic manner,
/// Features like movie recording depend on this.
/// It is the client's responsibility to manage this flag.
@@ -59,7 +61,7 @@ namespace BizHawk.Emulation.Common
bool DeterministicEmulation { get; }
///
- /// identifying information about a "mapper" or similar capability. null if no such useful distinction can be drawn
+ /// Gets the identifying information about a "mapper" or similar capability. null if no such useful distinction can be drawn
///
string BoardName { get; }
@@ -69,7 +71,7 @@ namespace BizHawk.Emulation.Common
void ResetCounters();
///
- /// the corecomm module in use by this core.
+ /// Gets the core communications module in use by this core.
///
///
CoreComm CoreComm { get; }
diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
index 127d3adb1a..2306ec5157 100644
--- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
+++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
@@ -905,6 +905,9 @@
LibsnesCore.cs
+ LibsnesCore.cs
+
+
LibsnesCore.cs
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IEmulator.cs
new file mode 100644
index 0000000000..2420722c61
--- /dev/null
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IEmulator.cs
@@ -0,0 +1,140 @@
+using System.IO;
+
+using BizHawk.Emulation.Common;
+
+namespace BizHawk.Emulation.Cores.Nintendo.SNES
+{
+ public partial class LibsnesCore : IEmulator
+ {
+ public IEmulatorServiceProvider ServiceProvider { get; }
+
+ public ControllerDefinition ControllerDefinition => _controllerDeck.Definition;
+
+ public IController Controller { get; set; }
+
+ public void FrameAdvance(bool render, bool rendersound)
+ {
+ /* if the input poll callback is called, it will set this to false
+ * this has to be done before we save the per-frame state in deterministic
+ * mode, because in there, the core actually advances, and might advance
+ * through the point in time where IsLagFrame gets set to false. makes sense?
+ */
+
+ IsLagFrame = true;
+
+ if (!nocallbacks && Tracer.Enabled)
+ {
+ api.QUERY_set_trace_callback(tracecb);
+ }
+ else
+ {
+ api.QUERY_set_trace_callback(null);
+ }
+
+ // for deterministic emulation, save the state we're going to use before frame advance
+ // don't do this during nocallbacks though, since it's already been done
+ if (!nocallbacks && DeterministicEmulation)
+ {
+ var ms = new MemoryStream();
+ var bw = new BinaryWriter(ms);
+ bw.Write(CoreSaveState());
+ bw.Write(false); // not framezero
+ var ssc = new SnesSaveController();
+ ssc.CopyFrom(Controller);
+ ssc.Serialize(bw);
+ bw.Close();
+ _savestatebuff = ms.ToArray();
+ }
+
+ // speedup when sound rendering is not needed
+ api.QUERY_set_audio_sample(rendersound ? soundcb : null);
+
+ bool resetSignal = Controller.IsPressed("Reset");
+ if (resetSignal)
+ {
+ api.CMD_reset();
+ }
+
+ bool powerSignal = Controller.IsPressed("Power");
+ if (powerSignal)
+ {
+ api.CMD_power();
+ }
+
+ var enables = new LibsnesApi.LayerEnables
+ {
+ BG1_Prio0 = _settings.ShowBG1_0,
+ BG1_Prio1 = _settings.ShowBG1_1,
+ BG2_Prio0 = _settings.ShowBG2_0,
+ BG2_Prio1 = _settings.ShowBG2_1,
+ BG3_Prio0 = _settings.ShowBG3_0,
+ BG3_Prio1 = _settings.ShowBG3_1,
+ BG4_Prio0 = _settings.ShowBG4_0,
+ BG4_Prio1 = _settings.ShowBG4_1,
+ Obj_Prio0 = _settings.ShowOBJ_0,
+ Obj_Prio1 = _settings.ShowOBJ_1,
+ Obj_Prio2 = _settings.ShowOBJ_2,
+ Obj_Prio3 = _settings.ShowOBJ_3
+ };
+
+ api.SetLayerEnables(ref enables);
+
+ RefreshMemoryCallbacks(false);
+
+ // apparently this is one frame?
+ _timeFrameCounter++;
+ api.CMD_run();
+
+ // once upon a time we forwarded messages frmo bsnes here, by checking for queued text messages, but I don't think it's needed any longer
+ if (IsLagFrame)
+ {
+ LagCount++;
+ }
+ }
+
+ public int Frame
+ {
+ get { return _timeFrameCounter; }
+ private set { _timeFrameCounter = value; }
+ }
+
+ public string SystemId { get; }
+
+ // adelikat: Nasty hack to force new business logic. Compatibility (and Accuracy when fully supported) will ALWAYS be in deterministic mode,
+ // a consequence is a permanent performance hit to the compatibility core
+ // Perormance will NEVER be in deterministic mode (and the client side logic will prohibit movie recording on it)
+ // feos: Nasty hack to a nasty hack. Allow user disable it with a strong warning.
+ public bool DeterministicEmulation =>
+ _settings.ForceDeterminism
+ && (CurrentProfile == "Compatibility" || CurrentProfile == "Accuracy");
+
+ public string BoardName { get; }
+
+ public void ResetCounters()
+ {
+ _timeFrameCounter = 0;
+ LagCount = 0;
+ IsLagFrame = false;
+ }
+
+ public CoreComm CoreComm { get; }
+
+ public void Dispose()
+ {
+ if (_disposed)
+ {
+ return;
+ }
+
+ _disposed = true;
+
+ api.CMD_unload_cartridge();
+ api.CMD_term();
+
+ resampler.Dispose();
+ api.Dispose();
+
+ _currCdl?.Unpin();
+ }
+ }
+}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs
index 9433b0bd0f..23b0c0b5b5 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs
@@ -160,7 +160,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
SetupMemoryDomains(romData, sgbRomData);
- DeterministicEmulation = deterministicEmulation;
+ // DeterministicEmulation = deterministicEmulation; // Note we don't respect the value coming in and force it instead
if (DeterministicEmulation) // save frame-0 savestate now
{
MemoryStream ms = new MemoryStream();
@@ -174,8 +174,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
}
}
- public IEmulatorServiceProvider ServiceProvider { get; private set; }
-
private GameInfo _game;
public string CurrentProfile
@@ -199,21 +197,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
/// disable all external callbacks. the front end should not even know the core is frame advancing
bool nocallbacks = false;
- bool disposed = false;
- public void Dispose()
- {
- if (disposed) return;
- disposed = true;
-
- api.CMD_unload_cartridge();
- api.CMD_term();
-
- resampler.Dispose();
- api.Dispose();
-
- if (_currCdl != null) _currCdl.Unpin();
- }
-
public ITraceable Tracer { get; private set; }
public class MyScanlineHookManager : ScanlineHookManager
@@ -230,10 +213,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
}
}
+ bool _disposed = false;
+
public MyScanlineHookManager ScanlineHookManager;
void OnScanlineHooksChanged()
{
- if (disposed) return;
+ if (_disposed) return;
if (ScanlineHookManager.HookCount == 0) api.QUERY_set_scanlineStart(null);
else api.QUERY_set_scanlineStart(scanlineStart_cb);
}
@@ -507,75 +492,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
}
}
- public void FrameAdvance(bool render, bool rendersound)
- {
- /* if the input poll callback is called, it will set this to false
- * this has to be done before we save the per-frame state in deterministic
- * mode, because in there, the core actually advances, and might advance
- * through the point in time where IsLagFrame gets set to false. makes sense?
- */
-
- IsLagFrame = true;
-
- if (!nocallbacks && Tracer.Enabled)
- api.QUERY_set_trace_callback(tracecb);
- else
- api.QUERY_set_trace_callback(null);
-
- // for deterministic emulation, save the state we're going to use before frame advance
- // don't do this during nocallbacks though, since it's already been done
- if (!nocallbacks && DeterministicEmulation)
- {
- MemoryStream ms = new MemoryStream();
- BinaryWriter bw = new BinaryWriter(ms);
- bw.Write(CoreSaveState());
- bw.Write(false); // not framezero
- SnesSaveController ssc = new SnesSaveController();
- ssc.CopyFrom(Controller);
- ssc.Serialize(bw);
- bw.Close();
- _savestatebuff = ms.ToArray();
- }
-
- // speedup when sound rendering is not needed
- if (!rendersound)
- api.QUERY_set_audio_sample(null);
- else
- api.QUERY_set_audio_sample(soundcb);
-
- bool resetSignal = Controller.IsPressed("Reset");
- if (resetSignal) api.CMD_reset();
-
- bool powerSignal = Controller.IsPressed("Power");
- if (powerSignal) api.CMD_power();
-
- var enables = new LibsnesApi.LayerEnables();
- enables.BG1_Prio0 = _settings.ShowBG1_0;
- enables.BG1_Prio1 = _settings.ShowBG1_1;
- enables.BG2_Prio0 = _settings.ShowBG2_0;
- enables.BG2_Prio1 = _settings.ShowBG2_1;
- enables.BG3_Prio0 = _settings.ShowBG3_0;
- enables.BG3_Prio1 = _settings.ShowBG3_1;
- enables.BG4_Prio0 = _settings.ShowBG4_0;
- enables.BG4_Prio1 = _settings.ShowBG4_1;
- enables.Obj_Prio0 = _settings.ShowOBJ_0;
- enables.Obj_Prio1 = _settings.ShowOBJ_1;
- enables.Obj_Prio2 = _settings.ShowOBJ_2;
- enables.Obj_Prio3 = _settings.ShowOBJ_3;
- api.SetLayerEnables(ref enables);
-
- RefreshMemoryCallbacks(false);
-
- //apparently this is one frame?
- timeFrameCounter++;
- api.CMD_run();
-
- //once upon a time we forwarded messages frmo bsnes here, by checking for queued text messages, but I don't think it's needed any longer
-
- if (IsLagFrame)
- LagCount++;
- }
-
void RefreshMemoryCallbacks(bool suppress)
{
var mcs = MemoryCallbacks;
@@ -584,34 +500,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
api.QUERY_set_state_hook_write(!suppress && mcs.HasWrites);
}
- public ControllerDefinition ControllerDefinition { get { return _controllerDeck.Definition; } }
- IController controller;
- public IController Controller
- {
- get { return controller; }
- set { controller = value; }
- }
-
- int timeFrameCounter;
- public int Frame { get { return timeFrameCounter; } set { timeFrameCounter = value; } }
-
- public string SystemId { get; private set; }
-
- public string BoardName { get; private set; }
-
- // adelikat: Nasty hack to force new business logic. Compatibility (and Accuracy when fully supported) will ALWAYS be in deterministic mode,
- // a consequence is a permanent performance hit to the compatibility core
- // Perormance will NEVER be in deterministic mode (and the client side logic will prohibit movie recording on it)
- // feos: Nasty hack to a nasty hack. Allow user disable it with a strong warning.
- public bool DeterministicEmulation
- {
- get
- {
- return _settings.ForceDeterminism &&
- (CurrentProfile == "Compatibility" || CurrentProfile == "Accuracy");
- }
- private set { /* Do nothing */ }
- }
+ private int _timeFrameCounter;
//public byte[] snes_get_memory_data_read(LibsnesApi.SNES_MEMORY id)
//{
@@ -621,13 +510,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
// return ret;
//}
- public void ResetCounters()
- {
- timeFrameCounter = 0;
- LagCount = 0;
- IsLagFrame = false;
- }
-
#region savestates
///
@@ -729,14 +611,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
}
}
-
-
-
-
#endregion
- public CoreComm CoreComm { get; private set; }
-
// works for WRAM, garbage for anything else
static int? FakeBusMap(int addr)
{