TAStudio: improve saving behavior (#2337)

* TAStudio import: ask before saving the bk2

* Only save cycle count at movie end; fixes #2203

* Rework the movie end cycle count warning.

* TAStudio import: allow saving even if no changes are detected
This commit is contained in:
RetroEdit 2020-08-29 18:33:13 +00:00 committed by GitHub
parent 56b9ec2350
commit cdf20ff1be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 55 additions and 23 deletions

View File

@ -287,7 +287,6 @@ namespace BizHawk.Client.Common
public void ConvertToTasProj()
{
Movie.Save();
Movie = Movie.ToTasMovie();
Movie.Save();
Movie.SwitchToPlay();
@ -335,13 +334,21 @@ namespace BizHawk.Client.Common
private void HandlePlaybackEnd()
{
if (Movie.Core == CoreNames.Gambatte)
if (Movie.IsAtEnd() && Movie.Core == CoreNames.Gambatte)
{
var movieCycles = Convert.ToUInt64(Movie.HeaderEntries[HeaderKeys.CycleCount]);
var coreCycles = ((Gameboy)Movie.Emulator).CycleCount;
if (movieCycles != (ulong)coreCycles)
var coreCycles = (ulong) ((Gameboy)Movie.Emulator).CycleCount;
var cyclesSaved = Movie.HeaderEntries.ContainsKey(HeaderKeys.CycleCount);
ulong previousCycles = 0;
if (cyclesSaved)
{
PopupMessage($"Cycle count in the movie ({movieCycles}) doesn't match the emulated value ({coreCycles}).");
previousCycles = Convert.ToUInt64(Movie.HeaderEntries[HeaderKeys.CycleCount]);
}
var cyclesMatch = previousCycles == coreCycles;
if (!cyclesSaved || !cyclesMatch)
{
var previousState = !cyclesSaved ? "The saved movie is currently missing a cycle count." : $"The previous cycle count ({previousCycles}) doesn't match.";
// TODO: Ideally, this would be a Yes/No MessageBox that saves when "Yes" is pressed.
PopupMessage($"The end of the movie has been reached.\n\n{previousState}\n\nSave to update to the new cycle count ({coreCycles}).");
}
}

View File

@ -52,7 +52,7 @@ namespace BizHawk.Client.Common
protected virtual void Write(string fn, bool isBackup = false)
{
SetCycleValues(); // We are pretending these only need to be set on save
SetCycleValues();
// EmulatorVersion used to store the unchanging original emulator version.
if (!Header.ContainsKey(HeaderKeys.OriginalEmulatorVersion))
{
@ -72,17 +72,26 @@ namespace BizHawk.Client.Common
private void SetCycleValues()
{
if (Emulator is Emulation.Cores.Nintendo.SubNESHawk.SubNESHawk subNes)
{
Header[HeaderKeys.VBlankCount] = subNes.VblankCount.ToString();
// The saved cycle value will only be valid if the end of the movie has been emulated.
if (this.IsAtEnd())
{
if (Emulator is Emulation.Cores.Nintendo.SubNESHawk.SubNESHawk subNes)
{
Header[HeaderKeys.VBlankCount] = subNes.VblankCount.ToString();
}
else if (Emulator is Emulation.Cores.Nintendo.Gameboy.Gameboy gameboy)
{
Header[HeaderKeys.CycleCount] = gameboy.CycleCount.ToString();
}
else if (Emulator is Emulation.Cores.Nintendo.SubGBHawk.SubGBHawk subGb)
{
Header[HeaderKeys.CycleCount] = subGb.CycleCount.ToString();
}
}
else if (Emulator is Emulation.Cores.Nintendo.Gameboy.Gameboy gameboy)
else
{
Header[HeaderKeys.CycleCount] = gameboy.CycleCount.ToString();
}
else if (Emulator is Emulation.Cores.Nintendo.SubGBHawk.SubGBHawk subGb)
{
Header[HeaderKeys.CycleCount] = subGb.CycleCount.ToString();
Header.Remove(HeaderKeys.CycleCount);
Header.Remove(HeaderKeys.VBlankCount);
}
}

View File

@ -258,6 +258,11 @@ namespace BizHawk.Client.Common
public static bool IsFinished(this IMovie movie) => movie?.Mode == MovieMode.Finished;
public static bool IsPlayingOrFinished(this IMovie movie) => movie?.Mode == MovieMode.Play || movie?.Mode == MovieMode.Finished;
public static bool IsPlayingOrRecording(this IMovie movie) => movie?.Mode == MovieMode.Play || movie?.Mode == MovieMode.Record;
/// <summary>
/// Emulation is currently right after the movie's last input frame,
/// but no further frames have been emulated.
/// </summary>
public static bool IsAtEnd(this IMovie movie) => movie != null && movie.Emulator?.Frame == movie.InputLogLength;
/// <summary>

View File

@ -273,7 +273,7 @@ namespace BizHawk.Client.EmuHawk
{
var moviePlaying = GlobalWin.MovieSession.Movie.IsPlaying();
// After the last frame of the movie, we want both the last movie input and the current inputs.
var atMovieEnd = (GlobalWin.MovieSession.Movie.IsFinished() && GlobalWin.Emulator.Frame == GlobalWin.MovieSession.Movie.InputLogLength);
var atMovieEnd = GlobalWin.MovieSession.Movie.IsFinished() && GlobalWin.MovieSession.Movie.IsAtEnd();
if (moviePlaying || atMovieEnd)
{
var input = InputStrMovie();

View File

@ -203,17 +203,28 @@ namespace BizHawk.Client.EmuHawk
// Start Scenario 1: A regular movie is active
if (MovieSession.Movie.IsActive() && !(MovieSession.Movie is ITasMovie))
{
var result = MessageBox.Show("In order to use Tastudio, a new project must be created from the current movie\nThe current movie will be saved and closed, and a new project file will be created\nProceed?", "Convert movie", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
if (result.IsOk())
var changesString = "Would you like to save the current movie before closing it?";
if (MovieSession.Movie.Changes)
{
ConvertCurrentMovieToTasproj();
StartNewMovieWrapper(CurrentTasMovie);
SetUpColumns();
changesString = "The current movie has unsaved changes. Would you like to save before closing it?";
}
else
var result = MessageBox.Show(
"TAStudio will create a new project file from the current movie.\n\n" + changesString,
"Convert movie",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question);
if (result.Equals(DialogResult.Yes))
{
MovieSession.Movie.Save();
}
else if (result.Equals(DialogResult.Cancel))
{
return false;
}
ConvertCurrentMovieToTasproj();
StartNewMovieWrapper(CurrentTasMovie);
SetUpColumns();
}
// Start Scenario 2: A tasproj is already active