Movie playback and recording will now set IEmulator.DeterministicEmulation = true; only snes core actually does anything with this. It hasn't been explained before in a log; so I'll do it now: When in deterministic mode, the snes core internally does exactly one savestate each and every frame. Then, if the frontend calls savestate at all, it always gets the same internal cached savestate. If the frontend doesn't call savestate, then the internal savestate is simply discarded. This way, the exact same number of RunToSave() calls occur every time.

This commit is contained in:
goyuken 2012-10-01 14:39:52 +00:00
parent 2b1e04997c
commit d4f5ed2f50
3 changed files with 13 additions and 6 deletions

View File

@ -637,7 +637,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
get { return _DeterministicEmulation; }
set
{
if (_DeterministicEmulationProtected)
if (_DeterministicEmulationProtected && value != _DeterministicEmulation)
throw new Exception("snes: DeterministicEmulation must be set before load!");
_DeterministicEmulation = value;
}
@ -762,19 +762,22 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
/// internal function handling savestate
/// this can cause determinism problems if called improperly!
/// </summary>
byte[] CoreSaveStateInternal(bool store)
byte[] CoreSaveStateInternal(bool cache)
{
int size = LibsnesDll.snes_serialize_size();
byte[] buf = new byte[size];
fixed (byte* pbuf = &buf[0])
LibsnesDll.snes_serialize(new IntPtr(pbuf), size);
if (store)
if (cache)
{
savestatebuff = buf;
return null;
}
else
{
savestatebuff = null;
return buf;
}
}
// Arbitrary extensible core comm mechanism

View File

@ -24,7 +24,7 @@ namespace BizHawk.MultiClient
Global.MovieSession.Movie = m;
RewireInputChain();
LoadRom(Global.MainForm.CurrentlyOpenRom);
LoadRom(Global.MainForm.CurrentlyOpenRom, true);
if (!record)
{
Global.MovieSession.Movie.LoadMovie();
@ -90,7 +90,7 @@ namespace BizHawk.MultiClient
{
if (Global.MovieSession.Movie.IsActive)
{
LoadRom(CurrentlyOpenRom);
LoadRom(CurrentlyOpenRom, true);
if (Global.MovieSession.Movie.StartsFromSavestate)
{
LoadStateFile(Global.MovieSession.Movie.Filename, Path.GetFileName(Global.MovieSession.Movie.Filename));

View File

@ -1274,7 +1274,7 @@ namespace BizHawk.MultiClient
Global.MovieOutputHardpoint.Source = Global.MovieInputSourceAdapter;
}
public bool LoadRom(string path)
public bool LoadRom(string path, bool deterministicemulation = false)
{
if (path == null) return false;
using (var file = new HawkFile())
@ -1401,6 +1401,7 @@ namespace BizHawk.MultiClient
{
game.System = "SNES";
var snes = new LibsnesCore();
if (deterministicemulation) snes.DeterministicEmulation = true;
nextEmulator = snes;
nextEmulator.CoreInputComm = Global.CoreInputComm;
snes.Load(game, rom.FileData, null);
@ -1491,6 +1492,7 @@ namespace BizHawk.MultiClient
game.AddOption("SGB");
game.System = "SGB";
var snes = new LibsnesCore();
if (deterministicemulation) snes.DeterministicEmulation = true;
nextEmulator = snes;
snes.Load(game, rom.FileData, sgbrom);
}
@ -1528,6 +1530,8 @@ namespace BizHawk.MultiClient
if (nextEmulator == null) throw new Exception();
if (deterministicemulation) nextEmulator.DeterministicEmulation = true;
CloseGame();
Global.Emulator.Dispose();
Global.Emulator = nextEmulator;