diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj index 9ad7e45111..4584c20b52 100644 --- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj +++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj @@ -123,6 +123,7 @@ + diff --git a/BizHawk.Client.Common/movie/ControllerLookups/MnemonicGenerators.cs b/BizHawk.Client.Common/movie/ControllerLookups/MnemonicGenerators.cs index 128eb45737..d1ab8f583a 100644 --- a/BizHawk.Client.Common/movie/ControllerLookups/MnemonicGenerators.cs +++ b/BizHawk.Client.Common/movie/ControllerLookups/MnemonicGenerators.cs @@ -31,11 +31,17 @@ namespace BizHawk.Client.Common /// string EmptyMnemonicString { get; } + // Analog TODO: this assumes the Generator is boolean /// /// Parses a segment of a full mnemonic string (the content between pipes) /// Note: this assume the pipes are not being passed in! /// IDictionary ParseMnemonicSegment(string mnemonicSegment); + + // Analog Support TODO: this assume the Generator is boolean + //Dictionary GetBoolButtons(); + + Dictionary AvailableMnemonics { get; } } /// @@ -49,6 +55,11 @@ namespace BizHawk.Client.Common /// int Count { get; } + /// + /// Source controller to read input state from + /// + IController Source { get; set; } + /// /// Gets or sets the given port with an IMnemonicGenerator implementation /// Ports are zero based @@ -61,6 +72,18 @@ namespace BizHawk.Client.Common /// Gets an IMnemonicGenerator implementation that represents the buttons and controls on the console itself (Reset, Power, etc) /// IMnemonicGenerator ConsoleControls { get; } + + Dictionary ParseMnemonicString(string mnemonicStr); + + // Analog TODO: this assume the generators are boolean + Dictionary GetBoolButtons(); + + // TODO: this shouldn't be required, refactor MovieRecord + string GenerateMnemonicString(Dictionary buttons); + + string EmptyMnemonic { get; } + + Dictionary AvailableMnemonics { get; } } public class BooleanControllerMnemonicGenerator : IMnemonicGenerator @@ -77,6 +100,14 @@ namespace BizHawk.Client.Common _controllerMnemonics.Add(key, value); } + public Dictionary AvailableMnemonics + { + get + { + return _controllerMnemonics.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + } + } + public IController Source { get; set; } public string ControllerPrefix { get; set; } public string Name diff --git a/BizHawk.Client.Common/movie/ControllerLookups/NesMnemonicGenerator.cs b/BizHawk.Client.Common/movie/ControllerLookups/NesMnemonicGenerator.cs index fecd6977e3..773329468e 100644 --- a/BizHawk.Client.Common/movie/ControllerLookups/NesMnemonicGenerator.cs +++ b/BizHawk.Client.Common/movie/ControllerLookups/NesMnemonicGenerator.cs @@ -2,15 +2,21 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using BizHawk.Emulation.Common; namespace BizHawk.Client.Common { public class NesMnemonicGenerator : IMnemonicPorts { - public NesMnemonicGenerator(bool fds = false, bool isFourscore = false) + public NesMnemonicGenerator(IController source, bool fds = false, bool isFourscore = false) { + Source = source; _isFds = fds; _isFourscore = isFourscore; + + _nesConsoleControls.Source = source; + _fdsConsoleControls.Source = source; + _controllerPorts.ForEach(x => x.Source = source); } public bool FourScoreEnabled @@ -32,6 +38,8 @@ namespace BizHawk.Client.Common get { return _isFourscore ? 4 : 2; } } + public IController Source { get; set; } + // This is probably not necessary, but let's see how things go public IEnumerable AvailableGenerators { @@ -86,6 +94,86 @@ namespace BizHawk.Client.Common } } + #region TODO: nothing specific to this object here, this could be done in a base class + + public Dictionary ParseMnemonicString(string mnemonicStr) + { + var segments = mnemonicStr.Split('|'); + var kvps = new List>(); + var generators = AvailableGenerators.ToList(); + for(int i = 0; i < mnemonicStr.Length; i++) + { + kvps.AddRange(generators[i].ParseMnemonicSegment(segments[i])); + } + + return kvps.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + } + + public Dictionary GetBoolButtons() + { + List generators = AvailableGenerators.ToList(); + + return generators + .SelectMany(mc => mc.AvailableMnemonics) + .ToDictionary(kvp => kvp.Key, kvp => this.Source.IsPressed(kvp.Key)); + } + + // TODO: this shouldn't be required, refactor MovieRecord + public string GenerateMnemonicString(Dictionary buttons) + { + var mnemonics = AvailableMnemonics; + + var sb = new StringBuilder(); + sb.Append('|'); + + foreach (var generator in AvailableGenerators) + { + foreach (var blah in generator.AvailableMnemonics) + { + if (buttons.ContainsKey(blah.Key)) + { + sb.Append(buttons[blah.Key] ? blah.Value : '.'); + } + else + { + sb.Append('.'); + } + } + } + + sb.Append('|'); + + return sb.ToString(); + } + + public string EmptyMnemonic + { + get + { + var blah = AvailableGenerators.Select(x => x.EmptyMnemonicString); + return "|" + String.Join("|", blah) + "|"; + } + } + + // TODO: refactor me! + public Dictionary AvailableMnemonics + { + get + { + var kvps = new List>(); + foreach (var blah in AvailableGenerators) + { + foreach (var blah2 in blah.AvailableMnemonics) + { + kvps.Add(blah2); + } + } + + return kvps.ToDictionary(x => x.Key, x => x.Value); + } + } + #endregion + #endregion #region Privates @@ -114,7 +202,6 @@ namespace BizHawk.Client.Common } ) { - Source = Global.MovieOutputHardpoint, ControllerPrefix = String.Empty }; @@ -130,7 +217,6 @@ namespace BizHawk.Client.Common } ) { - Source = Global.MovieOutputHardpoint, ControllerPrefix = String.Empty }; @@ -139,22 +225,18 @@ namespace BizHawk.Client.Common { new BooleanControllerMnemonicGenerator("Player 1", _basicController) { - Source = Global.MovieOutputHardpoint, ControllerPrefix = "P1" }, new BooleanControllerMnemonicGenerator("Player 2", _basicController) { - Source = Global.MovieOutputHardpoint, ControllerPrefix = "P2" }, new BooleanControllerMnemonicGenerator("Player 3", _basicController) { - Source = Global.MovieOutputHardpoint, ControllerPrefix = "P3" }, new BooleanControllerMnemonicGenerator("Player 4", _basicController) { - Source = Global.MovieOutputHardpoint, ControllerPrefix = "P4" } }; diff --git a/BizHawk.Client.Common/movie/NewMnemonicsGenerator.cs b/BizHawk.Client.Common/movie/NewMnemonicsGenerator.cs index d448cd4665..adc39df850 100644 --- a/BizHawk.Client.Common/movie/NewMnemonicsGenerator.cs +++ b/BizHawk.Client.Common/movie/NewMnemonicsGenerator.cs @@ -8,6 +8,7 @@ using BizHawk.Emulation.Common; namespace BizHawk.Client.Common { // Used with the version 2 movie implementation (TasMovie.cs) + /* public class NewMnemonicsGenerator { public MnemonicLookupTable MnemonicLookup { get; private set; } @@ -157,4 +158,5 @@ namespace BizHawk.Client.Common } } } + */ } diff --git a/BizHawk.Client.Common/movie/TasMovie.cs b/BizHawk.Client.Common/movie/TasMovie.cs index 0d264890de..6b1ade0da9 100644 --- a/BizHawk.Client.Common/movie/TasMovie.cs +++ b/BizHawk.Client.Common/movie/TasMovie.cs @@ -13,7 +13,7 @@ namespace BizHawk.Client.Common // TODO: preloading, or benchmark and see how much of a performaance gain it really is // TODO: support loop Offset // TODO: consider the fileformat of binary and lagged data - private readonly NewMnemonicsGenerator _mg; + private readonly IMnemonicPorts _mg; private readonly IController _source = Global.MovieOutputHardpoint; public MovieRecord this[int index] @@ -27,8 +27,7 @@ namespace BizHawk.Client.Common { get { - var mg = new NewMnemonicsGenerator(_source) { ActivePlayers = this.ActivePlayers }; - return mg.AvailableMnemonics; + return _mg.AvailableMnemonics; } } @@ -89,14 +88,13 @@ namespace BizHawk.Client.Common public TasMovie(bool startsFromSavestate = false) { + _mg = MnemonicGeneratorFactory.Generate(); Filename = String.Empty; Header = new MovieHeader { StartsFromSavestate = startsFromSavestate }; Header[HeaderKeys.MOVIEVERSION] = HeaderKeys.MovieVersion2; _records = new MovieRecordList(); _mode = Moviemode.Inactive; IsCountingRerecords = true; - - _mg = new NewMnemonicsGenerator(_source); } public string Filename { get; set; }