From b63a34249fc027d3cdf806548bf9ec4bb23ecddc Mon Sep 17 00:00:00 2001 From: adelikat Date: Wed, 16 Jul 2014 23:04:56 +0000 Subject: [PATCH] TAStudio - add the notion of the "pending" frame, the frame about to be emulated, for which you can click to add input that will be captured into the movie the next frame. Logic is still wonky when switching from play to record at the end of a movie, and frame 0 is still messed up but that's a different problem --- .../inputAdapters/InputAdapters.cs | 12 +++ .../movie/tasproj/TasMovie.cs | 15 ++- .../movie/tasproj/TasStateManager.cs | 8 ++ .../tools/TAStudio/TAStudio.IToolForm.cs | 2 +- .../tools/TAStudio/TAStudio.ListView.cs | 94 +++++++++++++++---- .../tools/TAStudio/TAStudio.cs | 9 +- 6 files changed, 116 insertions(+), 24 deletions(-) diff --git a/BizHawk.Client.Common/inputAdapters/InputAdapters.cs b/BizHawk.Client.Common/inputAdapters/InputAdapters.cs index 2dfa295cf6..f95b1db824 100644 --- a/BizHawk.Client.Common/inputAdapters/InputAdapters.cs +++ b/BizHawk.Client.Common/inputAdapters/InputAdapters.cs @@ -66,6 +66,18 @@ namespace BizHawk.Client.Common } } + public void SetBool(string button, bool value) + { + if (value) + { + _pressed.Remove(button); + } + else + { + _pressed.Add(button); + } + } + private readonly HashSet _pressed = new HashSet(); } diff --git a/BizHawk.Client.Common/movie/tasproj/TasMovie.cs b/BizHawk.Client.Common/movie/tasproj/TasMovie.cs index 15f1ea42bc..0b40d86d3f 100644 --- a/BizHawk.Client.Common/movie/tasproj/TasMovie.cs +++ b/BizHawk.Client.Common/movie/tasproj/TasMovie.cs @@ -83,11 +83,17 @@ namespace BizHawk.Client.Common public string DisplayValue(int frame, string buttonName) { var adapter = GetInputState(frame); + return CreateDisplayValueForButton(adapter, buttonName); + } + + public static string CreateDisplayValueForButton(IController adapter, string buttonName) + { + var mnemonics = new Bk2MnemonicConstants(); if (adapter.Type.BoolButtons.Contains(buttonName)) { return adapter.IsPressed(buttonName) ? - Mnemonics[buttonName].ToString() : + mnemonics[buttonName].ToString() : string.Empty; } @@ -215,7 +221,12 @@ namespace BizHawk.Client.Common { get { - return StateManager.Last.Key; + if (StateManager.StateCount > 0) + { + return StateManager.Last.Key; + } + + return 0; } } } diff --git a/BizHawk.Client.Common/movie/tasproj/TasStateManager.cs b/BizHawk.Client.Common/movie/tasproj/TasStateManager.cs index fd5b1ad229..e2285d973d 100644 --- a/BizHawk.Client.Common/movie/tasproj/TasStateManager.cs +++ b/BizHawk.Client.Common/movie/tasproj/TasStateManager.cs @@ -146,6 +146,14 @@ namespace BizHawk.Client.Common } } + public int StateCount + { + get + { + return States.Count; + } + } + public KeyValuePair Last { get { return States.Last(); } diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IToolForm.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IToolForm.cs index a6358f4f95..aa089b8613 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IToolForm.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IToolForm.cs @@ -14,7 +14,7 @@ namespace BizHawk.Client.EmuHawk return; } - TasView.ItemCount = _tas.InputLogLength; + RefreshDialog(); if (_tas.IsRecording) { TasView.ensureVisible(_tas.InputLogLength - 1); diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs index d1984d382e..ff31d6b4cd 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs @@ -17,35 +17,52 @@ namespace BizHawk.Client.EmuHawk private bool _startFrameDrag; private bool _rightMouseHeld = false; - private Color CurrentFrame_FrameCol = Color.FromArgb(0xCFEDFC); - private Color CurrentFrame_InputLog = Color.FromArgb(0xB5E7F7); + private readonly Color CurrentFrame_FrameCol = Color.FromArgb(0xCFEDFC); + private readonly Color CurrentFrame_InputLog = Color.FromArgb(0xB5E7F7); - private Color GreenZone_FrameCol = Color.FromArgb(0xDDFFDD); - private Color GreenZone_InputLog = Color.FromArgb(0xC4F7C8); + private readonly Color GreenZone_FrameCol = Color.FromArgb(0xDDFFDD); + private readonly Color GreenZone_InputLog = Color.FromArgb(0xC4F7C8); - private Color LagZone_FrameCol = Color.FromArgb(0xFFDCDD); - private Color LagZone_InputLog = Color.FromArgb(0xF0D0D2); + private readonly Color LagZone_FrameCol = Color.FromArgb(0xFFDCDD); + private readonly Color LagZone_InputLog = Color.FromArgb(0xF0D0D2); - private Color NoState_GreenZone_FrameCol = Color.FromArgb(0xF9FFF9); - private Color NoState_GreenZone_InputLog = Color.FromArgb(0xE0FBE0); + private readonly Color NoState_GreenZone_FrameCol = Color.FromArgb(0xF9FFF9); + private readonly Color NoState_GreenZone_InputLog = Color.FromArgb(0xE0FBE0); - private Color NoState_LagZone_FrameCol = Color.FromArgb(0xFFE9E9); - private Color NoState_LagZone_InputLog = Color.FromArgb(0xF0D0D2); + private readonly Color NoState_LagZone_FrameCol = Color.FromArgb(0xFFE9E9); + private readonly Color NoState_LagZone_InputLog = Color.FromArgb(0xF0D0D2); - private Color Marker_FrameCol = Color.FromArgb(0xF7FFC9); + private readonly Color Marker_FrameCol = Color.FromArgb(0xF7FFC9); #region Query callbacks private void TasView_QueryItemBkColor(int index, int column, ref Color color) { - var record = _tas[index]; var columnName = TasView.Columns[column].Name; + // Marker Column is white regardless if (columnName == MarkerColumnName) { color = Color.White; + return; } - else if (columnName == FrameColumnName) + + // "pending" frame logic + if (index == Global.Emulator.Frame && index == _tas.InputLogLength) + { + if (columnName == FrameColumnName) + { + color = CurrentFrame_FrameCol; + } + + color = CurrentFrame_InputLog; + + return; + } + + var record = _tas[index]; + + if (columnName == FrameColumnName) { if (Global.Emulator.Frame == index) { @@ -104,6 +121,7 @@ namespace BizHawk.Client.EmuHawk { try { + text = string.Empty; var columnName = TasView.Columns[column].Name; if (columnName == MarkerColumnName) @@ -116,7 +134,16 @@ namespace BizHawk.Client.EmuHawk } else { - text = _tas.DisplayValue(index, columnName); + if (index < _tas.InputLogLength) + { + text = _tas.DisplayValue(index, columnName); + } + else if (Global.Emulator.Frame == _tas.InputLogLength) // In this situation we have a "pending" frame for the user to click + { + text = TasMovie.CreateDisplayValueForButton( + Global.ClickyVirtualPadController, + columnName); + } } } catch (Exception ex) @@ -152,7 +179,7 @@ namespace BizHawk.Client.EmuHawk if (Global.MovieSession.MovieControllerAdapter.Type.BoolButtons.Contains(buttonName)) { - _tas.ToggleBoolState(TasView.PointedCell.Row.Value, TasView.PointedCell.Column); + ToggleBoolState(TasView.PointedCell.Row.Value, TasView.PointedCell.Column); GoToLastEmulatedFrameIfNecessary(TasView.PointedCell.Row.Value); TasView.Refresh(); @@ -173,6 +200,34 @@ namespace BizHawk.Client.EmuHawk } } + // TODO: move me + // Sets either the pending frame or the tas input log + private void ToggleBoolState(int frame, string buttonName) + { + if (frame < _tas.InputLogLength) + { + _tas.ToggleBoolState(frame, buttonName); + } + else if (frame == Global.Emulator.Frame && frame == _tas.InputLogLength) + { + Global.ClickyVirtualPadController.Toggle(buttonName); + } + } + + // TODO: move me + // Sets either the pending frame or the tas input log + private void SetBoolState(int frame, string buttonName, bool value) + { + if (frame < _tas.InputLogLength) + { + _tas.SetBoolState(frame, buttonName, value); + } + else if (frame == Global.Emulator.Frame && frame == _tas.InputLogLength) + { + Global.ClickyVirtualPadController.SetBool(buttonName, value); + } + } + private void TasView_MouseUp(object sender, MouseEventArgs e) { _startMarkerDrag = false; @@ -245,7 +300,7 @@ namespace BizHawk.Client.EmuHawk { for (var i = startVal; i < endVal; i++) { - _tas.SetBoolState(i, _startBoolDrawColumn, _boolPaintState); // Notice it uses new row, old column, you can only paint across a single column + SetBoolState(i, _startBoolDrawColumn, _boolPaintState); // Notice it uses new row, old column, you can only paint across a single column GoToLastEmulatedFrameIfNecessary(TasView.PointedCell.Row.Value); } @@ -258,8 +313,11 @@ namespace BizHawk.Client.EmuHawk { for (var i = startVal; i < endVal; i++) { - _tas.SetFloatState(i, _startFloatDrawColumn, _floatPaintState); // Notice it uses new row, old column, you can only paint across a single column - GoToLastEmulatedFrameIfNecessary(TasView.PointedCell.Row.Value); + if (i < _tas.InputLogLength) // TODO: how do we really want to handle the user setting the float state of the pending frame? + { + _tas.SetFloatState(i, _startFloatDrawColumn, _floatPaintState); // Notice it uses new row, old column, you can only paint across a single column + GoToLastEmulatedFrameIfNecessary(TasView.PointedCell.Row.Value); + } } TasView.Refresh(); diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs index 179e053ccb..0cfc8b1c18 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs @@ -212,7 +212,7 @@ namespace BizHawk.Client.EmuHawk public void RefreshDialog() { - TasView.ItemCount = _tas.InputLogLength; + TasView.ItemCount = _tas.InputLogLength + 1; if (MarkerControl != null) { MarkerControl.Refresh(); @@ -222,9 +222,12 @@ namespace BizHawk.Client.EmuHawk // TODO: a better name private void GoToLastEmulatedFrameIfNecessary(int frame) { - if (frame <= _tas.LastEmulatedFrame) + if (frame != Global.Emulator.Frame) // Don't go to a frame if you are already on it! { - GoToFrame(frame); + if (frame <= _tas.LastEmulatedFrame) + { + GoToFrame(frame); + } } }