From cde05919add8c5b4808149ae06eba40dc7f712e0 Mon Sep 17 00:00:00 2001 From: "andres.delikat" Date: Tue, 9 Aug 2011 22:13:57 +0000 Subject: [PATCH] Refactor autofire into an autofire controller. Added On & Off values that can be used to create any combination of On/Off patterns, hooked them to Global.Config values --- BizHawk.MultiClient/Config.cs | 2 + BizHawk.MultiClient/Global.cs | 13 +- .../Input/ControllerBinding.cs | 123 ++++++++++++++++-- BizHawk.MultiClient/MainForm.cs | 12 +- 4 files changed, 124 insertions(+), 26 deletions(-) diff --git a/BizHawk.MultiClient/Config.cs b/BizHawk.MultiClient/Config.cs index 45aac71eb8..a8a9601c8f 100644 --- a/BizHawk.MultiClient/Config.cs +++ b/BizHawk.MultiClient/Config.cs @@ -127,6 +127,8 @@ public bool InputConfigAutoTab = true; public bool ShowLogWindow = false; public bool BackupSavestates = true; + public int AutofireOn = 1; + public int AutofireOff = 1; // Run-Control settings public int FrameProgressDelayMs = 500; //how long until a frame advance hold turns into a frame progress? diff --git a/BizHawk.MultiClient/Global.cs b/BizHawk.MultiClient/Global.cs index 453bff1cda..c8b047528c 100644 --- a/BizHawk.MultiClient/Global.cs +++ b/BizHawk.MultiClient/Global.cs @@ -24,11 +24,12 @@ namespace BizHawk.MultiClient public static Controller NullControls; public static CheatList CheatList; - public static Controller AutofireNESControls; - public static Controller AutofireSMSControls; - public static Controller AutofirePCEControls; - public static Controller AutofireGBControls; - public static Controller AutofireGenControls; + public static AutofireController AutofireNullControls; + public static AutofireController AutofireNESControls; + public static AutofireController AutofireSMSControls; + public static AutofireController AutofirePCEControls; + public static AutofireController AutofireGBControls; + public static AutofireController AutofireGenControls; //the movie will be spliced inbetween these if it is present public static CopyControllerAdapter MovieInputSourceAdapter = new CopyControllerAdapter(); @@ -52,7 +53,7 @@ namespace BizHawk.MultiClient public static Controller ActiveController; //rapid fire version on the user controller, has its own key bindings and is OR'ed against ActiveController - public static Controller AutoFireController; + public static AutofireController AutoFireController; //the "output" port for the controller chain. public static CopyControllerAdapter ControllerOutput = new CopyControllerAdapter(); diff --git a/BizHawk.MultiClient/Input/ControllerBinding.cs b/BizHawk.MultiClient/Input/ControllerBinding.cs index 126bd66503..6f8c44faf3 100644 --- a/BizHawk.MultiClient/Input/ControllerBinding.cs +++ b/BizHawk.MultiClient/Input/ControllerBinding.cs @@ -10,9 +10,6 @@ namespace BizHawk.MultiClient private WorkingDictionary> bindings = new WorkingDictionary>(); private WorkingDictionary buttons = new WorkingDictionary(); - private bool autofire = false; - public bool Autofire { get { return false; } set { autofire = value; } } - public Controller(ControllerDefinition definition) { type = definition; @@ -22,16 +19,7 @@ namespace BizHawk.MultiClient public bool this[string button] { get { return IsPressed(button); } } public bool IsPressed(string button) { - if (autofire) - { - int a = Global.Emulator.Frame % 2; - if (a == 1) - return buttons[button]; - else - return false; - } - else - return buttons[button]; + return buttons[button]; } @@ -71,6 +59,114 @@ namespace BizHawk.MultiClient } } + /// + /// merges pressed logical buttons from the supplied controller, effectively ORing it with the current state + /// + public void OR_FromLogical(IController controller) + { + foreach (string button in type.BoolButtons) + { + if (controller.IsPressed(button)) + { + buttons[button] = true; + Console.WriteLine(button); + } + } + } + + public void BindButton(string button, string control) + { + bindings[button].Add(control); + } + + public void BindMulti(string button, string controlString) + { + if (string.IsNullOrEmpty(controlString)) + return; + string[] controlbindings = controlString.Split(','); + foreach (string control in controlbindings) + bindings[button].Add(control.Trim()); + } + } + + + public class AutofireController : IController + { + private ControllerDefinition type; + private WorkingDictionary> bindings = new WorkingDictionary>(); + private WorkingDictionary buttons = new WorkingDictionary(); + + private bool autofire = true; + public bool Autofire { get { return false; } set { autofire = value; } } + public int On { get; set; } + public int Off { get; set; } + + public AutofireController(ControllerDefinition definition) + { + + On = Global.Config.AutofireOn < 1 ? 0 : Global.Config.AutofireOn; + Off = Global.Config.AutofireOff < 1 ? 0 : Global.Config.AutofireOff; + type = definition; + } + + public ControllerDefinition Type { get { return type; } } + public bool this[string button] { get { return IsPressed(button); } } + public bool IsPressed(string button) + { + if (autofire) + { + int a = Global.Emulator.Frame % (On + Off); + if (a < On) + return buttons[button]; + else + return false; + } + else + return buttons[button]; + } + + + public float GetFloat(string name) { throw new NotImplementedException(); } + public void UpdateControls(int frame) { } + + //look for bindings which are activated by the supplied physical button. + public List SearchBindings(string button) + { + var ret = new List(); + foreach (var kvp in bindings) + { + foreach (var bound_button in kvp.Value) + { + if (bound_button == button) + ret.Add(kvp.Key); + } + } + return ret; + } + + int frameStarted = 0; + + /// + /// uses the bindings to latch our own logical button state from the source controller's button state (which are assumed to be the physical side of the binding). + /// this will clobber any existing data (use OR_* or other functions to layer in additional input sources) + /// + public void LatchFromPhysical(IController controller) + { + buttons.Clear(); + foreach (var kvp in bindings) + { + buttons[kvp.Key] = false; + foreach (var bound_button in kvp.Value) + { + if (buttons[kvp.Key] == false && controller[bound_button] == true) + frameStarted = Global.Emulator.Frame; + else + frameStarted = 0; + if (controller[bound_button]) + buttons[kvp.Key] = true; + } + } + } /// /// merges pressed logical buttons from the supplied controller, effectively ORing it with the current state @@ -100,6 +196,5 @@ namespace BizHawk.MultiClient foreach (string control in controlbindings) bindings[button].Add(control.Trim()); } - } } \ No newline at end of file diff --git a/BizHawk.MultiClient/MainForm.cs b/BizHawk.MultiClient/MainForm.cs index 1d253cfe02..fb02902189 100644 --- a/BizHawk.MultiClient/MainForm.cs +++ b/BizHawk.MultiClient/MainForm.cs @@ -129,7 +129,7 @@ namespace BizHawk.MultiClient InitControls(); Global.Emulator = new NullEmulator(); Global.ActiveController = Global.NullControls; - Global.AutoFireController = Global.NullControls; + Global.AutoFireController = Global.AutofireNullControls; Global.Sound = new Sound(Handle, Global.DSound); Global.Sound.StartSound(); RewireInputChain(); @@ -503,7 +503,7 @@ namespace BizHawk.MultiClient } Global.SMSControls = smsControls; - var asmsControls = new Controller(SMS.SmsController); + var asmsControls = new AutofireController(SMS.SmsController); asmsControls.Autofire = true; asmsControls.BindMulti("Reset", Global.Config.SmsReset); asmsControls.BindMulti("Pause", Global.Config.SmsPause); @@ -533,7 +533,7 @@ namespace BizHawk.MultiClient } Global.PCEControls = pceControls; - var apceControls = new Controller(PCEngine.PCEngineController); + var apceControls = new AutofireController(PCEngine.PCEngineController); apceControls.Autofire = true; for (int i = 0; i < 5; i++) { @@ -564,7 +564,7 @@ namespace BizHawk.MultiClient } Global.NESControls = nesControls; - var anesControls = new Controller(NES.NESController); + var anesControls = new AutofireController(NES.NESController); anesControls.Autofire = true; for (int i = 0; i < 2 /*TODO*/; i++) @@ -591,7 +591,7 @@ namespace BizHawk.MultiClient gbControls.BindMulti("Start", Global.Config.GBController.Start); Global.GBControls = gbControls; - var agbControls = new Controller(Gameboy.GbController); + var agbControls = new AutofireController(Gameboy.GbController); agbControls.Autofire = true; agbControls.BindMulti("Up", Global.Config.GBAutoController.Up); agbControls.BindMulti("Down", Global.Config.GBAutoController.Down); @@ -1137,7 +1137,7 @@ namespace BizHawk.MultiClient Global.Emulator.Dispose(); Global.Emulator = new NullEmulator(); Global.ActiveController = Global.NullControls; - Global.AutoFireController = Global.NESControls; + Global.AutoFireController = Global.AutofireNullControls; UserMovie.StopMovie(); }