シェル芸
ふと思い立って調べてみたので、備忘用に書いておきます。利用ハードウェアはエレコムのJC-U2312FSV。12ボタン、十字キー、アナログ2軸のゲームコントローラーです。
# 検証方法(信号を16進数8バイトずつ表示) cat /dev/input/js0 | od -tx1 -Ax -w8
js0デバイスを開くと、必ず以下のようなバイナリが流れて停止します。
000000 bc e7 8f 00 00 00 81 00 000008 bc e7 8f 00 00 00 81 01 000010 bc e7 8f 00 00 00 81 02 000018 bc e7 8f 00 00 00 81 03 000020 bc e7 8f 00 00 00 81 04 000028 bc e7 8f 00 00 00 81 05 000030 bc e7 8f 00 00 00 81 06 000038 bc e7 8f 00 00 00 81 07 000040 bc e7 8f 00 00 00 81 08 000048 bc e7 8f 00 00 00 81 09 000050 bc e7 8f 00 00 00 81 0a 000058 bc e7 8f 00 00 00 81 0b 000060 bc e7 8f 00 00 00 82 00 000068 bc e7 8f 00 00 00 82 01 000070 bc e7 8f 00 00 00 82 02 000078 bc e7 8f 00 00 00 82 03 000080 bc e7 8f 00 00 00 82 04 000088 bc e7 8f 00 00 00 82 05
このヘッダ信号は、有効なボタン/軸情報の申告かな。最初の4バイトが全て同じ値なので、メーカーまたは型番番号or以下に続くキーイベントのカウンタと区別するものかもしれない。
続けて、0番、1番ボタンを順に押下すると
000090 30 b1 91 00 01 00 01 00 ← 0番ボタン押下 000098 a0 b1 91 00 00 00 01 00 ← 0番ボタン離す 0000a0 70 b6 91 00 01 00 01 01 ← 1番ボタン押下 0000a8 e0 b6 91 00 00 00 01 01 ← 1番ボタン離す
と分かりやすい結果が出てきました。さらにいくつか押下してみると、以下の事が分かりました。
- キーイベントは8バイト構成
- それぞれの内容は以下のとおり
バイト順 | 内容 |
---|---|
1~4バイト目 | 同期用カウンタ?初期値不明。 |
5~6バイト目 | ボタン(押=1/離=0) or 方向(座標情報) |
7バイト目 | ボタンイベント時=1/方向イベント時=2 |
8バイト目 | ボタン番号(0~c) or 軸情報(LX=0/LY=1/RX=2/RY=3/CX=4/CY=5) |
※ 複数バイト値はリトルエディアン
7バイト目がフラグになっており、このイベントが通常ボタン押下なのか方向操作なのかを通知しているようです。
7バイト目が1、つまり通常ボタン押下の場合、5~6バイト目が unsigned short で押した(1)か離した(0)かの情報、8バイト目が char でキー番号(0~c)となります。
また、7バイト目が2、つまり方向操作の場合、5~6バイト目が signed short のずれ量(アナログスティック時)、8バイト目が軸情報となる。十字ボタンの5~6バイト目は以下のとおり。
キー | 方向情報 | 軸情報 |
---|---|---|
← | 8001 | 4 |
→ | 7fff | 4 |
↑ | 8001 | 5 |
↓ | 7fff | 5 |
※リトルエディアンなので、下位8ビットが5バイト目にあたります。
十字ボタンの値は、固定値のようだ。また、十字ボタンが離された際には、5~6バイト目はヌル(0)となります。
1~4バイト目は、キューが混乱した場合にちゃんとソート出来るようにした目印カウンタかな。
歴史的背景のあるキーボードの信号より、すごくシンプルで分かりやすいと思いました。きっと似たようなフォーマットで軸や強度、モーター情報を拵えて js0 に write してやると、振動してくれそうだー。
これを元に、ジョイスティックキー検知を行うシェルスクリプト関数を書きたいと思います。
※ 2020/07/02 度重なるブログ移転・ブログシステムのアップデートにより崩れた記事を校正。