Put my AutofireStickyXORAdapter back and fixed the bug it had.

This commit is contained in:
Suuper 2015-10-03 09:36:07 -05:00
parent 5cfc1dae2a
commit d1fa718120
3 changed files with 270 additions and 283 deletions

View File

@ -383,238 +383,139 @@ namespace BizHawk.Client.Common
private List<string> _justPressed = new List<string>();
}
/// 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<string, int> buttonStarts = new WorkingDictionary<string, int>();
public WorkingDictionary<string, int> lagStarts = new WorkingDictionary<string, int>(); // TODO: need a data structure not misc dictionaries
private readonly HashSet<string> _stickySet = new HashSet<string>();
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<string> CurrentStickies
{
get
{
return this._stickySet;
}
}
public void ClearStickies()
{
_stickySet.Clear();
buttonStarts.Clear();
lagStarts.Clear();
}
public void MassToggleStickyState(List<string> buttons)
{
foreach (var button in buttons.Where(button => !_justPressed.Contains(button)))
{
if (_stickySet.Contains(button))
{
_stickySet.Remove(button);
}
else
{
_stickySet.Add(button);
}
}
_justPressed = buttons;
}
/// <summary>
/// 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
/// </summary>
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<string> _justPressed = new List<string>();
}
// 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<string, int> buttonStarts = new WorkingDictionary<string, int>();
// public WorkingDictionary<string, int> lagStarts = new WorkingDictionary<string, int>(); // TODO: need a data structure not misc dictionaries
// private readonly HashSet<string> _stickySet = new HashSet<string>();
// 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<string, AutoPatternBool> _boolPatterns = new WorkingDictionary<string, AutoPatternBool>();
// private WorkingDictionary<string, AutoPatternFloat> _floatPatterns = new WorkingDictionary<string, AutoPatternFloat>();
// 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<string> CurrentStickies
// {
// get
// {
// return this._stickySet;
// }
// }
// public void ClearStickies()
// {
// _stickySet.Clear();
// buttonStarts.Clear();
// lagStarts.Clear();
// }
// public void MassToggleStickyState(List<string> buttons)
// {
// foreach (var button in buttons.Where(button => !_justPressed.Contains(button)))
// {
// if (_stickySet.Contains(button))
// {
// _stickySet.Remove(button);
// }
// else
// {
// _stickySet.Add(button);
// }
// }
// _justPressed = buttons;
// }
// /// <summary>
@ -623,84 +524,174 @@ namespace BizHawk.Client.Common
// /// </summary>
// 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<string> CurrentStickies
// {
// get
// {
// return new HashSet<string>(_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<string, AutoPatternBool> _toggledButtons = new WorkingDictionary<string, AutoPatternBool>();
// private List<string> _justPressed = new List<string>();
// public void MassToggleStickyState(List<string> 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<string, AutoPatternBool> _boolPatterns = new WorkingDictionary<string, AutoPatternBool>();
private WorkingDictionary<string, AutoPatternFloat> _floatPatterns = new WorkingDictionary<string, AutoPatternFloat>();
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;
}
}
/// <summary>
/// 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
/// </summary>
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<string> CurrentStickies
{
get
{
return new HashSet<string>(_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<string> _justPressed = new List<string>();
public void MassToggleStickyState(List<string> buttons)
{
foreach (var button in buttons.Where(button => !_justPressed.Contains(button)))
{
if (_boolPatterns.ContainsKey(button))
SetSticky(button, false);
else
SetSticky(button, true);
}
_justPressed = buttons;
}
}
/// <summary>
/// Just copies source to sink, or returns whatever a NullController would if it is disconnected. useful for immovable hardpoints.
/// </summary>

View File

@ -2956,7 +2956,7 @@ namespace BizHawk.Client.EmuHawk
{
Global.AutoFireController.IncrementStarts();
}
//Global.AutofireStickyXORAdapter.IncrementLoops(IsLagFrame);
Global.AutofireStickyXORAdapter.IncrementLoops(IsLagFrame);
PressFrameAdvance = false;

View File

@ -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);
}
}