LoginSignup
8
4

More than 1 year has passed since last update.

M5Stackをゲームコントローラーにする方法

Last updated at Posted at 2022-12-19

GameControllerizerって?

GameControllerize(以下G.C)は、専用基板とビジュアルプログラミング環境からなるミドルウエアで、デジタルゲームへの操作入力を自在にハックできます。
基本的には、Node-Redや、MakeCodeで開発が可能ですが、UARTでも直接制御が可能なので、備忘録としてまとめてます。

G.C専用基板について

汎用タイプと、micro:bit専用タイプの2種類が存在しています。
汎用基板は、Raspberry Pi Zeroとマウントできる作りになっており、Groveコネクタも装備されています。
今回は、このGrove端子を用いてM5Stackと連携します。

汎用タイプ (GC-GP) micro:bit専用タイプ (GC-MB)

※参照)https://sites.google.com/view/gamecontrollerizer/board より

UART Protocol

コマンド情報

UARTで制御するためのコマンドの一部を以下に掲載します。
他にもあるのですが、使ったことないので今回は割愛

基本的には、
1byte目の種類、コマンド設定
2 byte目の間隔
3 / 4byte目の制御情報の合計4byteのデータを送信します。

Byte 説明
1 制御コマンド ( [7:4] デバイス種類 / [3:0] 指定コマンド )
2 間隔
3 操作情報 
4 操作情報 
制御コマンド

制御コマンドは、以下のデバイス種類と、どのキーを操作するかの指定コマンドを組み合わせて利用します。
例えばゲームパッドで十字キーの場合は、0xC0
ボタンの場合は、 0xC1が制御コマンドになります。

デバイス種類

G.Cがシュミレートするデバイスの種類を設定します。

説明
0xC ゲームパッド
指定コマンド

どのボタンを操作するかを指定します。
ここでは説明しませんが、アナログのスティックも制御可能です。

説明
0x0 十字キー上書き
0x1 ボタン上書き
0x2 ボタン設定
0x3 ボタン解除

上書きと、設定の違いについて
ボタン設定(0x2)は、ボタンひとつひとつに対してONを設定することができます。
OFFにする場合はボタン解除(0x3)を指定します。
ボタン上書き(0x1)は、すべてのボタンに対してON/OFFを設定します。

間隔

どれだけボタンを押し続けるかを設定するためのパラメータです。
格闘コマンドのように時間差でボタンを入力が必要な場合は、Push(1~127) の時間の制御を
十字キーや、ボタンを同時押ししたい場合は、Chain(0)
ずっと押し続けたい場合は、Hold(-1)を設定します。

ちなみに、Push(1~127)を使用する場合、最低でも2~3を使用しないと反応しないゲームがほとんどのようです

情報 説明
1~127 Push 指定期間だけ適用して、次の処理に移る
-1 Hold 次のコマンドが来るまで押し続ける
0 Chain これ以降のPush/Holdがきた時点で適用される
操作情報(十字キー)

十字キーの場合に使用する、各位置対応する以下の値を3byte目に設定します。
4byte目は設定する情報がないのでを設定。

注意: 十字キーに同時押しは存在しません。ひとつのキーのみ設定可能
一般的な十字キーの場合、物理的な制約で右ボタンと左ボタンは同時に押せない

7 8 9
4 5 6
1 2 3
操作情報(ボタン)

ボタンは、最大16個のボタンまで制御可能です。
ただし、デバイス側で認識するボタンがない場合は、入力が無視されます。

0~7番目のボタンの状態を3byte目に、 8~15番目のボタンの状態を4byte目に設定します。
また、設定の意味は、指定コマンドにより変わってきます。

設定 / 解除モード時
設定モード時、各ビットでの箇所のボタンがONになります。0の場所は状態の変更はありません。
解除モード時、各ビットでの箇所のボタンがOFFになります。0の場所は状態の変更はありません。
   
上書き時
各ビット毎がの場合、ボタンがON0の場合は、ボタンのOFFが設定されます。

例)
12番目のボタンと、3番目のボタンをONにする場合
3byte目: 0x04(00000100)
4byte目: 0x08(00001000)

十字キーを制御してみる

ゲームパッドで十字キーを制御してみます。

ここでは、右キーを押し続けるコマンドを作ってみたいと思います。

まず1byte目には、ゲームパッドの十字キーを制御する 0xC0が設定します。
2byte目は、ボタンの押し方です。押し続けるので、-1を設定
3byte目には、十字キーの方向が設定され、右の場合は、 6が設定されてます。
4byte目は、設定項目がないので、0を設定します。

実際のコードにする以下になります。

  //Groveポートの制御開始
  Serial2.begin(115200, SERIAL_8N1, 32, 33);

  // コマンド作成 
  byte cmd[4];
  cmd[0] = 0xc0;  // 十字キー制御
  cmd[1] = -1;    // 状態を維持
  cmd[2] = 6;     // 右キー
  cmd[3] = 0;     // 設定なし

  // G.Cにコマンド送信
  Serial2.write(cmd, 4);

ボタンを制御してみる

次にボタンを制御してみます。

ここでは、2つのボタン(1番と2番のボタン)を同時に押してみたいと思います。

まず1byte目には、ゲームパッドの十字キーを制御する 0xC1が設定します。

2byte目は、ボタンの押し方です。押し続けるので、-1を設定
3byte目には、0x03 (00000011)を設定
*上書きなので、0の項目はボタンがOFFに設定されます。
*もし設定の場合は、指定された項目のみONになります(0は変化なし)

4byte目は、今回は、設定項目がないので、0を設定します。

実際のコードにする以下になります。

  //Groveポートの制御開始
  Serial2.begin(115200, SERIAL_8N1, 32, 33);

  // コマンド作成 
  byte cmd[4];
  cmd[0] = 0xc1;  // 十字キー制御
  cmd[1] = -1;    // 状態を維持
  cmd[2] = 3;     // 1番と2番ボタンをON、3~7番ボタンはOFF
  cmd[3] = 0;     // 8~16番ボタンをOFF

  // G.Cにコマンド送信
  Serial2.write(cmd, 4);

 ボタンと十字キーを同時に制御してみる

最後に十字キーとボタンを制御してみます。

基本的には先ほど同じように十字キーと、ボタンの制御コマンドを作成します。
しかし別々にG.Cにデータを送る必要があるため同時に送る場合は、間隔をChain(0)にする必要があります。
そして有効にしたいコマンドで、間隔のパラメータを指定します。

  //Groveポートの制御開始
  Serial2.begin(115200, SERIAL_8N1, 32, 33);

  // 十字キーのコマンド作成 
  byte cmd[4];
  cmd[0] = 0xc0; // 十字キー制御
  cmd[1] = 0;    // Chain状態に設定
  cmd[2] = 6;    // 右キー
  cmd[3] = 0;
  // G.Cにコマンド送信
  Serial2.write(cmd, 4);

  // ボタン用のコマンド作成 
  cmd[0] = 0xc1;  // 十字キー制御
  cmd[1] = -1;    // 状態を維持
  cmd[2] = 1;     // 1番をON、2~7番ボタンはOFF
  cmd[3] = 0;     // 8~16番ボタンをOFF
  // G.Cにコマンド送信
  Serial2.write(cmd, 4);

最後に

触りだけの説明でしたが、簡単に使えることは気づいていただけたのではないかなと思います。
UARTで直接制御しましたが、ビジュアルプログラミングでも簡単に利用できます。

GameControllerizerを使えば手軽に独自のゲームコントローラーを作ることができます。
あとはアイデア次第、興味があればぜひ使ってみてください。

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4