From 04fafd910d95f05cedf906d753938a8e20983e9d Mon Sep 17 00:00:00 2001 From: SuuperW Date: Tue, 10 Mar 2015 20:06:34 +0000 Subject: [PATCH] Macro tool now seems to work when TAStudio is open. --- .../tools/Macros/MacroInput.cs | 2 +- .../tools/Macros/MovieZone.cs | 109 +++++++++++++++--- 2 files changed, 95 insertions(+), 16 deletions(-) diff --git a/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs b/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs index c8df550e93..7bd1f8235d 100644 --- a/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs +++ b/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs @@ -122,7 +122,7 @@ namespace BizHawk.Client.EmuHawk return; } - MovieZone newZone = new MovieZone(CurrentTasMovie, (int)StartNum.Value, (int)(EndNum.Value - StartNum.Value)); + MovieZone newZone = new MovieZone(CurrentTasMovie, (int)StartNum.Value, (int)(EndNum.Value - StartNum.Value + 1)); newZone.Name = "Zone " + zones.Count; zones.Add(newZone); ZonesList.Items.Add(newZone.Name + " - length: " + newZone.Length); diff --git a/BizHawk.Client.EmuHawk/tools/Macros/MovieZone.cs b/BizHawk.Client.EmuHawk/tools/Macros/MovieZone.cs index 3fd821912a..f26dd589c2 100644 --- a/BizHawk.Client.EmuHawk/tools/Macros/MovieZone.cs +++ b/BizHawk.Client.EmuHawk/tools/Macros/MovieZone.cs @@ -6,6 +6,7 @@ using System.IO; using BizHawk.Client.Common; using BizHawk.Emulation.Common; +using BizHawk.Client.Common.InputAdapterExtensions; namespace BizHawk.Client.EmuHawk { @@ -20,7 +21,6 @@ namespace BizHawk.Client.EmuHawk public bool Replace = true; public bool Overlay = false; - public float defaultFloat = 0f; private Bk2ControllerAdapter controller; private Bk2ControllerAdapter targetController; @@ -30,7 +30,7 @@ namespace BizHawk.Client.EmuHawk } public MovieZone(TasMovie movie, int start, int length, string key = "") { - var lg = Global.MovieSession.LogGeneratorInstance() as Bk2LogEntryGenerator; + Bk2LogEntryGenerator lg = Global.MovieSession.LogGeneratorInstance() as Bk2LogEntryGenerator; lg.SetSource(Global.MovieSession.MovieControllerAdapter); targetController = new Bk2ControllerAdapter(); targetController.Type = Global.Emulator.ControllerDefinition; @@ -56,39 +56,52 @@ namespace BizHawk.Client.EmuHawk } controller = new Bk2ControllerAdapter() { Type = d }; - var logGenerator = new Bk2LogEntryGenerator(""); - logGenerator.SetSource(controller); + Bk2LogEntryGenerator logGenerator = new Bk2LogEntryGenerator(""); + logGenerator.SetSource(targetController); + logGenerator.GenerateLogEntry(); // Reference and create all buttons. for (int i = 0; i < length; i++) { - // Set controller with only the buttons in it's Type. + controller.LatchFromSource(movie.GetInputState(i + start)); + LatchFromSourceButtons(targetController, controller); _log[i] = logGenerator.GenerateLogEntry(); } } public void PlaceZone(TasMovie movie) { + if (Start > movie.InputLogLength) + { // Cannot place a frame here. Find a nice way around this. + return; + } + // TODO: This should probably do something with undo history batches/naming. if (!Replace) movie.InsertEmptyFrame(Start, Length); + Bk2LogEntryGenerator logGenerator = new Bk2LogEntryGenerator(""); + logGenerator.SetSource(targetController); + targetController.SetControllersAsMnemonic(logGenerator.EmptyEntry); if (Overlay) { for (int i = 0; i < Length; i++) - { - // Overlay the frame. Float controls should use the defaultFloat value. + { // Overlay the frames. + targetController.SetControllersAsMnemonic(_log[i]); + ORLatchFromSource(targetController, movie.GetInputState(i + Start)); + movie.SetFrame(i + Start, logGenerator.GenerateLogEntry()); } } else { for (int i = 0; i < Length; i++) - { - // Copy over the frame. (Only using the buttons in controller.Type) + { // Copy over the frame. + targetController.SetControllersAsMnemonic(_log[i]); + movie.SetFrame(i + Start, logGenerator.GenerateLogEntry()); } } if (movie is TasMovie) // Assume TAStudio is open? { - if (Global.Emulator.Frame < Start) + if (Global.Emulator.Frame > Start) { // TODO: Go to start of macro? Ask TAStudio to do that? @@ -113,23 +126,89 @@ namespace BizHawk.Client.EmuHawk // Save the controller definition/LogKey // Save the controller name and player count. (Only for the user.) // Save whether or not the macro should use overlay input, and/or replace + string[] header = new string[4]; + header[0] = InputKey; + header[1] = Global.Emulator.ControllerDefinition.Name; + header[2] = Global.Emulator.ControllerDefinition.PlayerCount.ToString(); + header[3] = Overlay.ToString() + "," + Replace.ToString(); - File.WriteAllText(fileName, Global.Emulator.ControllerDefinition.Name); - File.AppendAllText(fileName, "\n" + Global.Emulator.ControllerDefinition.PlayerCount); + File.WriteAllLines(fileName, header); File.AppendAllLines(fileName, _log); } public MovieZone(string fileName) { - // If the LogKey contains buttons/controls not accepted by the emulator, tell the user and display the macro's controller name and player count. - if (!File.Exists(fileName)) return; - _log = File.ReadAllLines(fileName); + string[] readText = File.ReadAllLines(fileName); + // If the LogKey contains buttons/controls not accepted by the emulator, + // tell the user and display the macro's controller name and player count + Bk2LogEntryGenerator lg = Global.MovieSession.LogGeneratorInstance() as Bk2LogEntryGenerator; + lg.SetSource(Global.MovieSession.MovieControllerAdapter); + string key = lg.GenerateLogKey(); + key = key.Replace("LogKey:", "").Replace("#", ""); + key = key.Substring(0, key.Length - 1); + string[] emuKeys = key.Split('|'); + string[] macroKeys = readText[0].Split('|'); + for (int i = 0; i < macroKeys.Length; i++) + { + if (!emuKeys.Contains(macroKeys[i])) + { + System.Windows.Forms.MessageBox.Show("The selected macro is not compatible with the current emulator core." + + "\nMacro controller: " + readText[1] + "\nMacro player count: " + readText[2], "Error"); + return; + } + } + + // Settings + string[] settings = readText[3].Split(','); + Overlay = Convert.ToBoolean(settings[0]); + Replace = Convert.ToBoolean(settings[1]); + + _log = new string[readText.Length - 4]; + readText.ToList().CopyTo(4, _log, 0, _log.Length); Length = _log.Length; Start = 0; Name = Path.GetFileNameWithoutExtension(fileName); + + // Adapter + targetController = new Bk2ControllerAdapter(); + targetController.Type = Global.Emulator.ControllerDefinition; + targetController.LatchFromSource(targetController); // Reference and create all buttons } + + #region "Custom Latch" + + public void LatchFromSourceButtons(Bk2ControllerAdapter latching, IController source) + { + foreach (string button in source.Type.BoolButtons) + { + latching[button] = source.IsPressed(button); + } + + foreach (string name in source.Type.FloatControls) + { + latching.SetFloat(name, source.GetFloat(name)); + } + } + + private void ORLatchFromSource(Bk2ControllerAdapter latching, IController source) + { + foreach (string button in latching.Type.BoolButtons) + { + latching[button] |= source.IsPressed(button); + } + + foreach (string name in latching.Type.FloatControls) + { + float sFloat = source.GetFloat(name); + int indexRange = source.Type.FloatControls.IndexOf(name); + if (sFloat == source.Type.FloatRanges[indexRange].Mid) + latching.SetFloat(name, sFloat); + } + } + + #endregion } }