Instead of implementing this in a timer, why not use another thread, and continuously check the state of the controller by triggering an event in the form when a button is pressed and when it is released.
Form Code:
public partial class FormWithExternalEvents : Form
{
private GamepadEvents gpe;
public FormWithExternalEvents()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
gpe = new GamepadEvents();
gpe.JoystickButtonDown += b =>
{
if (this.InvokeRequired) this.Invoke((GamepadButtonEvent) gpe_JoystickButtonDown);
else gpe_JoystickButtonDown(b);
};
gpe.JoystickButtonUp += b =>
{
if (this.InvokeRequired) this.Invoke((GamepadButtonEvent)gpe_JoystickButtonUp);
else gpe_JoystickButtonUp(b);
};
var thread = new Thread(gpe.Run);
thread.Start();
base.OnLoad(e);
}
void gpe_JoystickButtonUp(SharpDX.XInput.GamepadButtonFlags button)
{
throw new NotImplementedException();
}
void gpe_JoystickButtonDown(SharpDX.XInput.GamepadButtonFlags button)
{
throw new NotImplementedException();
}
}
Code of the class that will be running on another thread:
public delegate void GamepadButtonEvent(GamepadButtonFlags button);
public class GamepadEvents
{
public event GamepadButtonEvent JoystickButtonUp;
public event GamepadButtonEvent JoystickButtonDown;
private bool[] buttonsBools = new bool[32];
public void Run()
{
while (true)
{
var controller = new Controller();
State s = controller.GetState();
ButtonSignal(0, GamepadButtonFlags.DPadUp, (s.Gamepad.Buttons & GamepadButtonFlags.DPadUp) != 0);
ButtonSignal(1, GamepadButtonFlags.DPadDown, (s.Gamepad.Buttons & GamepadButtonFlags.DPadDown) != 0);
ButtonSignal(2, GamepadButtonFlags.DPadLeft, (s.Gamepad.Buttons & GamepadButtonFlags.DPadLeft) != 0);
ButtonSignal(3, GamepadButtonFlags.DPadRight, (s.Gamepad.Buttons & GamepadButtonFlags.DPadRight) != 0);
ButtonSignal(4, GamepadButtonFlags.Start, (s.Gamepad.Buttons & GamepadButtonFlags.Start) != 0);
ButtonSignal(5, GamepadButtonFlags.Back, (s.Gamepad.Buttons & GamepadButtonFlags.Back) != 0);
ButtonSignal(6, GamepadButtonFlags.LeftThumb, (s.Gamepad.Buttons & GamepadButtonFlags.LeftThumb) != 0);
ButtonSignal(7, GamepadButtonFlags.RightThumb, (s.Gamepad.Buttons & GamepadButtonFlags.RightThumb) != 0);
ButtonSignal(8, GamepadButtonFlags.LeftShoulder, (s.Gamepad.Buttons & GamepadButtonFlags.LeftShoulder) != 0);
ButtonSignal(9, GamepadButtonFlags.RightShoulder, (s.Gamepad.Buttons & GamepadButtonFlags.RightShoulder) != 0);
ButtonSignal(10, GamepadButtonFlags.A, (s.Gamepad.Buttons & GamepadButtonFlags.A) != 0);
ButtonSignal(11, GamepadButtonFlags.B, (s.Gamepad.Buttons & GamepadButtonFlags.B) != 0);
ButtonSignal(12, GamepadButtonFlags.X, (s.Gamepad.Buttons & GamepadButtonFlags.X) != 0);
ButtonSignal(13, GamepadButtonFlags.Y, (s.Gamepad.Buttons & GamepadButtonFlags.Y) != 0);
Thread.Sleep(1);
}
}
private void ButtonSignal(int btnIdx, GamepadButtonFlags gamepadButton, bool pressed)
{
bool wasPressed = buttonsBools[btnIdx];
buttonsBools[btnIdx] = pressed;
if (wasPressed && !pressed)
this.JoystickButtonUp(gamepadButton);
if (!wasPressed && pressed)
this.JoystickButtonDown(gamepadButton);
}
}
Are you facing problems in practice, or is it just a possibility that occurred to you? Everything I’ve read on the subject in one way or another involves Polling as you are doing, so unfortunately I have nothing better to suggest... but perhaps someone with more experience has a better alternative.
– mgibsonbr
It’s a possibility for now, but it will be practical soon. I’m trying to adapt controls so that paraplegic people can use them. Not to play, but to operate a computer.
– Oralista de Sistemas
Perhaps it was the case that you rethink your usability requirements then. After all, your current method will only bring problems if there is the possibility of the person pressing the button several times in sequence faster than your timer can follow. If there is no motive for her to do so (i.e. if there is no use case in which this action produces a desirable result) then the need to distinguish between the two cases becomes less important. Not that it answers the question - I think it’s still valid - but in practice it might be useful.
– mgibsonbr