Overhaul movie savestate logic - cleaned up a lot of code, implemented GUID, Future Event, and Timeline checks to read-only situations. Prevented loading of state if an error occurs. Still TODO - GUID checks in read+write mode
This commit is contained in:
parent
35180dbae4
commit
3481943b74
|
@ -74,11 +74,6 @@ namespace BizHawk.MultiClient
|
||||||
return mg.GetControllersAsMnemonic();
|
return mg.GetControllersAsMnemonic();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO - wtf is this being used for
|
|
||||||
public static bool MovieMode;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static CoreAccessor PsxCoreLibrary = new CoreAccessor(new Win32LibAccessor("PsxHawk.Core.dll"));
|
public static CoreAccessor PsxCoreLibrary = new CoreAccessor(new Win32LibAccessor("PsxHawk.Core.dll"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,35 +104,35 @@ namespace BizHawk.MultiClient
|
||||||
if (UserMovie.Mode != MOVIEMODE.INACTIVE)
|
if (UserMovie.Mode != MOVIEMODE.INACTIVE)
|
||||||
{
|
{
|
||||||
UserMovie.StopMovie();
|
UserMovie.StopMovie();
|
||||||
Global.MovieMode = false;
|
|
||||||
Global.RenderPanel.AddMessage(message);
|
Global.RenderPanel.AddMessage(message);
|
||||||
SetMainformMovieInfo();
|
SetMainformMovieInfo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleMovieLoadState(StreamReader reader)
|
private bool HandleMovieLoadState(StreamReader reader)
|
||||||
{
|
{
|
||||||
//Note, some of the situations in these IF's may be identical and could be combined but I intentionally separated it out for clarity
|
//Note, some of the situations in these IF's may be identical and could be combined but I intentionally separated it out for clarity
|
||||||
|
if (UserMovie.Mode == MOVIEMODE.INACTIVE)
|
||||||
|
return true;
|
||||||
|
|
||||||
if (UserMovie.Mode == MOVIEMODE.RECORD)
|
if (UserMovie.Mode == MOVIEMODE.RECORD)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (ReadOnly)
|
if (ReadOnly)
|
||||||
{
|
{
|
||||||
|
|
||||||
int x = UserMovie.CheckTimeLines(reader);
|
if (!UserMovie.CheckTimeLines(reader))
|
||||||
//if (x >= 0)
|
return false; //Timeline/GUID error
|
||||||
// MessageBox.Show("Savestate input log does not match the movie at frame " + (x+1).ToString() + "!", "Timeline error", MessageBoxButtons.OK); //TODO: replace with a not annoying message once savestate logic is running smoothly
|
else
|
||||||
//else
|
|
||||||
{
|
{
|
||||||
UserMovie.WriteMovie();
|
UserMovie.WriteMovie();
|
||||||
UserMovie.StartPlayback();
|
UserMovie.StartPlayback();
|
||||||
SetMainformMovieInfo();
|
SetMainformMovieInfo();
|
||||||
Global.MovieMode = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Global.MovieMode = false;
|
//TODO: GUID check
|
||||||
UserMovie.LoadLogFromSavestateText(reader);
|
UserMovie.LoadLogFromSavestateText(reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,59 +140,55 @@ namespace BizHawk.MultiClient
|
||||||
{
|
{
|
||||||
if (ReadOnly)
|
if (ReadOnly)
|
||||||
{
|
{
|
||||||
int x = UserMovie.CheckTimeLines(reader);
|
if (!UserMovie.CheckTimeLines(reader))
|
||||||
//if (x >= 0)
|
return false; //Timeline/GUID error
|
||||||
// MessageBox.Show("Savestate input log does not match the movie at frame " + (x+1).ToString() + "!", "Timeline error", MessageBoxButtons.OK); //TODO: replace with a not annoying message once savestate logic is running smoothly
|
//Frame loop automatically handles the rewinding effect based on Global.Emulator.Frame so nothing else is needed here
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//TODO: GUID check
|
||||||
//QUESTIONABLE - control whether the movie gets truncated here?
|
//QUESTIONABLE - control whether the movie gets truncated here?
|
||||||
UserMovie.StartNewRecording(!Global.MovieSession.MultiTrack.IsActive);
|
UserMovie.StartNewRecording(!Global.MovieSession.MultiTrack.IsActive);
|
||||||
SetMainformMovieInfo();
|
SetMainformMovieInfo();
|
||||||
Global.MovieMode = false;
|
|
||||||
UserMovie.LoadLogFromSavestateText(reader);
|
UserMovie.LoadLogFromSavestateText(reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (UserMovie.Mode == MOVIEMODE.FINISHED)
|
else if (UserMovie.Mode == MOVIEMODE.FINISHED)
|
||||||
{
|
{
|
||||||
//TODO: have the input log kick in upon movie finished mode and stop upon movie resume
|
|
||||||
if (ReadOnly)
|
if (ReadOnly)
|
||||||
{
|
{
|
||||||
if (Global.Emulator.Frame > UserMovie.Length())
|
if (Global.Emulator.Frame > UserMovie.Length())
|
||||||
{
|
{
|
||||||
Global.MovieMode = false;
|
|
||||||
//Post movie savestate
|
//Post movie savestate
|
||||||
//There is no movie data to load, and the movie will stay in movie finished mode
|
//There is no movie data to load, and the movie will stay in movie finished mode
|
||||||
//So do nothing
|
//So do nothing
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int x = UserMovie.CheckTimeLines(reader);
|
if (!UserMovie.CheckTimeLines(reader))
|
||||||
|
return false; //Timeline/GUID error
|
||||||
UserMovie.StartPlayback();
|
UserMovie.StartPlayback();
|
||||||
SetMainformMovieInfo();
|
SetMainformMovieInfo();
|
||||||
Global.MovieMode = true;
|
|
||||||
//if (x >= 0)
|
|
||||||
// MessageBox.Show("Savestate input log does not match the movie at frame " + (x+1).ToString() + "!", "Timeline error", MessageBoxButtons.OK); //TODO: replace with a not annoying message once savestate logic is running smoothly
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Global.Emulator.Frame > UserMovie.Length())
|
if (Global.Emulator.Frame > UserMovie.Length())
|
||||||
{
|
{
|
||||||
Global.MovieMode = false;
|
|
||||||
//Post movie savestate
|
//Post movie savestate
|
||||||
//There is no movie data to load, and the movie will stay in movie finished mode
|
//There is no movie data to load, and the movie will stay in movie finished mode
|
||||||
//So do nothing
|
//So do nothing
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//TODO: GUID check
|
||||||
UserMovie.StartNewRecording();
|
UserMovie.StartNewRecording();
|
||||||
Global.MovieMode = false;
|
|
||||||
SetMainformMovieInfo();
|
SetMainformMovieInfo();
|
||||||
UserMovie.LoadLogFromSavestateText(reader);
|
UserMovie.LoadLogFromSavestateText(reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleMovieSaveState(StreamWriter writer)
|
private void HandleMovieSaveState(StreamWriter writer)
|
||||||
|
|
|
@ -777,7 +777,6 @@ namespace BizHawk.MultiClient
|
||||||
}
|
}
|
||||||
|
|
||||||
RewireInputChain();
|
RewireInputChain();
|
||||||
Global.MovieMode = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RewireInputChain()
|
void RewireInputChain()
|
||||||
|
@ -1462,7 +1461,6 @@ namespace BizHawk.MultiClient
|
||||||
if (UserMovie.Length() == Global.Emulator.Frame)
|
if (UserMovie.Length() == Global.Emulator.Frame)
|
||||||
{
|
{
|
||||||
UserMovie.SetMovieFinished();
|
UserMovie.SetMovieFinished();
|
||||||
Global.MovieMode = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (UserMovie.Mode == MOVIEMODE.FINISHED)
|
if (UserMovie.Mode == MOVIEMODE.FINISHED)
|
||||||
|
@ -1599,11 +1597,14 @@ namespace BizHawk.MultiClient
|
||||||
private void LoadStateFile(string path, string name)
|
private void LoadStateFile(string path, string name)
|
||||||
{
|
{
|
||||||
var reader = new StreamReader(path);
|
var reader = new StreamReader(path);
|
||||||
Global.Emulator.LoadStateText(reader);
|
|
||||||
HandleMovieLoadState(reader);
|
if (HandleMovieLoadState(reader))
|
||||||
UpdateTools();
|
{
|
||||||
reader.Close();
|
Global.Emulator.LoadStateText(reader);
|
||||||
Global.RenderPanel.AddMessage("Loaded state: " + name);
|
UpdateTools();
|
||||||
|
reader.Close();
|
||||||
|
Global.RenderPanel.AddMessage("Loaded state: " + name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadState(string name)
|
private void LoadState(string name)
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace BizHawk.MultiClient
|
namespace BizHawk.MultiClient
|
||||||
{
|
{
|
||||||
|
@ -477,34 +478,61 @@ namespace BizHawk.MultiClient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int CheckTimeLines(StreamReader reader)
|
public bool CheckTimeLines(StreamReader reader)
|
||||||
{
|
{
|
||||||
return -1; //Hack
|
|
||||||
//This function will compare the movie data to the savestate movie data to see if they match
|
//This function will compare the movie data to the savestate movie data to see if they match
|
||||||
//TODO: Will eventually check header data too such as GUI
|
|
||||||
/*
|
|
||||||
MovieLog l = new MovieLog();
|
MovieLog l = new MovieLog();
|
||||||
string line;
|
string line;
|
||||||
|
string GUID;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
line = reader.ReadLine();
|
line = reader.ReadLine();
|
||||||
if (line.Trim() == "") continue;
|
if (line.Trim() == "") continue;
|
||||||
|
else if (line.Contains("GUID"))
|
||||||
|
{
|
||||||
|
GUID = ParseHeader(line, MovieHeader.GUID);
|
||||||
|
if (Header.GetHeaderLine(MovieHeader.GUID) != GUID)
|
||||||
|
{
|
||||||
|
//GUID Mismatch error
|
||||||
|
var result = MessageBox.Show(GUID + " : " + Header.GetHeaderLine(MovieHeader.GUID) + "\n" +
|
||||||
|
"The savestate GUID does not match the current movie. Proceed anyway?", "GUID Mismatch error",
|
||||||
|
MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||||
|
|
||||||
|
if (result == DialogResult.No)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (line == "[Input]") continue;
|
else if (line == "[Input]") continue;
|
||||||
else if (line == "[/Input]") break;
|
else if (line == "[/Input]") break;
|
||||||
else if (line[0] == '|')
|
else if (line[0] == '|')
|
||||||
l.AddFrame(line);
|
l.AddFrame(line);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reader.BaseStream.Position = 0; //Reset position because this stream may be read again by other code
|
||||||
|
|
||||||
|
if (Log.Length() < l.Length())
|
||||||
|
{
|
||||||
|
//Future event error
|
||||||
|
MessageBox.Show("The savestate is from frame " + l.Length().ToString() + " which is greater than the current movie length of " +
|
||||||
|
Log.Length().ToString() + ".\nCan not load this savestate.", "Future event Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
for (int x = 0; x < Log.Length(); x++)
|
for (int x = 0; x < Log.Length(); x++)
|
||||||
{
|
{
|
||||||
string xs = Log.GetFrame(x);
|
string xs = Log.GetFrame(x);
|
||||||
string ys = l.GetFrame(x);
|
string ys = l.GetFrame(x);
|
||||||
//if (Log.GetFrame(x) != l.GetFrame(x))
|
if (Log.GetFrame(x) != l.GetFrame(x))
|
||||||
if (xs != ys)
|
{
|
||||||
return x;
|
//TimeLine Error
|
||||||
|
MessageBox.Show("The savestate input does not match the movie input at frame " + (x + 1).ToString() + ".",
|
||||||
|
"Timeline Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return true;
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int CompareTo(Movie Other, string parameter)
|
public int CompareTo(Movie Other, string parameter)
|
||||||
|
|
Loading…
Reference in New Issue