From ba2c345608dbf8277050ec8b9d1dc6458c2f05f1 Mon Sep 17 00:00:00 2001 From: adelikat Date: Sat, 7 Dec 2013 17:29:47 +0000 Subject: [PATCH] TAStudio - better column building and tracking of what has been pressed. Also now allows a variable number of players to be recorded. --- .../BizHawk.Client.Common.csproj | 1 - BizHawk.Client.Common/movie/IMovieRecord.cs | 31 ----- .../movie/MnemonicsGenerator.cs | 117 +++++++++++++++++- BizHawk.Client.Common/movie/MovieRecord.cs | 84 +++++++------ BizHawk.Client.Common/movie/TasMovie.cs | 16 ++- .../tools/TAStudio/TAStudio.Designer.cs | 5 +- .../tools/TAStudio/TAStudio.cs | 40 ++++-- 7 files changed, 205 insertions(+), 89 deletions(-) delete mode 100644 BizHawk.Client.Common/movie/IMovieRecord.cs diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj index c4b8620672..d56325fd9e 100644 --- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj +++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj @@ -124,7 +124,6 @@ - diff --git a/BizHawk.Client.Common/movie/IMovieRecord.cs b/BizHawk.Client.Common/movie/IMovieRecord.cs deleted file mode 100644 index e3fed09c37..0000000000 --- a/BizHawk.Client.Common/movie/IMovieRecord.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Generic; - -namespace BizHawk.Client.Common -{ - /// - /// Represents everything needed for a frame of input - /// - public interface IMovieRecord - { - /// - /// Gets or sets the string representation of the controller input as a series of mnemonics - /// - string Input { get; } - - /// - /// Gets a value indicating whether or not this was a lag frame, - /// where lag is the act of the core failing to poll for input (input on lag frames have no affect) - /// - bool Lagged { get; } - - /// - /// Gets a valude indicating whether or not this record has a captured state - /// - bool HasState { get; } - - /// - /// Gets the Savestate for this frame of input - /// - IEnumerable State { get; } - } -} diff --git a/BizHawk.Client.Common/movie/MnemonicsGenerator.cs b/BizHawk.Client.Common/movie/MnemonicsGenerator.cs index 43d404522b..5757d43490 100644 --- a/BizHawk.Client.Common/movie/MnemonicsGenerator.cs +++ b/BizHawk.Client.Common/movie/MnemonicsGenerator.cs @@ -466,17 +466,130 @@ namespace BizHawk.Client.Common public class NewMnemonicsGenerator { + public MnemonicLookupTable MnemonicLookup { get; private set; } + public IController Source { get; private set; } + + public List ActivePlayers { get; set; } + + public NewMnemonicsGenerator(IController source) + { + MnemonicLookup = new MnemonicLookupTable(); + Source = source; + ActivePlayers = MnemonicLookup[Global.Emulator.SystemId].Select(x => x.Name).ToList(); + } + public bool IsEmpty { - get { return false; } // TODO + get + { + IEnumerable collections = MnemonicLookup[Global.Emulator.SystemId].Where(x => ActivePlayers.Contains(x.Name)); + + foreach (var mc in collections) + { + foreach (var kvp in mc) + { + if (Source.IsPressed(kvp.Key)) + { + return false; + } + } + } + + return true; + } } public string EmptyMnemonic { get { - return String.Empty; // TODO + IEnumerable collections = MnemonicLookup[Global.Emulator.SystemId].Where(x => ActivePlayers.Contains(x.Name)); + StringBuilder sb = new StringBuilder(); + + sb.Append('|'); + foreach (var mc in collections) + { + foreach (var kvp in mc) + { + sb.Append('.'); + } + sb.Append('|'); + } + + return sb.ToString(); } } + + public string MnemonicString + { + get + { + IEnumerable collections = MnemonicLookup[Global.Emulator.SystemId].Where(x => ActivePlayers.Contains(x.Name)); + StringBuilder sb = new StringBuilder(); + + sb.Append('|'); + foreach (var mc in collections) + { + foreach(var kvp in mc) + { + sb.Append(Source.IsPressed(kvp.Key) ? kvp.Value : '.'); + } + sb.Append('|'); + } + + return sb.ToString(); + } + } + + public IEnumerable Mnemonics + { + get + { + IEnumerable collections = MnemonicLookup[Global.Emulator.SystemId].Where(x => ActivePlayers.Contains(x.Name)); + + List mnemonics = new List(); + foreach (var mc in collections) + { + mnemonics.AddRange(mc.Select(x => x.Value)); + } + + return mnemonics; + } + } + + public Dictionary AvailableMnemonics + { + get + { + var buttons = new Dictionary(); + IEnumerable collections = MnemonicLookup[Global.Emulator.SystemId].Where(x => ActivePlayers.Contains(x.Name)); + + foreach (var mc in collections) + { + foreach (var kvp in mc) + { + buttons.Add(kvp.Key, kvp.Value); + } + } + + return buttons; + } + } + + public Dictionary GetBoolButtons() + { + var buttons = new Dictionary(); + IEnumerable collections = MnemonicLookup[Global.Emulator.SystemId].Where(x => ActivePlayers.Contains(x.Name)); + + foreach (var mc in collections) + { + foreach (var kvp in mc) + { + buttons.Add(kvp.Key, Source.IsPressed(kvp.Key)); + } + } + + return buttons; + } } } diff --git a/BizHawk.Client.Common/movie/MovieRecord.cs b/BizHawk.Client.Common/movie/MovieRecord.cs index 9e5194f695..df39296133 100644 --- a/BizHawk.Client.Common/movie/MovieRecord.cs +++ b/BizHawk.Client.Common/movie/MovieRecord.cs @@ -7,25 +7,48 @@ using BizHawk.Emulation.Common; namespace BizHawk.Client.Common { - public class MovieRecord : IMovieRecord + public class MovieRecord { - Dictionary BoolButtons = new Dictionary(); + // TODO: pass in ActivePlayers + // TODO: pass in IController source, probably wasteful though + + private NewMnemonicsGenerator _mg; + private Dictionary _boolButtons = new Dictionary(); private byte[] _state; + public MovieRecord() + { + _mg = new NewMnemonicsGenerator(Global.MovieOutputHardpoint); + } + + public MovieRecord(IController source, bool captureState) + { + _mg = new NewMnemonicsGenerator(source); + SetInput(); + if (captureState) + { + Lagged = Global.Emulator.IsLagFrame; + _state = Global.Emulator.SaveStateBinary(); + } + } + + public List ActivePlayers + { + get + { + return _mg.ActivePlayers; + } + set + { + _mg.ActivePlayers = value; + } + } + public string Input { get { - SimpleController controller = new SimpleController { Type = new ControllerDefinition() }; - foreach (var kvp in BoolButtons) - { - controller["P1 " + kvp.Key] = kvp.Value; // TODO: multi-player, all cores - } - - controller.Type.Name = Global.Emulator.ControllerDefinition.Name; - MnemonicsGenerator mg = new MnemonicsGenerator(); - mg.SetSource(controller); - return mg.GetControllersAsMnemonic(); + return _mg.MnemonicString; } } @@ -35,52 +58,31 @@ namespace BizHawk.Client.Common get { return _state; } } - public bool IsPressed(int player, string mnemonic) + public bool IsPressed(string buttonName) { - return BoolButtons[mnemonic]; // TODO: player + return _boolButtons[buttonName]; } - public void SetInput(IController controller) + public void SetInput() { - var mnemonics = MnemonicConstants.BUTTONS[Global.Emulator.Controller.Type.Name].Select(x => x.Value); - foreach (var mnemonic in mnemonics) - { - BoolButtons[mnemonic] = controller["P1 " + mnemonic]; // TODO: doesn't work on every core, can't do multiplayer - } + _boolButtons.Clear(); + _boolButtons = _mg.GetBoolButtons(); } public void ClearInput() { - foreach (var key in BoolButtons.Keys) - { - BoolButtons[key] = false; - } - } - - public MovieRecord(IController controller, bool captureState) - { - SetInput(controller); - - if (captureState) - { - Lagged = Global.Emulator.IsLagFrame; - _state = Global.Emulator.SaveStateBinary(); - } + _boolButtons.Clear(); } public bool HasState { - get - { - return State.Count() > 0; - } + get { return State.Count() > 0; } } public override string ToString() { - //TODO: consider the fileformat of binary and lagged data - return Input; + return Input; // TODO: consider the fileformat of binary and lagged data } } diff --git a/BizHawk.Client.Common/movie/TasMovie.cs b/BizHawk.Client.Common/movie/TasMovie.cs index d5da21ca0b..557bc19052 100644 --- a/BizHawk.Client.Common/movie/TasMovie.cs +++ b/BizHawk.Client.Common/movie/TasMovie.cs @@ -13,6 +13,8 @@ namespace BizHawk.Client.Common // TODO: preloading, or benchmark and see how much of a performaance gain it really is // TODO: support loop Offset + private IController _source = Global.MovieOutputHardpoint; //TODO: don't do it this way; + public MovieRecord this[int index] { get @@ -21,6 +23,18 @@ namespace BizHawk.Client.Common } } + public List ActivePlayers { get; set; } + + public Dictionary AvailableMnemonics + { + get + { + NewMnemonicsGenerator mg = new NewMnemonicsGenerator(_source); + mg.ActivePlayers = ActivePlayers; + return mg.AvailableMnemonics; + } + } + #region Implementation public TasMovie(string filename, bool startsFromSavestate = false) @@ -199,7 +213,7 @@ namespace BizHawk.Client.Common if (frame < _records.Count) { Changes = true; - _records[frame].SetInput(source); + _records[frame].SetInput(); } } diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs index 2ca259717d..b4b78c1c00 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs @@ -649,8 +649,9 @@ namespace BizHawk.Client.EmuHawk // // TASView // - this.TASView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left))); + this.TASView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.TASView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.Frame, this.Log}); diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs index 682b357487..c824bd2e1d 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs @@ -12,8 +12,8 @@ namespace BizHawk.Client.EmuHawk { public partial class TAStudio : Form, IToolForm { - private const string MarkerColumn = ""; - private const string FrameColumn = "Frame#"; + private const string MarkerColumnName = "MarkerColumn"; + private const string FrameColumnName = "FrameColumn"; private int _defaultWidth; private int _defaultHeight; @@ -98,23 +98,24 @@ namespace BizHawk.Client.EmuHawk { text = String.Empty; var columnName = TASView.Columns[column].Name; + var columnText = TASView.Columns[column].Text; - if (columnName == MarkerColumn) + if (columnName == MarkerColumnName) { - text = "X"; + text = ""; } - else if (columnName == FrameColumn) + else if (columnName == FrameColumnName) { text = index.ToString().PadLeft(5, '0'); } else { - text = _tas[index].IsPressed(1, columnName) ? columnName : String.Empty; + text = _tas[index].IsPressed(columnName) ? columnText : String.Empty; } } catch (Exception ex) { - text = ""; + text = String.Empty; MessageBox.Show("oops\n" + ex.ToString()); } } @@ -138,20 +139,37 @@ namespace BizHawk.Client.EmuHawk LoadConfigSettings(); + + _tas.ActivePlayers = new List { "Player 1", "Player 2" }; SetUpColumns(); } private void SetUpColumns() { TASView.Columns.Clear(); - ToolHelpers.AddColumn(TASView, "", true, 18); - ToolHelpers.AddColumn(TASView, "Frame#", true, 68); + AddColumn(MarkerColumnName, "", 18); + AddColumn(FrameColumnName, "Frame#", 68); var mnemonics = MnemonicConstants.BUTTONS[Global.Emulator.Controller.Type.Name].Select(x => x.Value); - foreach (var mnemonic in mnemonics) + foreach(var kvp in _tas.AvailableMnemonics) { - ToolHelpers.AddColumn(TASView, mnemonic, true, 20); + AddColumn(kvp.Key, kvp.Value.ToString(), 20); + } + } + + public void AddColumn(string columnName, string columnText, int columnWidth) + { + if (TASView.Columns[columnName] == null) + { + var column = new ColumnHeader + { + Name = columnName, + Text = columnText, + Width = columnWidth, + }; + + TASView.Columns.Add(column); } }