7

RPM ベースのディストリビューションでの入力にUSB SNES コントローラーを使用する C 言語のプログラムを開発しています。これを操作しやすくするライブラリ、またはデバイスからの入力を適切に読み取ることができるツール (joydev?) はありますか? ゲーム エンジン全体は必要ありません。キャラクターデバイスからの入力専用です。

すでにこれを行っているライブラリがあれば、それは素晴らしいことです (ライブラリが自分で何をするかを見ることができます)。これはリンクだけで閉じることができます。それ以外の場合、これを自分で行う必要がある場合は、いくつかの具体的な質問があります。

質問:

  • USB デバイスとゲームパッドとのやり取りをすべて処理する既存の C ライブラリはありますか? 私は喜んで新しいライブラリを学びます。(私のgoogle-fuはここで失敗しました。これが過度に明白である場合は申し訳ありません)
  • セッション/初期化間でイベント*名が変わるため、毎回適切なキャラクターデバイスを開くための適切な方法は何ですか?
  • アプリケーションからこれらのデバイスからの入力を処理する適切な方法は何ですか? ボタンを押すたびに値がどのようになるかを判断し、キャラクター デバイスをポーリングするときにその入力に基づいてアクションを実行するだけでよいでしょうか?

要するに疑似Cで、こんな感じ?

struct gamepad {
    int fd;
};

void get_input(struct gamepad *gamepad)
{
    char *buf;
    read(gamepad->fd, buf, 48);
    switch(buf)
    {
        /* insert cases about handling differing buttons */
    }
}

デバイスの表示方法:

私が見ることができる限り、デバイスのレジスタが適切に表示されていることがはっきりとわかります。

$ dmesg | tail
[198564.517068] usb 1-1: USB disconnect, device number 17
[198566.154324] usb 1-1: new low-speed USB device number 18 using xhci_hcd
[198566.323309] usb 1-1: New USB device found, idVendor=12bd, idProduct=d015
[198566.323312] usb 1-1: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[198566.323313] usb 1-1: Product: 2Axes 11Keys Game  Pad
[198566.323792] usb 1-1: ep 0x81 - rounding interval to 64 microframes, ep desc says 80 microframes
[198566.328692] input: 2Axes 11Keys Game  Pad as /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0/input/input20
[198566.329036] hid-generic 0003:12BD:D015.0006: input,hidraw2: USB HID v1.10 Gamepad [2Axes 11Keys Game  Pad] on usb-0000:00:14.0-1/input0

デバイスから読み取ると、割り込みを受信し、デバイスからの入力が 16 進ダンプを使用していることがわかります。

$ ls -lattr /dev/input/by-id/usb-12bd_2Axes_11Keys_Game_Pad-event-joystick 
lrwxrwxrwx. 1 root root 10 Jan 20 15:56 /dev/input/by-id/usb-12bd_2Axes_11Keys_Game_Pad-event-joystick -> ../event17

キーを押す (離さない) と、期待どおりに動作するように見えますが、まだコンテキストなしでバッファーから返されているものを解読することはできません。

$ hexdump /dev/input/event17 
0000000 f53a 569f 0000 0000 ac6c 000c 0000 0000
0000010 0003 0000 007f 0000 f53a 569f 0000 0000
0000020 ac6c 000c 0000 0000 0000 0000 0000 0000

ボタンを離すと、同様の出力が表示されます。

0000030 f53c 569f 0000 0000 8be3 0007 0000 0000
0000040 0003 0001 007f 0000 f53c 569f 0000 0000
0000050 8be3 0007 0000 0000 0000 0000 0000 0000

それは、上で押して離した「上」ボタンです。

リサーチ:

他のライブラリがこれをどのように行うかを判断するために、Python で strace を実行し、pygameそれが開くデバイスと入力の読み取り方法を確認することを考えましたが、使用方法についてはまだ学習中です。また、joydev に関するあいまいな言及もいくつか見ましたが、やはり、それらの使用方法を学んでいません。私は現在それを行っており、価値のあることを学べば結果を投稿します.

さらに、ASCII と hexdump を介してボタンの押下を監視すると、ボタンに基づいて同様の入力があることに注意してください。 0xf53c)。これも常に増加しているように見えますが、私の目的では、おそらく破棄できます。

一部のモジュールまたはパッケージが不足しているため、デバイスを正しくマウントしていない可能性もあります (もう一度、joydev とそれが何をすべきかについて考えます)。私は USB をあまり扱ったことがないので、このタイプのデバイス処理は初めてです。

しばらく探し回っても、探していたものを正確に示すものは何も見つかりませんでしたが、他の質問/トピックへのリダイレクトを喜んで受け入れます.

前もって感謝します!

4

2 に答える 2

5

Linux の USB 入力デバイスは通常、HID ドライバー (Human Interface Device) によって処理され、入力デバイスに変換されます。

それらを未加工の USB デバイスとして読み取ることができますが、これは非常に低レベルのプロトコルであるため、通常はあまり良い考えではありません。

/dev/input/*適切な権限があれば、デバイスを読み取ることができます。通常、root のみが読み取り可能です。生のバイトを読みたくない場合は、libinputなど、その仕事をしてくれるライブラリがいくつかあります。

ただし、ゲームが XWindows で動作する場合 (ほとんどの場合)、XInput デバイスを管理する必要があります。生の X 呼び出しでそれを行うことができますが、おそらくSDLなどのライブラリを使用する方がよいでしょう。実際、SDL は内部でpygame使用するものなので、最初にそれを試してみます。

適切なデバイスを識別する方法については、すべての入力デバイスには名前があり、一部にはシリアル番号もあります (/dev/input/by-idこれらは通常、入力番号の代わりに、デバイスを識別するのに十分です。

生の入力デバイスを読みたい場合は、hexdumps について説明させてください。input*デバイスを読み取っているため、次のタイプの値を取得していますstruct input_event( を参照/usr/include/linux/input.h)。

struct input_event {
    struct timeval time;
    __u16 type;
    __u16 code;
    __s32 value;
};

最初のダンプでは、たとえば次のようになります。

0000000 f53a 569f 0000 0000 ac6c 000c 0000 0000
0000010 0003 0000 007f 0000 f53a 569f 0000 0000
0000020 ac6c 000c 0000 0000 0000 0000 0000 0000

実際には 2 つinput_eventの s があります。最初のものは次のとおりです。

f53a 569f 0000 0000 ac6c 000c 0000 0000 0003 0000 007f 0000

最初の 64 バイトはタイムスタンプです。次に、0003 (EV_ABS)絶対軸の移動を意味し、0000 (ABS_X)は軸インデックス、0000007fはその軸の位置です。絶対軸は、スロットルやジョイスティックなどを表すために使用されることがあります (キーパッドが 4 つのボタンではなくジョイスティックとして送信される場合もあります)。最初の読み取りで位置を取得して、コントロールを動かさなくても、コントロールがどこにあるかを知ることができます。

2 つ目のイベントは次のとおりです。

f53a 569f 0000 0000 ac6c 000c 0000 0000 0000 0000 0000 0000

最初の 64 バイトはタイムスタンプです (上記と同じです。その後0000 (EV_SYN)は同期イベントを意味します。EV_SYNの場合、他のフィールドは使用されません。EV_SYNマウスの水平軸と垂直軸など、単一のイベントのさまざまな値をグループ化するために使用されます。ジョイスティック。

他のダンプは似ていますが、AXIS_Y.

私の推測では、キーパッドはデジタル ジョイスティックとして扱われ、2 つの軸ABS_XABS_Y0x7F中間点 (から0x00までの範囲0xFF) になっていると思われます。あなたが得ているメッセージは、単にキーパッドのボタンが押されていない中間点です。多分あなたのhexdump出力はバッファリングされていますか?

于 2016-01-20T22:13:41.400 に答える
1

これは USB Hid デバイスであるため、hid ドライバーによって処理されます。デバッグ出力 "USB HID v1.10 Gamepad" を参照してください。さまざまなチュートリアルとその方法の例があります。

出発点として、「apt-get install joystick」にジョイスティックをインストールして、ソース コードを確認できます。

libhidapi も良い選択です。

于 2016-01-20T21:59:22.063 に答える