Надежный способ захвата нажатия кнопки геймпада (не игровое приложение)

Я пытаюсь использовать геймпад для управления приложением. Это не игра, а простое приложение, использующее Windows Forms. Так что у него нет игрового цикла/процесса обновления или чего-то подобного. Я не хотел бы использовать XNA, потому что я думаю, что это огромная перегрузка только для захвата нажатия кнопки.

Я экспериментирую как с SlimDX, так и с SharpDX. Я так понимаю, это просто обертки для DirectX, да?

Глядя на документацию, кажется, что нет события для нажатия кнопки. Поэтому я искал альтернативу. Я попытался добавить таймер (из класса System.Windows.Forms.Timer) и прочитать состояние геймпада следующим образом:

private void timer_tick(object sender, EventArgs e)
{
    State s = controller.GetState();
    stateLabel.Text = s.Gamepad.Buttons == GamepadButtonFlags.A ? "A" : "";
}

При достаточно маленьком интервале между тиками таймера (у меня 10 мс) я вижу, нажата кнопка или нет. Однако я не хочу обрабатывать нажатие кнопки несколько раз, если кнопка удерживается нажатой - мне нужно убедиться, что она была отпущена, прежде чем снова обрабатывать нажатие кнопки. Между двумя тиками таймера я не знаю, была ли кнопка нажата дважды или ее просто удерживали.

Я думал об использовании номера пакета в состоянии контроллера, но он будет меняться при малейшем прикосновении к аналоговому стику или плечевому триггеру.

Помощь?


person Geeky Guy    schedule 23.03.2014    source источник
comment
Чему вы скармливаете эту информацию? Что-то вроде текстового поля?   -  person bubbinator    schedule 23.03.2014
comment
Может быть. На самом деле я пытаюсь взломать контроллер, чтобы человек с параличом нижних конечностей мог управлять им ртом, а контроллер вел себя как мышь. Что-то вроде этого, но больше ориентировано на обычное использование компьютера, а не на игры. Я знаю, что мог бы сделать специальную мышь, но у меня полно запасных контроллеров, и я думаю, что с ними я могу сделать больше, чем с мышью.   -  person Geeky Guy    schedule 23.03.2014
comment
Очень благородное дело. Я посмотрю, смогу ли я приготовить что-нибудь, чтобы вы начали. Похоже, некоторые умные bool способы помогут вам начать работу.   -  person bubbinator    schedule 23.03.2014


Ответы (1)


Из того, что я могу понять после прочтения вашего вопроса несколько раз, является то, что вы хотите зарегистрировать нажатие кнопки только 1 раз, пока оно не будет отпущено. Вы, вероятно, должны использовать технику номера пакета, чтобы отслеживать любые изменения на другом входе.

Чтобы получить один ввод от удерживаемой кнопки, а не получать непрерывный ввод (1 вместо 11111111... и т. д.), создайте старое состояние и текущее состояние. Затем сравните старое состояние с новым состоянием.

Что-то вроде этого:

class Input
{
    State old;

    void GetInput()
    {
        State new = controller.GetState();
        if (this.old.GamePad.Buttons == GamepadButtonFlags.A && new.GamePad.Buttons == GamepadButtonFlags.A)
        {
            // Do stuff that will be called only once.
        }
        this.old = new;
    }
}   
person bubbinator    schedule 23.03.2014
comment
Такое сравнение состояний помогло. Мне нравится эта стратегия, в которой не нужно проверять номер пакета, потому что даже малейшее прикосновение к палочкам или триггерам будет генерировать новый пакет. Спасибо большое :) - person Geeky Guy; 24.03.2014
comment
Рад, что смог помочь. Для справки, я взял за основу код, который использовал для Monogame. - person bubbinator; 24.03.2014