diff --git a/BizHawk.MultiClient/Global.cs b/BizHawk.MultiClient/Global.cs index bb157e8f88..2d1eb19978 100644 --- a/BizHawk.MultiClient/Global.cs +++ b/BizHawk.MultiClient/Global.cs @@ -236,6 +236,11 @@ namespace BizHawk.MultiClient public static AutoFireStickyXORAdapter AutofireStickyXORAdapter = new AutoFireStickyXORAdapter(); + /// + /// Forces any controller button to Off, useful for things like Joypad.Set + /// + public static ForceOffAdaptor ForceOffAdaptor = new ForceOffAdaptor(); + /// /// will OR together two IControllers /// diff --git a/BizHawk.MultiClient/LuaImplementation.cs b/BizHawk.MultiClient/LuaImplementation.cs index 3659e2694a..243b989ca5 100644 --- a/BizHawk.MultiClient/LuaImplementation.cs +++ b/BizHawk.MultiClient/LuaImplementation.cs @@ -2117,15 +2117,82 @@ namespace BizHawk.MultiClient { foreach (var button in buttons.Keys) { - if (Convert.ToBoolean(buttons[button]) == true) + bool invert = false; + bool? theValue = null; + string theValueStr = buttons[button].ToString(); + + if (!String.IsNullOrWhiteSpace(theValueStr)) { - if (controller == null) + if (theValueStr.ToLower() == "false") { - Global.ClickyVirtualPadController.Click(button.ToString()); + theValue = false; + } + else if (theValueStr.ToLower() == "true") + { + theValue = true; } else { - Global.ClickyVirtualPadController.Click("P" + controller.ToString() + " " + button.ToString()); + invert = true; + theValue = null; + } + } + else + { + theValue = null; + } + + + if (!invert) + { + if (theValue == true) + { + if (controller == null) //Force On + { + Global.ClickyVirtualPadController.Click(button.ToString()); + Global.ForceOffAdaptor.SetSticky(button.ToString(), false); + } + else + { + Global.ClickyVirtualPadController.Click("P" + controller.ToString() + " " + button.ToString()); + Global.ForceOffAdaptor.SetSticky("P" + controller.ToString() + " " + button.ToString(), false); + } + } + else if (theValue == false) //Force off + { + if (controller == null) + { + Global.ForceOffAdaptor.SetSticky(button.ToString(), true); + } + else + { + Global.ForceOffAdaptor.SetSticky("P" + controller.ToString() + " " + button.ToString(), true); + } + } + else if (theValue == null) + { + //Turn everything off + if (controller == null) + { + Global.ForceOffAdaptor.SetSticky(button.ToString(), false); + } + else + { + Global.ForceOffAdaptor.SetSticky("P" + controller.ToString() + " " + button.ToString(), false); + } + } + } + else //Inverse + { + if (controller == null) + { + Global.StickyXORAdapter.SetSticky(button.ToString(), true); + Global.ForceOffAdaptor.SetSticky(button.ToString(), false); + } + else + { + Global.StickyXORAdapter.SetSticky("P" + controller.ToString() + " " + button.ToString(), true); + Global.ForceOffAdaptor.SetSticky("P" + controller.ToString() + " " + button.ToString(), false); } } } diff --git a/BizHawk.MultiClient/MainForm.cs b/BizHawk.MultiClient/MainForm.cs index 2aefe4f756..f231f64338 100644 --- a/BizHawk.MultiClient/MainForm.cs +++ b/BizHawk.MultiClient/MainForm.cs @@ -1780,7 +1780,9 @@ namespace BizHawk.MultiClient Global.AutofireStickyXORAdapter.Source = Global.StickyXORAdapter; Global.MultitrackRewiringControllerAdapter.Source = Global.AutofireStickyXORAdapter; - Global.MovieInputSourceAdapter.Source = Global.MultitrackRewiringControllerAdapter; + Global.ForceOffAdaptor.Source = Global.MultitrackRewiringControllerAdapter; + + Global.MovieInputSourceAdapter.Source = Global.ForceOffAdaptor; Global.ControllerOutput.Source = Global.MovieOutputHardpoint; Global.Emulator.Controller = Global.ControllerOutput; diff --git a/BizHawk.MultiClient/movie/InputAdapters.cs b/BizHawk.MultiClient/movie/InputAdapters.cs index 86c645906b..0ef72c6cde 100644 --- a/BizHawk.MultiClient/movie/InputAdapters.cs +++ b/BizHawk.MultiClient/movie/InputAdapters.cs @@ -34,6 +34,23 @@ namespace BizHawk.MultiClient Pressed.Add(button); } + public void Unclick(string button) + { + Pressed.Remove(button); + } + + public void Toggle(string button) + { + if (IsPressed(button)) + { + Pressed.Remove(button); + } + else + { + Pressed.Add(button); + } + } + HashSet Pressed = new HashSet(); } @@ -118,9 +135,45 @@ namespace BizHawk.MultiClient } + public class ForceOffAdaptor : IController + { + public bool IsPressed(string button) { return this[button]; } + public float GetFloat(string name) { return 0.0f; } //TODO + public void UpdateControls(int frame) { } + + protected HashSet stickySet = new HashSet(); + public IController Source; + public IController SourceOr; + public ControllerDefinition Type { get { return Source.Type; } set { throw new InvalidOperationException(); } } + + public bool this[string button] + { + get + { + bool source = Source[button]; + if (stickySet.Contains(button)) + { + return false; + } + else + { + return Source[button]; + } + } + set { throw new InvalidOperationException(); } + } + + public void SetSticky(string button, bool isSticky) + { + if (isSticky) + stickySet.Add(button); + else stickySet.Remove(button); + } + } + public class StickyXORAdapter : IController { - private HashSet stickySet = new HashSet(); + protected HashSet stickySet = new HashSet(); public IController Source; public ControllerDefinition Type { get { return Source.Type; } set { throw new InvalidOperationException(); } }