Bugfix: Extending movie by painting invalidated last frame

Moved GreenzoneCurrentFrame call to a new method called after frame advance.
Feature: Scroll to marker
Page up/down now scrolls by one page
Scrolling via dragging bar and via wheel now both have the same max value.
This commit is contained in:
SuuperW 2015-03-16 20:42:14 +00:00
parent 84acda3bbc
commit 6783978f49
11 changed files with 413 additions and 360 deletions

View File

@ -136,11 +136,6 @@ namespace BizHawk.Client.Common
{
var input = Movie.GetInputState(Global.Emulator.Frame);
if (Movie is TasMovie) // Hack city, GetInputState can't run this code because all sorts of places call it, we only want to do this during this playback loop
{
(Movie as TasMovie).GreenzoneCurrentFrame();
}
MovieControllerAdapter.LatchFromSource(input);
if (MultiTrack.IsActive)
{
@ -278,7 +273,7 @@ namespace BizHawk.Client.Common
Movie.PokeFrame(Global.Emulator.Frame, Global.MovieOutputHardpoint);
}
else
{
{ // Why, this was already done?
LatchInputFromLog();
}
}
@ -307,6 +302,12 @@ namespace BizHawk.Client.Common
Movie.RecordFrame(Global.Emulator.Frame, Global.MovieOutputHardpoint);
}
public void HandleMovieAfterFrameLoop()
{
if (Movie is TasMovie) // Was being done in LatchInputFromLog
(Movie as TasMovie).GreenzoneCurrentFrame();
}
public bool HandleMovieLoadState(string path)
{
using (var sr = new StreamReader(path))

View File

@ -21,6 +21,7 @@ namespace BizHawk.Client.Common
bool? PreviousSNES_InSnes9x { get; set; }
void HandleMovieOnFrameLoop();
void HandleMovieAfterFrameLoop();
void HandleMovieSaveState(TextWriter writer);
bool HandleMovieLoadState(string path);

View File

@ -313,7 +313,6 @@ namespace BizHawk.Client.Common
_log.Add(lg.EmptyEntry);
Changes = true;
InvalidateAfter(oldLength - 1);
ChangeLog.SetGeneralRedo();
if (endBatch)

View File

@ -2802,6 +2802,8 @@ namespace BizHawk.Client.EmuHawk
Global.Emulator.FrameAdvance(render, renderSound);
}
Global.MovieSession.HandleMovieAfterFrameLoop();
GlobalWin.DisplayManager.NeedsToPaint = true;
Global.CheatList.Pulse();

View File

@ -694,7 +694,7 @@ namespace BizHawk.Client.EmuHawk
ret = columnList.Count - 1;
}
else
ret = columnList.FindLastIndex(c => c.Left <= DrawWidth);
ret = columnList.FindLastIndex(c => c.Left <= DrawWidth + HBar.Value);
return ret;
}
@ -1562,9 +1562,9 @@ namespace BizHawk.Client.EmuHawk
if (increment)
{
newVal = bar.Value + bar.SmallChange;
if (newVal > bar.Maximum)
if (newVal > bar.Maximum - bar.LargeChange)
{
newVal = bar.Maximum;
newVal = bar.Maximum - bar.LargeChange;
}
}
else
@ -1789,15 +1789,30 @@ namespace BizHawk.Client.EmuHawk
if (HorizontalOrientation)
{
NeedsVScrollbar = columns.Count > DrawHeight / CellHeight;
NeedsHScrollbar = RowCount > (DrawWidth - ColumnWidth) / CellWidth;
NeedsHScrollbar = RowCount > 1;
}
else
{
NeedsVScrollbar = RowCount > DrawHeight / CellHeight;
NeedsVScrollbar = RowCount > 1;
NeedsHScrollbar = TotalColWidth.HasValue && TotalColWidth.Value - DrawWidth + 1 > 0;
}
UpdateDrawSize();
if (VisibleRows > 0)
{
if (HorizontalOrientation)
{
VBar.LargeChange = 10;
HBar.Maximum = Math.Max((VisibleRows - 1) * CellHeight, HBar.Maximum);
HBar.LargeChange = (VisibleRows - 1) * CellHeight;
}
else
{
VBar.Maximum = Math.Max((VisibleRows - 1) * CellHeight, VBar.Maximum); // ScrollBar.Maximum is dumb
VBar.LargeChange = (VisibleRows - 1) * CellHeight;
HBar.LargeChange = 10;
}
}
//Update VBar
if (NeedsVScrollbar)
@ -1808,7 +1823,7 @@ namespace BizHawk.Client.EmuHawk
}
else
{
VBar.Maximum = RowsToPixels(RowCount + 1) - DrawHeight + VBar.LargeChange - 1;
VBar.Maximum = RowsToPixels(RowCount + 1) - (CellHeight * 3) + VBar.LargeChange - 1;
}
VBar.Location = new Point(Width - VBar.Width, 0);
@ -1826,7 +1841,7 @@ namespace BizHawk.Client.EmuHawk
{
if (HorizontalOrientation)
{
HBar.Maximum = RowsToPixels(RowCount + 1) - DrawWidth + HBar.LargeChange - 1;
HBar.Maximum = RowsToPixels(RowCount + 1) - (CellHeight * 3) + HBar.LargeChange - 1;
}
else
{

View File

@ -176,5 +176,16 @@ namespace BizHawk.Client.EmuHawk
RemoveBtn_Click(null, null);
}
}
public int SelectedMarkerFrame()
{
if (MarkerView.SelectedRows.Any())
{
var index = MarkerView.SelectedRows.First();
var marker = Tastudio.CurrentTasMovie.Markers[index];
return marker.Frame;
}
return -1;
}
}
}

View File

@ -13,7 +13,7 @@ namespace BizHawk.Client.EmuHawk
{
public partial class PlaybackBox : UserControl
{
private bool _programmaticallyChangingValue = false;
private bool _loading = true;
public TAStudio Tastudio { get; set; }
@ -71,8 +71,6 @@ namespace BizHawk.Client.EmuHawk
{
base.OnLoad(e);
_programmaticallyChangingValue = true;
if (Global.Config != null) // For the designer
{
TurboSeekCheckbox.Checked = Global.Config.TurboSeek;
@ -84,7 +82,7 @@ namespace BizHawk.Client.EmuHawk
FollowCursorCheckbox.Checked = Tastudio.Settings.FollowCursor;
}
_programmaticallyChangingValue = false;
_loading = false;
}
private void PreviousMarkerButton_Click(object sender, EventArgs e)
@ -114,7 +112,7 @@ namespace BizHawk.Client.EmuHawk
private void TurboSeekCheckbox_CheckedChanged(object sender, EventArgs e)
{
if (!_programmaticallyChangingValue)
if (!_loading)
{
Global.Config.TurboSeek ^= true;
}
@ -122,7 +120,7 @@ namespace BizHawk.Client.EmuHawk
private void AutoRestoreCheckbox_CheckedChanged(object sender, EventArgs e)
{
if (!_programmaticallyChangingValue)
if (!_loading)
{
Tastudio.Settings.AutoRestoreLastPosition ^= true;
}
@ -130,10 +128,10 @@ namespace BizHawk.Client.EmuHawk
private void FollowCursorCheckbox_CheckedChanged(object sender, EventArgs e)
{
Tastudio.Settings.FollowCursor ^= true;
if (!_programmaticallyChangingValue)
if (!_loading)
{
Tastudio.Settings.FollowCursor ^= true;
if (Tastudio.Settings.FollowCursor)
{
Tastudio.SetVisibleIndex();

View File

@ -168,6 +168,7 @@ namespace BizHawk.Client.EmuHawk
this.StartFromNowSeparator = new System.Windows.Forms.ToolStripSeparator();
this.StartNewProjectFromNowMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.ScrollToMarkerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.TASMenu.SuspendLayout();
this.TasStatusStrip.SuspendLayout();
this.MarkerContextMenu.SuspendLayout();
@ -1083,31 +1084,32 @@ namespace BizHawk.Client.EmuHawk
// MarkerContextMenu
//
this.MarkerContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.ScrollToMarkerToolStripMenuItem,
this.EditMarkerContextMenuItem,
this.AddMarkerContextMenuItem,
this.RemoveMarkerContextMenuItem});
this.MarkerContextMenu.Name = "MarkerContextMenu";
this.MarkerContextMenu.Size = new System.Drawing.Size(118, 70);
this.MarkerContextMenu.Size = new System.Drawing.Size(153, 114);
this.MarkerContextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.MarkerContextMenu_Opening);
//
// EditMarkerContextMenuItem
//
this.EditMarkerContextMenuItem.Name = "EditMarkerContextMenuItem";
this.EditMarkerContextMenuItem.Size = new System.Drawing.Size(117, 22);
this.EditMarkerContextMenuItem.Size = new System.Drawing.Size(152, 22);
this.EditMarkerContextMenuItem.Text = "Edit";
this.EditMarkerContextMenuItem.Click += new System.EventHandler(this.EditMarkerContextMenuItem_Click);
//
// AddMarkerContextMenuItem
//
this.AddMarkerContextMenuItem.Name = "AddMarkerContextMenuItem";
this.AddMarkerContextMenuItem.Size = new System.Drawing.Size(117, 22);
this.AddMarkerContextMenuItem.Size = new System.Drawing.Size(152, 22);
this.AddMarkerContextMenuItem.Text = "Add";
this.AddMarkerContextMenuItem.Click += new System.EventHandler(this.AddMarkerContextMenuItem_Click);
//
// RemoveMarkerContextMenuItem
//
this.RemoveMarkerContextMenuItem.Name = "RemoveMarkerContextMenuItem";
this.RemoveMarkerContextMenuItem.Size = new System.Drawing.Size(117, 22);
this.RemoveMarkerContextMenuItem.Size = new System.Drawing.Size(152, 22);
this.RemoveMarkerContextMenuItem.Text = "Remove";
this.RemoveMarkerContextMenuItem.Click += new System.EventHandler(this.RemoveMarkerContextMenuItem_Click);
//
@ -1314,6 +1316,13 @@ namespace BizHawk.Client.EmuHawk
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Markers";
//
// scrollToToolStripMenuItem
//
this.ScrollToMarkerToolStripMenuItem.Name = "scrollToToolStripMenuItem";
this.ScrollToMarkerToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.ScrollToMarkerToolStripMenuItem.Text = "Scroll To";
this.ScrollToMarkerToolStripMenuItem.Click += new System.EventHandler(this.ScrollToMarkerToolStripMenuItem_Click);
//
// TAStudio
//
this.AllowDrop = true;
@ -1488,5 +1497,6 @@ namespace BizHawk.Client.EmuHawk
private System.Windows.Forms.ToolStripMenuItem scrollToTopToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem scrollToBottomToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem scrollToCenterToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem ScrollToMarkerToolStripMenuItem;
}
}

View File

@ -191,6 +191,7 @@ namespace BizHawk.Client.EmuHawk
}
catch (Exception ex)
{
System.Diagnostics.Debugger.Break();
text = string.Empty;
MessageBox.Show("oops\n" + ex);
}

View File

@ -878,7 +878,7 @@ namespace BizHawk.Client.EmuHawk
menuItem.CheckedChanged += (o, ev) =>
{
var sender = o as ToolStripMenuItem;
ToolStripMenuItem sender = o as ToolStripMenuItem;
TasView.AllColumns.Find(c => c.Name == (string)sender.Tag).Visible = sender.Checked;
TasView.AllColumns.ColumnsChanged();
CurrentTasMovie.FlagChanges();
@ -906,10 +906,10 @@ namespace BizHawk.Client.EmuHawk
ToolStripMenuItem dummyObject = playerMenus[i];
item.CheckedChanged += (o, ev) =>
{
ToolStripMenuItem sender = o as ToolStripMenuItem;
foreach (ToolStripMenuItem menuItem in dummyObject.DropDownItems)
{
(menuItem.Tag as InputRoll.RollColumn).Visible =
(o as ToolStripMenuItem).Checked && menuItem.Checked;
TasView.AllColumns.Find(c => c.Name == (string)menuItem.Tag).Visible = sender.Checked;
}
CurrentTasMovie.FlagChanges();

View File

@ -64,6 +64,8 @@ namespace BizHawk.Client.EmuHawk
get { return Global.MovieSession.Movie as TasMovie; }
}
#region "Initializing"
public TAStudio()
{
InitializeComponent();
@ -87,7 +89,6 @@ namespace BizHawk.Client.EmuHawk
TasView.MultiSelect = true;
TasView.MaxCharactersInHorizontal = 1;
WantsToControlRestartMovie = true;
}
private void InitializeSaveWorker()
@ -124,78 +125,80 @@ namespace BizHawk.Client.EmuHawk
CurrentTasMovie.NewBGWorker(_saveBackgroundWorker);
}
private void TastudioToStopMovie()
private void Tastudio_Load(object sender, EventArgs e)
{
Global.MovieSession.StopMovie(false);
GlobalWin.MainForm.SetMainformMovieInfo();
if (!InitializeOnLoad())
{
Close();
this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
return;
}
SetColumnsFromCurrentStickies();
if (VersionInfo.DeveloperBuild)
{
RightClickMenu.Items.AddRange(TasView.GenerateContextMenuItems().ToArray());
RightClickMenu.Items
.OfType<ToolStripMenuItem>()
.First(t => t.Name == "RotateMenuItem")
.Click += (o, ov) =>
{
CurrentTasMovie.FlagChanges();
};
}
RefreshDialog();
}
private void ConvertCurrentMovieToTasproj()
private bool InitializeOnLoad()
{
Global.MovieSession.Movie.Save();
Global.MovieSession.Movie = Global.MovieSession.Movie.ToTasMovie();
Global.MovieSession.Movie.Save();
Global.MovieSession.Movie.SwitchToRecord();
Settings.RecentTas.Add(Global.MovieSession.Movie.Filename);
}
// Start Scenario 1: A regular movie is active
if (Global.MovieSession.Movie.IsActive && !(Global.MovieSession.Movie is TasMovie))
{
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 == DialogResult.OK)
{
ConvertCurrentMovieToTasproj();
StartNewMovieWrapper(false);
}
else
{
return false;
}
}
private void EngageTastudio()
{
GlobalWin.MainForm.PauseOnFrame = null;
GlobalWin.OSD.AddMessage("TAStudio engaged");
SetTasMovieCallbacks();
SetTextProperty();
GlobalWin.MainForm.PauseEmulator();
GlobalWin.MainForm.RelinquishControl(this);
_originalEndAction = Global.Config.MovieEndAction;
GlobalWin.MainForm.ClearRewindData();
Global.Config.MovieEndAction = MovieEndAction.Record;
GlobalWin.MainForm.SetMainformMovieInfo();
}
// Start Scenario 2: A tasproj is already active
else if (Global.MovieSession.Movie.IsActive && Global.MovieSession.Movie is TasMovie)
{
// Nothing to do
}
private void DisengageTastudio()
{
GlobalWin.MainForm.PauseOnFrame = null;
GlobalWin.OSD.AddMessage("TAStudio disengaged");
Global.MovieSession.Movie = MovieService.DefaultInstance;
GlobalWin.MainForm.TakeBackControl();
Global.Config.MovieEndAction = _originalEndAction;
GlobalWin.MainForm.SetMainformMovieInfo();
// Do not keep TAStudio's disk save states.
if (Directory.Exists(PathManager.MakeAbsolutePath(Global.Config.PathEntries["Global", "TAStudio states"].Path, null)))
Directory.Delete(PathManager.MakeAbsolutePath(Global.Config.PathEntries["Global", "TAStudio states"].Path, null), true);
}
// Start Scenario 3: No movie, but user wants to autload their last project
else if (Settings.RecentTas.AutoLoad && !string.IsNullOrEmpty(Settings.RecentTas.MostRecent))
{
var result = LoadProject(Settings.RecentTas.MostRecent);
if (!result)
{
TasView.AllColumns.Clear();
NewDefaultProject();
}
}
private void NewTasMovie()
{
Global.MovieSession.Movie = new TasMovie(false, _saveBackgroundWorker);
SetTasMovieCallbacks();
CurrentTasMovie.PropertyChanged += new PropertyChangedEventHandler(this.TasMovie_OnPropertyChanged);
CurrentTasMovie.Filename = DefaultTasProjName(); // TODO don't do this, take over any mainform actions that can crash without a filename
CurrentTasMovie.PopulateWithDefaultHeaderValues();
CurrentTasMovie.ClearChanges();
TasView.RowCount = 1;
}
// Start Scenario 4: No movie, default behavior of engaging tastudio with a new default project
else
{
NewDefaultProject();
}
/// <summary>
/// Used when starting a new project
/// </summary>
private static string DefaultTasProjName()
{
return Path.Combine(
PathManager.MakeAbsolutePath(Global.Config.PathEntries.MoviesPathFragment, null),
TasMovie.DefaultProjectName + "." + TasMovie.Extension);
}
EngageTastudio();
/// <summary>
/// Used for things like SaveFile dialogs to suggest a name to the user
/// </summary>
/// <returns></returns>
private static string SuggestedTasProjName()
{
return Path.Combine(
PathManager.MakeAbsolutePath(Global.Config.PathEntries.MoviesPathFragment, null),
PathManager.FilesystemSafeName(Global.Game) + "." + TasMovie.Extension);
if (!TasView.AllColumns.Any()) // If a project with column settings has already been loaded we don't need to do this
{
SetUpColumns();
}
return true;
}
private void SetTasMovieCallbacks()
@ -203,147 +206,16 @@ namespace BizHawk.Client.EmuHawk
CurrentTasMovie.ClientSettingsForSave = ClientSettingsForSave;
CurrentTasMovie.GetClientSettingsOnLoad = GetClientSettingsOnLoad;
}
private void StartNewTasMovie()
{
if (AskSaveChanges())
{
NewTasMovie();
WantsToControlStopMovie = false;
StartNewMovieWrapper(record: true);
CurrentTasMovie.ClearChanges();
WantsToControlStopMovie = true;
SetTextProperty();
RefreshDialog();
}
}
private void DummyLoadProject(string path)
{
LoadProject(path);
}
private void DummyLoadMacro(string path)
{
if (!TasView.SelectedRows.Any())
return;
MovieZone loadZone = new MovieZone(path);
if (loadZone != null)
{
loadZone.Start = TasView.FirstSelectedIndex.Value;
loadZone.PlaceZone(CurrentTasMovie);
}
}
private string ClientSettingsForSave()
{
return TasView.UserSettingsSerialized();
}
private void GetClientSettingsOnLoad(string settingsJson)
{
TasView.LoadSettingsSerialized(settingsJson);
RefreshTasView();
}
private void SetTextProperty()
{
var text = "TAStudio";
if (CurrentTasMovie != null)
{
text += " - " + CurrentTasMovie.Name + (CurrentTasMovie.Changes ? "*" : "");
}
if (this.InvokeRequired)
{
this.Invoke(() => Text = text);
}
else
{
Text = text;
}
}
public bool LoadProject(string path)
{
if (AskSaveChanges())
{
var movie = new TasMovie(false, _saveBackgroundWorker)
{
Filename = path,
ClientSettingsForSave = ClientSettingsForSave,
GetClientSettingsOnLoad = GetClientSettingsOnLoad
};
movie.PropertyChanged += TasMovie_OnPropertyChanged;
movie.Load();
var file = new FileInfo(path);
if (!file.Exists)
{
Settings.RecentTas.HandleLoadError(path);
}
WantsToControlStopMovie = false;
var shouldRecord = movie.InputLogLength == 0;
var result = StartNewMovieWrapper(movie: movie, record: shouldRecord);
if (!result)
{
return false;
}
SetTasMovieCallbacks();
WantsToControlStopMovie = true;
Settings.RecentTas.Add(path);
Text = "TAStudio - " + CurrentTasMovie.Name;
RefreshDialog();
return true;
}
return false;
}
public void RefreshDialog()
{
RefreshTasView();
if (MarkerControl != null)
MarkerControl.UpdateValues();
if (undoForm != null)
undoForm.UpdateValues();
}
private void RefreshTasView()
{
CurrentTasMovie.UseInputCache = true;
TasView.RowCount = CurrentTasMovie.InputLogLength + 1;
TasView.Refresh();
CurrentTasMovie.FlushInputCache();
CurrentTasMovie.UseInputCache = false;
}
private void DoAutoRestore()
{
if (Settings.AutoRestoreLastPosition && _autoRestoreFrame.HasValue)
{
if (_autoRestoreFrame > Emulator.Frame) // Don't unpause if we are already on the desired frame, else runaway seek
{
GlobalWin.MainForm.UnpauseEmulator();
GlobalWin.MainForm.PauseOnFrame = _autoRestoreFrame;
}
}
_autoRestoreFrame = null;
}
private void SetUpColumns()
{
TasView.AllColumns.Clear();
@ -412,6 +284,274 @@ namespace BizHawk.Client.EmuHawk
}
}
private void EngageTastudio()
{
GlobalWin.MainForm.PauseOnFrame = null;
GlobalWin.OSD.AddMessage("TAStudio engaged");
SetTasMovieCallbacks();
SetTextProperty();
GlobalWin.MainForm.PauseEmulator();
GlobalWin.MainForm.RelinquishControl(this);
_originalEndAction = Global.Config.MovieEndAction;
GlobalWin.MainForm.ClearRewindData();
Global.Config.MovieEndAction = MovieEndAction.Record;
GlobalWin.MainForm.SetMainformMovieInfo();
}
#endregion
#region "Loading, Saving"
private void ConvertCurrentMovieToTasproj()
{
Global.MovieSession.Movie.Save();
Global.MovieSession.Movie = Global.MovieSession.Movie.ToTasMovie();
Global.MovieSession.Movie.Save();
Global.MovieSession.Movie.SwitchToRecord();
Settings.RecentTas.Add(Global.MovieSession.Movie.Filename);
}
private void NewTasMovie()
{
Global.MovieSession.Movie = new TasMovie(false, _saveBackgroundWorker);
SetTasMovieCallbacks();
CurrentTasMovie.PropertyChanged += new PropertyChangedEventHandler(this.TasMovie_OnPropertyChanged);
CurrentTasMovie.Filename = DefaultTasProjName(); // TODO don't do this, take over any mainform actions that can crash without a filename
CurrentTasMovie.PopulateWithDefaultHeaderValues();
CurrentTasMovie.ClearChanges();
TasView.RowCount = 1;
}
private void StartNewTasMovie()
{
if (AskSaveChanges())
{
NewTasMovie();
WantsToControlStopMovie = false;
StartNewMovieWrapper(record: true);
CurrentTasMovie.ClearChanges();
WantsToControlStopMovie = true;
SetTextProperty();
RefreshDialog();
}
}
public bool LoadProject(string path)
{
if (AskSaveChanges())
{
var movie = new TasMovie(false, _saveBackgroundWorker)
{
Filename = path,
ClientSettingsForSave = ClientSettingsForSave,
GetClientSettingsOnLoad = GetClientSettingsOnLoad
};
movie.PropertyChanged += TasMovie_OnPropertyChanged;
movie.Load();
var file = new FileInfo(path);
if (!file.Exists)
{
Settings.RecentTas.HandleLoadError(path);
}
WantsToControlStopMovie = false;
var shouldRecord = movie.InputLogLength == 0;
var result = StartNewMovieWrapper(movie: movie, record: shouldRecord);
if (!result)
{
return false;
}
SetTasMovieCallbacks();
WantsToControlStopMovie = true;
Settings.RecentTas.Add(path);
Text = "TAStudio - " + CurrentTasMovie.Name;
RefreshDialog();
return true;
}
return false;
}
private void DummyLoadProject(string path)
{
LoadProject(path);
}
private void DummyLoadMacro(string path)
{
if (!TasView.SelectedRows.Any())
return;
MovieZone loadZone = new MovieZone(path);
if (loadZone != null)
{
loadZone.Start = TasView.FirstSelectedIndex.Value;
loadZone.PlaceZone(CurrentTasMovie);
}
}
private void SetColumnsFromCurrentStickies()
{
foreach (var column in TasView.VisibleColumns)
{
if (Global.StickyXORAdapter.IsSticky(column.Name))
{
column.Emphasis = true;
}
}
}
private void NewDefaultProject()
{
NewTasMovie();
StartNewMovieWrapper(record: true);
CurrentTasMovie.TasStateManager.Capture();
CurrentTasMovie.SwitchToRecord();
CurrentTasMovie.ClearChanges();
}
private bool StartNewMovieWrapper(bool record, IMovie movie = null)
{
_initializing = true;
var result = GlobalWin.MainForm.StartNewMovie(movie != null ? movie : CurrentTasMovie, record);
_initializing = false;
return result;
}
private void LoadFile(FileInfo file)
{
CurrentTasMovie.Filename = file.FullName;
try
{
CurrentTasMovie.Load();
}
catch
{
MessageBox.Show(
"Tastudio could not open the file. Due to the loading process, the emulator/Tastudio may be in a unspecified state depending on the error.",
"Tastudio",
MessageBoxButtons.OK);
return;
}
Settings.RecentTas.Add(CurrentTasMovie.Filename);
if (CurrentTasMovie.InputLogLength > 0) // TODO: this is probably reoccuring logic, break off into a function
{
CurrentTasMovie.SwitchToPlay();
}
else
{
CurrentTasMovie.SwitchToRecord();
}
RefreshDialog();
MessageStatusLabel.Text = Path.GetFileName(CurrentTasMovie.Filename) + " loaded.";
}
#endregion
private void TastudioToStopMovie()
{
Global.MovieSession.StopMovie(false);
GlobalWin.MainForm.SetMainformMovieInfo();
}
private void DisengageTastudio()
{
GlobalWin.MainForm.PauseOnFrame = null;
GlobalWin.OSD.AddMessage("TAStudio disengaged");
Global.MovieSession.Movie = MovieService.DefaultInstance;
GlobalWin.MainForm.TakeBackControl();
Global.Config.MovieEndAction = _originalEndAction;
GlobalWin.MainForm.SetMainformMovieInfo();
// Do not keep TAStudio's disk save states.
if (Directory.Exists(PathManager.MakeAbsolutePath(Global.Config.PathEntries["Global", "TAStudio states"].Path, null)))
Directory.Delete(PathManager.MakeAbsolutePath(Global.Config.PathEntries["Global", "TAStudio states"].Path, null), true);
}
/// <summary>
/// Used when starting a new project
/// </summary>
private static string DefaultTasProjName()
{
return Path.Combine(
PathManager.MakeAbsolutePath(Global.Config.PathEntries.MoviesPathFragment, null),
TasMovie.DefaultProjectName + "." + TasMovie.Extension);
}
/// <summary>
/// Used for things like SaveFile dialogs to suggest a name to the user
/// </summary>
/// <returns></returns>
private static string SuggestedTasProjName()
{
return Path.Combine(
PathManager.MakeAbsolutePath(Global.Config.PathEntries.MoviesPathFragment, null),
PathManager.FilesystemSafeName(Global.Game) + "." + TasMovie.Extension);
}
private void SetTextProperty()
{
var text = "TAStudio";
if (CurrentTasMovie != null)
{
text += " - " + CurrentTasMovie.Name + (CurrentTasMovie.Changes ? "*" : "");
}
if (this.InvokeRequired)
{
this.Invoke(() => Text = text);
}
else
{
Text = text;
}
}
public void RefreshDialog()
{
RefreshTasView();
if (MarkerControl != null)
MarkerControl.UpdateValues();
if (undoForm != null)
undoForm.UpdateValues();
}
private void RefreshTasView()
{
CurrentTasMovie.UseInputCache = true;
if (TasView.RowCount != CurrentTasMovie.InputLogLength + 1)
TasView.RowCount = CurrentTasMovie.InputLogLength + 1;
TasView.Refresh();
CurrentTasMovie.FlushInputCache();
CurrentTasMovie.UseInputCache = false;
}
private void DoAutoRestore()
{
if (Settings.AutoRestoreLastPosition && _autoRestoreFrame.HasValue)
{
if (_autoRestoreFrame > Emulator.Frame) // Don't unpause if we are already on the desired frame, else runaway seek
{
GlobalWin.MainForm.UnpauseEmulator();
GlobalWin.MainForm.PauseOnFrame = _autoRestoreFrame;
}
}
_autoRestoreFrame = null;
}
private void StartAtNearestFrameAndEmulate(int frame)
{
CurrentTasMovie.SwitchToPlay();
@ -519,35 +659,6 @@ namespace BizHawk.Client.EmuHawk
// TODO
}
private void SetColumnsFromCurrentStickies()
{
foreach (var column in TasView.VisibleColumns)
{
if (Global.StickyXORAdapter.IsSticky(column.Name))
{
column.Emphasis = true;
}
}
}
private void NewDefaultProject()
{
NewTasMovie();
StartNewMovieWrapper(record: true);
CurrentTasMovie.TasStateManager.Capture();
CurrentTasMovie.SwitchToRecord();
CurrentTasMovie.ClearChanges();
}
private bool StartNewMovieWrapper(bool record, IMovie movie = null)
{
_initializing = true;
var result = GlobalWin.MainForm.StartNewMovie(movie != null ? movie : CurrentTasMovie, record);
_initializing = false;
return result;
}
private void DoTriggeredAutoRestoreIfNeeded()
{
if (_triggerAutoRestore)
@ -568,114 +679,8 @@ namespace BizHawk.Client.EmuHawk
}
}
private void LoadFile(FileInfo file)
{
CurrentTasMovie.Filename = file.FullName;
try
{
CurrentTasMovie.Load();
}
catch
{
MessageBox.Show(
"Tastudio could not open the file. Due to the loading process, the emulator/Tastudio may be in a unspecified state depending on the error.",
"Tastudio",
MessageBoxButtons.OK);
return;
}
Settings.RecentTas.Add(CurrentTasMovie.Filename);
if (CurrentTasMovie.InputLogLength > 0) // TODO: this is probably reoccuring logic, break off into a function
{
CurrentTasMovie.SwitchToPlay();
}
else
{
CurrentTasMovie.SwitchToRecord();
}
RefreshDialog();
MessageStatusLabel.Text = Path.GetFileName(CurrentTasMovie.Filename) + " loaded.";
}
#region Dialog Events
private void Tastudio_Load(object sender, EventArgs e)
{
if (!InitializeOnLoad())
{
Close();
this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
return;
}
SetColumnsFromCurrentStickies();
if (VersionInfo.DeveloperBuild)
{
RightClickMenu.Items.AddRange(TasView.GenerateContextMenuItems().ToArray());
RightClickMenu.Items
.OfType<ToolStripMenuItem>()
.First(t => t.Name == "RotateMenuItem")
.Click += (o, ov) =>
{
CurrentTasMovie.FlagChanges();
};
}
RefreshDialog();
}
private bool InitializeOnLoad()
{
// Start Scenario 1: A regular movie is active
if (Global.MovieSession.Movie.IsActive && !(Global.MovieSession.Movie is TasMovie))
{
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 == DialogResult.OK)
{
ConvertCurrentMovieToTasproj();
StartNewMovieWrapper(false);
}
else
{
return false;
}
}
// Start Scenario 2: A tasproj is already active
else if (Global.MovieSession.Movie.IsActive && Global.MovieSession.Movie is TasMovie)
{
// Nothing to do
}
// Start Scenario 3: No movie, but user wants to autload their last project
else if (Settings.RecentTas.AutoLoad && !string.IsNullOrEmpty(Settings.RecentTas.MostRecent))
{
var result = LoadProject(Settings.RecentTas.MostRecent);
if (!result)
{
TasView.AllColumns.Clear();
NewDefaultProject();
}
}
// Start Scenario 4: No movie, default behavior of engaging tastudio with a new default project
else
{
NewDefaultProject();
}
EngageTastudio();
if (!TasView.AllColumns.Any()) // If a project with column settings has already been loaded we don't need to do this
{
SetUpColumns();
}
return true;
}
private void Tastudio_Closing(object sender, FormClosingEventArgs e)
{
_exiting = true;
@ -740,13 +745,21 @@ namespace BizHawk.Client.EmuHawk
#endregion
#region "Marker Control right-click menu"
private void MarkerContextMenu_Opening(object sender, CancelEventArgs e)
{
EditMarkerContextMenuItem.Enabled =
RemoveMarkerContextMenuItem.Enabled =
ScrollToMarkerToolStripMenuItem.Enabled =
MarkerControl.MarkerInputRoll.SelectedRows.Any();
}
private void ScrollToMarkerToolStripMenuItem_Click(object sender, EventArgs e)
{
SetVisibleIndex(MarkerControl.SelectedMarkerFrame());
RefreshTasView();
}
private void EditMarkerContextMenuItem_Click(object sender, EventArgs e)
{
MarkerControl.EditMarker();
@ -761,6 +774,7 @@ namespace BizHawk.Client.EmuHawk
{
MarkerControl.RemoveMarker();
}
#endregion
private void AutoAdjustInput()
{
@ -788,5 +802,6 @@ namespace BizHawk.Client.EmuHawk
if (e.KeyCode == Keys.F)
TasPlaybackBox.FollowCursor ^= true;
}
}
}