2011-06-27 05:31:46 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
|
|
namespace BizHawk.MultiClient
|
|
|
|
|
{
|
2011-07-24 20:23:27 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// will hold buttons for 1 frame and then release them. (Calling Click() from your button click is what you want to do)
|
|
|
|
|
/// TODO - should the duration be controllable?
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class ClickyVirtualPadController : IController
|
|
|
|
|
{
|
|
|
|
|
public ControllerDefinition Type { get; set; }
|
|
|
|
|
public bool this[string button] { get { return IsPressed(button); } }
|
|
|
|
|
public float GetFloat(string name) { return 0.0f; } //TODO
|
|
|
|
|
public void UpdateControls(int frame) { }
|
|
|
|
|
public bool IsPressed(string button)
|
|
|
|
|
{
|
|
|
|
|
return Pressed.Contains(button);
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// call this once per frame to do the timekeeping for the hold and release
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void FrameTick()
|
|
|
|
|
{
|
|
|
|
|
Pressed.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// call this to hold the button down for one frame
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void Click(string button)
|
|
|
|
|
{
|
|
|
|
|
Pressed.Add(button);
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-23 20:34:25 +00:00
|
|
|
|
public void Unclick(string button)
|
|
|
|
|
{
|
|
|
|
|
Pressed.Remove(button);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Toggle(string button)
|
|
|
|
|
{
|
|
|
|
|
if (IsPressed(button))
|
|
|
|
|
{
|
|
|
|
|
Pressed.Remove(button);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Pressed.Add(button);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-15 02:14:14 +00:00
|
|
|
|
readonly HashSet<string> Pressed = new HashSet<string>();
|
2011-07-24 20:23:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-07-10 06:24:04 +00:00
|
|
|
|
//filters input for things called Up and Down while considering the client's AllowUD_LR option.
|
|
|
|
|
//this is a bit gross but it is unclear how to do it more nicely
|
|
|
|
|
public class UD_LR_ControllerAdapter : IController
|
|
|
|
|
{
|
|
|
|
|
public ControllerDefinition Type { get { return Source.Type; } }
|
|
|
|
|
public IController Source;
|
|
|
|
|
|
|
|
|
|
public bool this[string button] { get { return IsPressed(button); } }
|
2013-07-14 16:35:22 +00:00
|
|
|
|
// the float format implies no U+D and no L+R no matter what, so just passthru
|
|
|
|
|
public float GetFloat(string name) { return Source.GetFloat(name); }
|
2011-07-10 06:24:04 +00:00
|
|
|
|
public void UpdateControls(int frame) { }
|
2011-08-09 00:57:56 +00:00
|
|
|
|
|
2011-07-10 06:24:04 +00:00
|
|
|
|
public bool IsPressed(string button)
|
|
|
|
|
{
|
2013-04-15 02:14:14 +00:00
|
|
|
|
if (Global.Config.AllowUD_LR)
|
|
|
|
|
{
|
2011-07-10 06:24:04 +00:00
|
|
|
|
return Source.IsPressed(button);
|
2013-04-15 02:14:14 +00:00
|
|
|
|
}
|
2011-07-10 06:24:04 +00:00
|
|
|
|
|
|
|
|
|
string prefix;
|
|
|
|
|
|
2013-05-06 21:37:30 +00:00
|
|
|
|
if (button.Contains("Down") && !button.Contains(" C "))
|
2011-07-10 06:24:04 +00:00
|
|
|
|
{
|
|
|
|
|
prefix = button.GetPrecedingString("Down");
|
|
|
|
|
if (Source.IsPressed(prefix + "Up"))
|
2013-04-15 02:14:14 +00:00
|
|
|
|
{
|
2011-07-10 06:24:04 +00:00
|
|
|
|
return false;
|
2013-04-15 02:14:14 +00:00
|
|
|
|
}
|
2011-07-10 06:24:04 +00:00
|
|
|
|
}
|
2013-05-06 21:37:30 +00:00
|
|
|
|
if (button.Contains("Right") && !button.Contains(" C "))
|
2011-07-10 06:24:04 +00:00
|
|
|
|
{
|
|
|
|
|
prefix = button.GetPrecedingString("Right");
|
|
|
|
|
if (Source.IsPressed(prefix + "Left"))
|
2013-04-15 02:14:14 +00:00
|
|
|
|
{
|
2011-07-10 06:24:04 +00:00
|
|
|
|
return false;
|
2013-04-15 02:14:14 +00:00
|
|
|
|
}
|
2011-07-10 06:24:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Source.IsPressed(button);
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-07-10 02:14:58 +00:00
|
|
|
|
|
|
|
|
|
public class SimpleController : IController
|
|
|
|
|
{
|
|
|
|
|
public ControllerDefinition Type { get; set; }
|
|
|
|
|
|
|
|
|
|
protected WorkingDictionary<string, bool> Buttons = new WorkingDictionary<string, bool>();
|
2013-07-18 16:18:17 +00:00
|
|
|
|
protected WorkingDictionary<string, float> Floats = new WorkingDictionary<string, float>();
|
2011-07-24 19:52:13 +00:00
|
|
|
|
public virtual bool this[string button] { get { return Buttons[button]; } set { Buttons[button] = value; } }
|
|
|
|
|
public virtual bool IsPressed(string button) { return this[button]; }
|
2013-07-18 16:18:17 +00:00
|
|
|
|
public float GetFloat(string name) { return Floats[name]; }
|
2011-07-24 19:52:13 +00:00
|
|
|
|
public void UpdateControls(int frame) { }
|
2011-08-09 00:57:56 +00:00
|
|
|
|
|
2012-03-24 18:39:55 +00:00
|
|
|
|
public IEnumerable<KeyValuePair<string, bool>> BoolButtons()
|
|
|
|
|
{
|
|
|
|
|
foreach (var kvp in Buttons) yield return kvp;
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-24 19:52:13 +00:00
|
|
|
|
public virtual void LatchFrom(IController source)
|
|
|
|
|
{
|
|
|
|
|
foreach (string button in source.Type.BoolButtons)
|
|
|
|
|
{
|
|
|
|
|
Buttons[button] = source[button];
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-07-18 16:18:17 +00:00
|
|
|
|
|
|
|
|
|
public void AcceptNewFloats(IEnumerable<Tuple<string, float>> NewValues)
|
|
|
|
|
{
|
|
|
|
|
foreach (var sv in NewValues)
|
|
|
|
|
Floats[sv.Item1] = sv.Item2;
|
|
|
|
|
}
|
2011-07-24 19:52:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-08-09 00:51:46 +00:00
|
|
|
|
public class ORAdapter : IController
|
|
|
|
|
{
|
|
|
|
|
public bool IsPressed(string button) { return this[button]; }
|
2013-07-14 16:35:22 +00:00
|
|
|
|
// pass floats solely from the original source
|
|
|
|
|
// this works in the code because SourceOr is the autofire controller
|
|
|
|
|
public float GetFloat(string name) { return Source.GetFloat(name); }
|
2011-08-09 00:51:46 +00:00
|
|
|
|
public void UpdateControls(int frame) { }
|
|
|
|
|
|
|
|
|
|
public IController Source;
|
|
|
|
|
public IController SourceOr;
|
|
|
|
|
public ControllerDefinition Type { get { return Source.Type; } set { throw new InvalidOperationException(); } }
|
2012-02-18 15:49:44 +00:00
|
|
|
|
|
2011-08-09 00:51:46 +00:00
|
|
|
|
public bool this[string button]
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
bool source = Source[button] | SourceOr[button];
|
|
|
|
|
return source;
|
|
|
|
|
}
|
|
|
|
|
set { throw new InvalidOperationException(); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-23 20:34:25 +00:00
|
|
|
|
public class ForceOffAdaptor : IController
|
|
|
|
|
{
|
|
|
|
|
public bool IsPressed(string button) { return this[button]; }
|
2013-07-14 16:35:22 +00:00
|
|
|
|
// what exactly would we want to do here with floats?
|
|
|
|
|
// ForceOffAdaptor is only used by lua, and the code there looks like a big mess...
|
|
|
|
|
public float GetFloat(string name) { return Source.GetFloat(name); }
|
2013-03-23 20:34:25 +00:00
|
|
|
|
public void UpdateControls(int frame) { }
|
|
|
|
|
|
|
|
|
|
protected HashSet<string> stickySet = new HashSet<string>();
|
|
|
|
|
public IController Source;
|
|
|
|
|
public IController SourceOr;
|
|
|
|
|
public ControllerDefinition Type { get { return Source.Type; } set { throw new InvalidOperationException(); } }
|
|
|
|
|
|
|
|
|
|
public bool this[string button]
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-24 19:52:13 +00:00
|
|
|
|
public class StickyXORAdapter : IController
|
|
|
|
|
{
|
2013-03-23 20:34:25 +00:00
|
|
|
|
protected HashSet<string> stickySet = new HashSet<string>();
|
2011-07-24 19:52:13 +00:00
|
|
|
|
public IController Source;
|
|
|
|
|
|
|
|
|
|
public ControllerDefinition Type { get { return Source.Type; } set { throw new InvalidOperationException(); } }
|
2012-09-14 21:31:00 +00:00
|
|
|
|
public bool Locked = false; //Pretty much a hack,
|
2011-07-24 19:52:13 +00:00
|
|
|
|
|
2011-07-10 02:14:58 +00:00
|
|
|
|
public bool IsPressed(string button) { return this[button]; }
|
2013-05-10 23:29:14 +00:00
|
|
|
|
|
2013-07-14 16:35:22 +00:00
|
|
|
|
// if SetFloat() is called (typically virtual pads), then that float will entirely override the Source input
|
|
|
|
|
// otherwise, the source is passed thru.
|
|
|
|
|
WorkingDictionary<string,float?> FloatSet = new WorkingDictionary<string,float?>();
|
2013-08-26 21:35:50 +00:00
|
|
|
|
public void SetFloat(string name, float? value)
|
2013-05-10 23:29:14 +00:00
|
|
|
|
{
|
2013-08-26 21:35:50 +00:00
|
|
|
|
if (value.HasValue)
|
|
|
|
|
FloatSet[name] = value;
|
|
|
|
|
else FloatSet.Remove(name);
|
2013-05-10 23:29:14 +00:00
|
|
|
|
}
|
|
|
|
|
public float GetFloat(string name)
|
|
|
|
|
{
|
2013-07-14 16:35:22 +00:00
|
|
|
|
return FloatSet[name] ?? Source.GetFloat(name);
|
2013-05-10 23:29:14 +00:00
|
|
|
|
}
|
2013-07-14 16:35:22 +00:00
|
|
|
|
public void ClearStickyFloats()
|
|
|
|
|
{
|
|
|
|
|
FloatSet.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2011-07-10 02:14:58 +00:00
|
|
|
|
public void UpdateControls(int frame) { }
|
2011-08-09 00:57:56 +00:00
|
|
|
|
|
2011-07-24 19:52:13 +00:00
|
|
|
|
public bool this[string button] {
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
bool source = Source[button];
|
|
|
|
|
if (source)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
source ^= stickySet.Contains(button);
|
|
|
|
|
return source;
|
|
|
|
|
}
|
|
|
|
|
set { throw new InvalidOperationException(); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetSticky(string button, bool isSticky)
|
|
|
|
|
{
|
|
|
|
|
if(isSticky)
|
|
|
|
|
stickySet.Add(button);
|
|
|
|
|
else stickySet.Remove(button);
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-15 13:11:29 +00:00
|
|
|
|
public bool IsSticky(string button)
|
|
|
|
|
{
|
|
|
|
|
return stickySet.Contains(button);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public HashSet<string> CurrentStickies
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return stickySet;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ClearStickies()
|
|
|
|
|
{
|
|
|
|
|
stickySet.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void MassToggleStickyState(List<string> buttons)
|
|
|
|
|
{
|
|
|
|
|
foreach (string button in buttons)
|
|
|
|
|
{
|
|
|
|
|
if (!JustPressed.Contains(button))
|
|
|
|
|
{
|
|
|
|
|
if (stickySet.Contains(button))
|
|
|
|
|
{
|
|
|
|
|
stickySet.Remove(button);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
stickySet.Add(button);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
JustPressed = buttons;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<string> JustPressed = new List<string>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class AutoFireStickyXORAdapter : IController
|
|
|
|
|
{
|
|
|
|
|
public int On { get; set; }
|
|
|
|
|
public int Off { get; set; }
|
|
|
|
|
public WorkingDictionary<string, int> buttonStarts = new WorkingDictionary<string, int>();
|
|
|
|
|
|
2013-04-15 02:14:14 +00:00
|
|
|
|
private readonly HashSet<string> stickySet = new HashSet<string>();
|
2012-09-15 13:11:29 +00:00
|
|
|
|
|
|
|
|
|
public IController Source;
|
|
|
|
|
|
2012-09-15 13:33:04 +00:00
|
|
|
|
public void SetOnOffPatternFromConfig()
|
|
|
|
|
{
|
|
|
|
|
On = Global.Config.AutofireOn < 1 ? 0 : Global.Config.AutofireOn;
|
|
|
|
|
Off = Global.Config.AutofireOff < 1 ? 0 : Global.Config.AutofireOff;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-15 13:11:29 +00:00
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
if (stickySet.Contains(button))
|
|
|
|
|
{
|
|
|
|
|
int a = (Global.Emulator.Frame - buttonStarts[button]) % (On + Off);
|
|
|
|
|
if (a < On)
|
|
|
|
|
return this[button];
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return Source[button];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool this[string button]
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
bool source = Source[button];
|
|
|
|
|
if (source)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
if (stickySet.Contains(button))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int a = (Global.Emulator.Frame - buttonStarts[button]) % (On + Off);
|
|
|
|
|
if (a < On)
|
|
|
|
|
{
|
|
|
|
|
source ^= true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
source ^= false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return source;
|
|
|
|
|
}
|
|
|
|
|
set { throw new InvalidOperationException(); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public ControllerDefinition Type { get { return Source.Type; } set { throw new InvalidOperationException(); } }
|
|
|
|
|
public bool Locked = false; //Pretty much a hack,
|
|
|
|
|
|
2013-07-14 16:35:22 +00:00
|
|
|
|
// dumb passthrough for floats, because autofire doesn't care about them
|
|
|
|
|
public float GetFloat(string name) { return Source.GetFloat(name); }
|
2012-09-15 13:11:29 +00:00
|
|
|
|
public void UpdateControls(int frame) { }
|
|
|
|
|
|
|
|
|
|
public void SetSticky(string button, bool isSticky)
|
|
|
|
|
{
|
|
|
|
|
if (isSticky)
|
|
|
|
|
stickySet.Add(button);
|
|
|
|
|
else stickySet.Remove(button);
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-24 19:52:13 +00:00
|
|
|
|
public bool IsSticky(string button)
|
|
|
|
|
{
|
|
|
|
|
return stickySet.Contains(button);
|
|
|
|
|
}
|
2012-09-14 21:31:00 +00:00
|
|
|
|
|
|
|
|
|
public HashSet<string> CurrentStickies
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return stickySet;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ClearStickies()
|
|
|
|
|
{
|
|
|
|
|
stickySet.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void MassToggleStickyState(List<string> buttons)
|
|
|
|
|
{
|
|
|
|
|
foreach (string button in buttons)
|
|
|
|
|
{
|
|
|
|
|
if (!JustPressed.Contains(button))
|
|
|
|
|
{
|
|
|
|
|
if (stickySet.Contains(button))
|
|
|
|
|
{
|
|
|
|
|
stickySet.Remove(button);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
stickySet.Add(button);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
JustPressed = buttons;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<string> JustPressed = new List<string>();
|
2011-07-10 02:14:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-06-27 05:31:46 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// just copies source to sink, or returns whatever a NullController would if it is disconnected. useful for immovable hardpoints.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class CopyControllerAdapter : IController
|
|
|
|
|
{
|
|
|
|
|
public IController Source;
|
2013-04-15 02:14:14 +00:00
|
|
|
|
|
|
|
|
|
private readonly NullController _null = new NullController();
|
2011-06-27 05:31:46 +00:00
|
|
|
|
|
2011-07-13 00:18:47 +00:00
|
|
|
|
IController Curr
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (Source == null) return _null;
|
|
|
|
|
else return Source;
|
|
|
|
|
}
|
2011-06-27 05:31:46 +00:00
|
|
|
|
}
|
2011-08-09 00:57:56 +00:00
|
|
|
|
|
2011-07-13 00:18:47 +00:00
|
|
|
|
public ControllerDefinition Type { get { return Curr.Type; } }
|
|
|
|
|
public bool this[string button] { get { return Curr[button]; } }
|
|
|
|
|
public bool IsPressed(string button) { return Curr.IsPressed(button); }
|
|
|
|
|
public float GetFloat(string name) { return Curr.GetFloat(name); }
|
|
|
|
|
public void UpdateControls(int frame) { Curr.UpdateControls(frame); }
|
2011-06-27 05:31:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ButtonNameParser
|
|
|
|
|
{
|
|
|
|
|
ButtonNameParser()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static ButtonNameParser Parse(string button)
|
|
|
|
|
{
|
|
|
|
|
//see if we're being asked for a button that we know how to rewire
|
|
|
|
|
string[] parts = button.Split(' ');
|
|
|
|
|
if (parts.Length < 2) return null;
|
|
|
|
|
if (parts[0][0] != 'P') return null;
|
2013-04-15 02:14:14 +00:00
|
|
|
|
int player;
|
2011-06-27 05:31:46 +00:00
|
|
|
|
if (!int.TryParse(parts[0].Substring(1), out player))
|
2013-04-15 02:14:14 +00:00
|
|
|
|
{
|
2011-06-27 05:31:46 +00:00
|
|
|
|
return null;
|
2013-04-15 02:14:14 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return new ButtonNameParser { PlayerNum = player, ButtonPart = button.Substring(parts[0].Length + 1) };
|
|
|
|
|
}
|
2011-06-27 05:31:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int PlayerNum;
|
|
|
|
|
public string ButtonPart;
|
|
|
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
|
{
|
|
|
|
|
return string.Format("P{0} {1}", PlayerNum, ButtonPart);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// rewires player1 controls to playerN
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class MultitrackRewiringControllerAdapter : IController
|
|
|
|
|
{
|
|
|
|
|
public IController Source;
|
|
|
|
|
public int PlayerSource = 1;
|
|
|
|
|
public int PlayerTargetMask = 0;
|
|
|
|
|
|
2011-07-13 00:18:47 +00:00
|
|
|
|
public ControllerDefinition Type { get { return Source.Type; } }
|
2013-04-15 02:14:14 +00:00
|
|
|
|
public bool this[string button] { get { return IsPressed(button); } }
|
2013-07-14 16:35:22 +00:00
|
|
|
|
// floats can be player number remapped just like boolbuttons
|
|
|
|
|
public float GetFloat(string name) { return Source.GetFloat(RemapButtonName(name)); }
|
2011-07-13 00:18:47 +00:00
|
|
|
|
public void UpdateControls(int frame) { Source.UpdateControls(frame); }
|
2011-08-09 00:57:56 +00:00
|
|
|
|
|
2013-07-14 16:35:22 +00:00
|
|
|
|
string RemapButtonName(string button)
|
2011-06-27 05:31:46 +00:00
|
|
|
|
{
|
|
|
|
|
//do we even have a source?
|
2013-07-14 16:35:22 +00:00
|
|
|
|
if (PlayerSource == -1) return button;
|
2011-06-27 05:31:46 +00:00
|
|
|
|
|
|
|
|
|
//see if we're being asked for a button that we know how to rewire
|
|
|
|
|
ButtonNameParser bnp = ButtonNameParser.Parse(button);
|
2013-07-14 16:35:22 +00:00
|
|
|
|
if (bnp == null) return button;
|
2011-06-27 05:31:46 +00:00
|
|
|
|
|
|
|
|
|
//ok, this looks like a normal `P1 Button` type thing. we can handle it
|
|
|
|
|
//were we supposed to replace this one?
|
|
|
|
|
int foundPlayerMask = (1 << bnp.PlayerNum);
|
2013-07-14 16:35:22 +00:00
|
|
|
|
if ((PlayerTargetMask & foundPlayerMask) == 0) return button;
|
2011-06-27 05:31:46 +00:00
|
|
|
|
//ok, we were. swap out the source player and then grab his button
|
|
|
|
|
bnp.PlayerNum = PlayerSource;
|
2013-07-14 16:35:22 +00:00
|
|
|
|
return bnp.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsPressed(string button)
|
|
|
|
|
{
|
|
|
|
|
return Source.IsPressed(RemapButtonName(button));
|
2011-06-27 05:31:46 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//not being used..
|
|
|
|
|
|
|
|
|
|
///// <summary>
|
|
|
|
|
///// adapts an IController to force some buttons to a different state.
|
|
|
|
|
///// unforced button states will flow through to the adaptee
|
|
|
|
|
///// </summary>
|
|
|
|
|
//public class ForceControllerAdapter : IController
|
|
|
|
|
//{
|
|
|
|
|
// public IController Controller;
|
|
|
|
|
|
|
|
|
|
// public Dictionary<string, bool> Forces = new Dictionary<string, bool>();
|
|
|
|
|
// public void Clear()
|
|
|
|
|
// {
|
|
|
|
|
// Forces.Clear();
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// public ControllerDefinition Type { get { return Controller.Type; } }
|
|
|
|
|
|
|
|
|
|
// public bool this[string button] { get { return IsPressed(button); } }
|
|
|
|
|
|
|
|
|
|
// public bool IsPressed(string button)
|
|
|
|
|
// {
|
|
|
|
|
// if (Forces.ContainsKey(button))
|
|
|
|
|
// return Forces[button];
|
|
|
|
|
// else return Controller.IsPressed(button);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// public float GetFloat(string name)
|
|
|
|
|
// {
|
|
|
|
|
// return Controller.GetFloat(name); //TODO!
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// public void UpdateControls(int frame)
|
|
|
|
|
// {
|
|
|
|
|
// Controller.UpdateControls(frame);
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
}
|