From d1fa71812084edce0451877370703aa9baca42b6 Mon Sep 17 00:00:00 2001 From: Suuper Date: Sat, 3 Oct 2015 09:36:07 -0500 Subject: [PATCH] Put my AutofireStickyXORAdapter back and fixed the bug it had. --- .../inputAdapters/InputAdapters.cs | 543 +++++++++--------- BizHawk.Client.EmuHawk/MainForm.cs | 2 +- .../tools/TAStudio/TAStudio.ListView.cs | 8 +- 3 files changed, 270 insertions(+), 283 deletions(-) diff --git a/BizHawk.Client.Common/inputAdapters/InputAdapters.cs b/BizHawk.Client.Common/inputAdapters/InputAdapters.cs index 70bf6ebdb3..46a31fb849 100644 --- a/BizHawk.Client.Common/inputAdapters/InputAdapters.cs +++ b/BizHawk.Client.Common/inputAdapters/InputAdapters.cs @@ -383,238 +383,139 @@ namespace BizHawk.Client.Common private List _justPressed = new List(); } - /// SuuperW: I'm leaving the old class in case I accidentally screwed something up - /// adelikat: You did, the autofire feature this was controlling, putting it back, fix your class - public class AutoFireStickyXorAdapter : IController, ISticky - { - public int On { get; set; } - public int Off { get; set; } - public WorkingDictionary buttonStarts = new WorkingDictionary(); - public WorkingDictionary lagStarts = new WorkingDictionary(); // TODO: need a data structure not misc dictionaries - - private readonly HashSet _stickySet = new HashSet(); - - public IController Source { get; set; } - - public void SetOnOffPatternFromConfig() - { - On = Global.Config.AutofireOn < 1 ? 0 : Global.Config.AutofireOn; - Off = Global.Config.AutofireOff < 1 ? 0 : Global.Config.AutofireOff; - } - - public AutoFireStickyXorAdapter() - { - //On = Global.Config.AutofireOn < 1 ? 0 : Global.Config.AutofireOn; - //Off = Global.Config.AutofireOff < 1 ? 0 : Global.Config.AutofireOff; - On = 1; - Off = 1; - } - - public bool IsPressed(string button) - { - return this[button]; - } - - public bool this[string button] - { - get - { - var source = Source[button]; - - if (_stickySet.Contains(button)) - { - var lagcount = 0; - if (Global.Emulator.CanPollInput() && Global.Config.AutofireLagFrames) - { - lagcount = Global.Emulator.AsInputPollable().LagCount; - } - - var a = ((Global.Emulator.Frame - lagcount) - (buttonStarts[button] - lagStarts[button])) % (On + Off); - if (a < On) - { - return source ^= true; - } - else - { - return source ^= false; - } - } - - return source; - } - - set - { - throw new InvalidOperationException(); - } - } - - public ControllerDefinition Type { get { return Source.Type; } set { throw new InvalidOperationException(); } } - public bool Locked { get; set; } // Pretty much a hack, - - // dumb passthrough for floats, because autofire doesn't care about them - public float GetFloat(string name) - { - return Source.GetFloat(name); - } - - public void SetSticky(string button, bool isSticky) - { - if (isSticky) - { - _stickySet.Add(button); - buttonStarts.Add(button, Global.Emulator.Frame); - - if (Global.Emulator.CanPollInput()) - { - lagStarts.Add(button, Global.Emulator.AsInputPollable().LagCount); - } - else - { - lagStarts.Add(button, 0); - } - } - else - { - _stickySet.Remove(button); - buttonStarts.Remove(button); - lagStarts.Remove(button); - } - } - - public bool IsSticky(string button) - { - return this._stickySet.Contains(button); - } - - public HashSet CurrentStickies - { - get - { - return this._stickySet; - } - } - - public void ClearStickies() - { - _stickySet.Clear(); - buttonStarts.Clear(); - lagStarts.Clear(); - } - - public void MassToggleStickyState(List buttons) - { - foreach (var button in buttons.Where(button => !_justPressed.Contains(button))) - { - if (_stickySet.Contains(button)) - { - _stickySet.Remove(button); - } - else - { - _stickySet.Add(button); - } - } - - _justPressed = buttons; - } - - /// - /// Determines if a sticky is current mashing the button itself, - /// If sticky is not set then false, if set, it returns true if the Source is not pressed, else false - /// - public bool StickyIsInEffect(string button) - { - if (Source.IsPressed(button)) - { - return false; - } - - return (IsPressed(button)); // Shortcut logic since we know the Source isn't pressed, Ispressed can only return true if the autofire sticky is in effect for this frame - } - - private List _justPressed = new List(); - } - - // commenting this out, it breaks the autofire hotkey + ///// SuuperW: I'm leaving the old class in case I accidentally screwed something up //public class AutoFireStickyXorAdapter : IController, ISticky //{ - // // TODO: Change the AutoHold adapter to be one of these, with an 'Off' value of 0? - // // Probably would have slightly lower performance, but it seems weird to have such a similar class that is only used once. - // private int On; - // private int Off; + // public int On { get; set; } + // public int Off { get; set; } + // public WorkingDictionary buttonStarts = new WorkingDictionary(); + // public WorkingDictionary lagStarts = new WorkingDictionary(); // TODO: need a data structure not misc dictionaries + + // private readonly HashSet _stickySet = new HashSet(); + + // public IController Source { get; set; } + // public void SetOnOffPatternFromConfig() // { // On = Global.Config.AutofireOn < 1 ? 0 : Global.Config.AutofireOn; // Off = Global.Config.AutofireOff < 1 ? 0 : Global.Config.AutofireOff; // } - // private WorkingDictionary _boolPatterns = new WorkingDictionary(); - // private WorkingDictionary _floatPatterns = new WorkingDictionary(); - // public AutoFireStickyXorAdapter() // { - // On = 1; Off = 1; + // //On = Global.Config.AutofireOn < 1 ? 0 : Global.Config.AutofireOn; + // //Off = Global.Config.AutofireOff < 1 ? 0 : Global.Config.AutofireOff; + // On = 1; + // Off = 1; // } - // public IController Source { get; set; } - - // public ControllerDefinition Type - // { - // get { return Source.Type; } - // } - - // public bool Locked { get; set; } // Pretty much a hack, - // public bool IsPressed(string button) // { // return this[button]; // } - // public void SetFloat(string name, float? value, AutoPatternFloat pattern = null) - // { - // if (value.HasValue) - // { - // if (pattern == null) - // pattern = new AutoPatternFloat(value.Value, On, 0, Off); - // _floatPatterns[name] = pattern; - // } - // else - // { - // _floatPatterns.Remove(name); - // } - // } - - // public float GetFloat(string name) - // { - // if (_floatPatterns.ContainsKey(name)) - // return _floatPatterns[name].PeekNextValue(); - - // if (Source == null) - // return 0; - - // return Source.GetFloat(name); - // } - - // public void ClearStickyFloats() - // { - // _floatPatterns.Clear(); - // } - // public bool this[string button] // { // get // { // var source = Source[button]; - // bool patternValue = false; - // if (_boolPatterns.ContainsKey(button)) - // { // I can't figure a way to determine right here if it should Peek or Get. - // patternValue = _boolPatterns[button].PeekNextValue(); + + // if (_stickySet.Contains(button)) + // { + // var lagcount = 0; + // if (Global.Emulator.CanPollInput() && Global.Config.AutofireLagFrames) + // { + // lagcount = Global.Emulator.AsInputPollable().LagCount; + // } + + // var a = ((Global.Emulator.Frame - lagcount) - (buttonStarts[button] - lagStarts[button])) % (On + Off); + // if (a < On) + // { + // return source ^= true; + // } + // else + // { + // return source ^= false; + // } // } - // source ^= patternValue; // return source; // } + + // set + // { + // throw new InvalidOperationException(); + // } + // } + + // public ControllerDefinition Type { get { return Source.Type; } set { throw new InvalidOperationException(); } } + // public bool Locked { get; set; } // Pretty much a hack, + + // // dumb passthrough for floats, because autofire doesn't care about them + // public float GetFloat(string name) + // { + // return Source.GetFloat(name); + // } + + // public void SetSticky(string button, bool isSticky) + // { + // if (isSticky) + // { + // _stickySet.Add(button); + // buttonStarts.Add(button, Global.Emulator.Frame); + + // if (Global.Emulator.CanPollInput()) + // { + // lagStarts.Add(button, Global.Emulator.AsInputPollable().LagCount); + // } + // else + // { + // lagStarts.Add(button, 0); + // } + // } + // else + // { + // _stickySet.Remove(button); + // buttonStarts.Remove(button); + // lagStarts.Remove(button); + // } + // } + + // public bool IsSticky(string button) + // { + // return this._stickySet.Contains(button); + // } + + // public HashSet CurrentStickies + // { + // get + // { + // return this._stickySet; + // } + // } + + // public void ClearStickies() + // { + // _stickySet.Clear(); + // buttonStarts.Clear(); + // lagStarts.Clear(); + // } + + // public void MassToggleStickyState(List buttons) + // { + // foreach (var button in buttons.Where(button => !_justPressed.Contains(button))) + // { + // if (_stickySet.Contains(button)) + // { + // _stickySet.Remove(button); + // } + // else + // { + // _stickySet.Add(button); + // } + // } + + // _justPressed = buttons; // } // /// @@ -623,84 +524,174 @@ namespace BizHawk.Client.Common // /// // public bool StickyIsInEffect(string button) // { - // if (IsSticky(button)) + // if (Source.IsPressed(button)) // { - // return !Source.IsPressed(button); + // return false; // } - // return false; + // return (IsPressed(button)); // Shortcut logic since we know the Source isn't pressed, Ispressed can only return true if the autofire sticky is in effect for this frame // } - // public void SetSticky(string button, bool isSticky, AutoPatternBool pattern = null) - // { - // if (isSticky) - // { - // if (pattern == null) - // pattern = new AutoPatternBool(On, Off); - // _boolPatterns[button] = pattern; - // } - // else - // { - // _boolPatterns.Remove(button); - // } - // } - - // public void Unset(string button) - // { - // _boolPatterns.Remove(button); - // _floatPatterns.Remove(button); - // } - - // public bool IsSticky(string button) - // { - // return _boolPatterns.ContainsKey(button) || _floatPatterns.ContainsKey(button); - // } - - // public HashSet CurrentStickies - // { - // get - // { - // return new HashSet(_boolPatterns.Keys); - // } - // } - - // public void ClearStickies() - // { - // _boolPatterns.Clear(); - // _floatPatterns.Clear(); - // } - - // public void IncrementLoops(bool lagged) - // { - // for (int i = 0; i < _boolPatterns.Count; i++) - // _boolPatterns.ElementAt(i).Value.GetNextValue(lagged); - // for (int i = 0; i < _floatPatterns.Count; i++) - // _floatPatterns.ElementAt(i).Value.GetNextValue(lagged); - // } - - // // SuuperW: What does this even do? I set a breakpoint inside the loop and it wasn't reached. - // private WorkingDictionary _toggledButtons = new WorkingDictionary(); // private List _justPressed = new List(); - // public void MassToggleStickyState(List buttons) - // { - // foreach (var button in buttons.Where(button => !_justPressed.Contains(button))) - // { - // if (_boolPatterns.ContainsKey(button)) - // { - // _toggledButtons[button] = _boolPatterns[button]; - // SetSticky(button, false); - // } - // else - // { - // _boolPatterns[button] = _toggledButtons[button]; - // _toggledButtons.Remove(button); - // } - // } - - // _justPressed = buttons; - // } //} + // commenting this out, it breaks the autofire hotkey + public class AutoFireStickyXorAdapter : IController, ISticky + { + // TODO: Change the AutoHold adapter to be one of these, with an 'Off' value of 0? + // Probably would have slightly lower performance, but it seems weird to have such a similar class that is only used once. + private int On; + private int Off; + public void SetOnOffPatternFromConfig() + { + On = Global.Config.AutofireOn < 1 ? 0 : Global.Config.AutofireOn; + Off = Global.Config.AutofireOff < 1 ? 0 : Global.Config.AutofireOff; + } + + private WorkingDictionary _boolPatterns = new WorkingDictionary(); + private WorkingDictionary _floatPatterns = new WorkingDictionary(); + + public AutoFireStickyXorAdapter() + { + On = 1; Off = 1; + } + + public IController Source { get; set; } + + public ControllerDefinition Type + { + get { return Source.Type; } + } + + public bool Locked { get; set; } // Pretty much a hack, + + public bool IsPressed(string button) + { + return this[button]; + } + + public void SetFloat(string name, float? value, AutoPatternFloat pattern = null) + { + if (value.HasValue) + { + if (pattern == null) + pattern = new AutoPatternFloat(value.Value, On, 0, Off); + _floatPatterns[name] = pattern; + } + else + { + _floatPatterns.Remove(name); + } + } + + public float GetFloat(string name) + { + if (_floatPatterns.ContainsKey(name)) + return _floatPatterns[name].PeekNextValue(); + + if (Source == null) + return 0; + + return Source.GetFloat(name); + } + + public void ClearStickyFloats() + { + _floatPatterns.Clear(); + } + + public bool this[string button] + { + get + { + var source = Source[button]; + bool patternValue = false; + if (_boolPatterns.ContainsKey(button)) + { // I can't figure a way to determine right here if it should Peek or Get. + patternValue = _boolPatterns[button].PeekNextValue(); + } + source ^= patternValue; + + return source; + } + } + + /// + /// Determines if a sticky is current mashing the button itself, + /// If sticky is not set then false, if set, it returns true if the Source is not pressed, else false + /// + public bool StickyIsInEffect(string button) + { + if (IsSticky(button)) + { + return !Source.IsPressed(button); + } + + return false; + } + + public void SetSticky(string button, bool isSticky, AutoPatternBool pattern = null) + { + if (isSticky) + { + if (pattern == null) + pattern = new AutoPatternBool(On, Off); + _boolPatterns[button] = pattern; + } + else + { + _boolPatterns.Remove(button); + } + } + + public void Unset(string button) + { + _boolPatterns.Remove(button); + _floatPatterns.Remove(button); + } + + public bool IsSticky(string button) + { + return _boolPatterns.ContainsKey(button) || _floatPatterns.ContainsKey(button); + } + + public HashSet CurrentStickies + { + get + { + return new HashSet(_boolPatterns.Keys); + } + } + + public void ClearStickies() + { + _boolPatterns.Clear(); + _floatPatterns.Clear(); + } + + public void IncrementLoops(bool lagged) + { + for (int i = 0; i < _boolPatterns.Count; i++) + _boolPatterns.ElementAt(i).Value.GetNextValue(lagged); + for (int i = 0; i < _floatPatterns.Count; i++) + _floatPatterns.ElementAt(i).Value.GetNextValue(lagged); + } + + private List _justPressed = new List(); + public void MassToggleStickyState(List buttons) + { + foreach (var button in buttons.Where(button => !_justPressed.Contains(button))) + { + if (_boolPatterns.ContainsKey(button)) + SetSticky(button, false); + else + SetSticky(button, true); + } + + _justPressed = buttons; + } + } + /// /// Just copies source to sink, or returns whatever a NullController would if it is disconnected. useful for immovable hardpoints. /// diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index a289f4d627..a25d511693 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -2956,7 +2956,7 @@ namespace BizHawk.Client.EmuHawk { Global.AutoFireController.IncrementStarts(); } - //Global.AutofireStickyXORAdapter.IncrementLoops(IsLagFrame); + Global.AutofireStickyXORAdapter.IncrementLoops(IsLagFrame); PressFrameAdvance = false; diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs index f1a1eb98a4..81118050ef 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs @@ -315,9 +315,7 @@ namespace BizHawk.Client.EmuHawk else index += controllerType.BoolButtons.Count - 1; AutoPatternBool p = BoolPatterns[index]; - // adelikat: I broke it - //Global.AutofireStickyXORAdapter.SetSticky(button, isOn.Value, p); - Global.StickyXORAdapter.SetSticky(button, true); + Global.AutofireStickyXORAdapter.SetSticky(button, isOn.Value, p); } else { @@ -328,9 +326,7 @@ namespace BizHawk.Client.EmuHawk float? value = null; if (isOn.Value) value = 0f; AutoPatternFloat p = FloatPatterns[index]; - // adelikat: I broke it - //Global.AutofireStickyXORAdapter.SetFloat(button, value, p); - Global.StickyXORAdapter.SetFloat(button, value); + Global.AutofireStickyXORAdapter.SetFloat(button, value, p); } }