Arduino を使って Nintendo Switch のゲームを自動化する、マイコン用のライブラリです。
このライブラリは celclow 氏のSwitchControlLibraryを参考にして作られています。
SwitchControlLibrary は自由度が高いものの、コードが冗長になりやすい点、ArduinoSTL を使用するためコンパイルに時間がかかる点などがネックでした。
そこで、一般的によく使われる入力のパターンを厳選して関数にまとめることにしました。
ボタンを押して離すまでの処理が 1 行で書けるようになり、より効率的に自動化プログラムを組むことができるようになります。連打や長押しの処理にも対応させ、汎用性の高いプログラムに仕上げました。
そしてなにより、ArduinoSTL を使わずにこれらの処理を実装することに成功しています。これによりコンパイルが高速に行えるほか、依存関係に悩まされなくなっていることも特徴です。
詳しい導入の手順については、ブログで解説していますので、そちらをご覧ください。
マイコンを導入して、ポケモン剣盾を自動化しよう!【Mac・Windows】|ポケモニット
Arduino Leonardo については、ブログ内で紹介しているものを推奨しています。その他の Arduino では動作確認を行っておりません。異なるものを使用している場合には、質問にも一切答えられませんので予めご了承ください。
Arduino IDE やボードのバージョンは、基本的に最新の安定版のものを使って動作確認しています。古いバージョンでも使えるとは思いますが、動作を保証するものではありません。
なお、Nintendo Switch のバージョンには指定がありません。どのバージョンでも問題なく動作するはずです。
ライブラリを使いたいファイルの先頭に以下のように記載してください。
#include <NintendoSwitchControlLibrary.h>
これでライブラリを読み込み、各種コマンドを使うことができるようになります。
単体で完結しているため、ArduinoSTL や SwitchControlLibrary といった別のライブラリを読み込む必要はありません。
SwitchControlLibrary とは競合するため、同時に読み込むことはできませんが、NintendoSwitchControlLibrary は SwitchControlLibrary(v2 系)を継承して作られているため、SwitchControlLibrary のコマンドも使用することが可能となっています。(ArduinoSTL を使用していない都合で、十字キーのコマンドのみ動作が少し異なりますが、基本的には同じように使うことができます)
ボタンを押すコマンド(連打にも対応)
pushButton(uint16_t button, int delay_time = 0, int loop = 1)
button: 押すボタン
delay_time: ボタンを押した後の待ち時間(1 秒 = 1000)
loop: ボタンを押す回数(省略可、デフォルトは 1)
使用例
pushButton(Button::HOME); // HOMEボタンを入力する
pushButton(Button::A, 500); // Aボタンを入力後、0.5秒待機する
pushButton(Button::B, 3000, 10); // 3秒おきにBボタンを入力する、それを10回繰り返す
ボタンを長押しするコマンド
holdButton(uint16_t button, int hold_time)
button: 押し続けるボタン
hold_time: ボタンを押す時間の長さ(1 秒 = 1000)
使用例
holdButton(Button::L, 2000); // Lボタンを2秒間押し続けてから離す
holdButton(Button::CAPTURE, 1500); // キャプチャーボタンを1.5秒間押し続けてから離す
Button
定義一覧
Button::Y
Button::B
Button::A
Button::X
Button::L
Button::R
Button::ZL
Button::ZR
Button::MINUS
Button::PLUS
Button::LCLICK
Button::RCLICK
Button::HOME
Button::CAPTURE
十字キー(方向ボタン)を押すコマンド(連打にも対応)
pushHat(uint8_t hat, int delay_time = 0, int loop = 1);
hat: 押す十字キーのボタン
delay_time: ボタンを押した後の待ち時間(1 秒 = 1000)
loop: ボタンを押す回数(省略可、デフォルトは 1)
使用例
pushHat(Hat::UP); // 上キーを1回だけ入力する
pushHat(Hat::LEFT, 1000); // 左キーを入力後、1秒待機する
pushHat(Hat::DOWN, 25, 5); // 0.25秒おきに下キーを入力する、それを5回繰り返す
十字キー(方向ボタン)を長押しするコマンド
holdHat(uint8_t hat, int hold_time);
hat: 押し続ける十字キーのボタン
hold_time: ボタンを押す時間の長さ(1 秒 = 1000)
使用例
holdHat(Hat::RIGHT, 5000); // 右キーを5秒間押し続けてから離す
holdHat(Hat::UP_LEFT, 2500); // 十字キーを左上方向に2.5秒間押し続けてから離す
Hat
定義一覧
Hat::UP
Hat::UP_RIGHT
Hat::RIGHT
Hat::DOWN_RIGHT
Hat::DOWN
Hat::DOWN_LEFT
Hat::LEFT
Hat::UP_LEFT
Hat::NEUTRAL
スティックの座標は、128 を基点として 0〜255 の値を指定します。
0・128・255 の 3 つの値は Stick で定義されているため、置き換えて使用することもできます(0 = MIN, NEUTRAL = 128, MAX = 255)
また、引数にボタンを渡すことでボタンを連打しながらスティックを傾ける操作を行うことができます。
左スティックを操作するコマンド
tiltLeftStick(uint8_t lx, uint8_t ly, int tilt_time, uint16_t button = NULL);
lx: 左スティックの x 軸
ly: 左スティックの y 軸
tilt_time: スティックを傾ける時間の長さ
button: 連打するボタン
使用例
tiltLeftStick(0, 128, 5000); // 左スティックを左に5秒間倒す
tiltLeftStick(Stick::NEUTRAL, Stick::MAX, 15000); // 左スティックを下に15秒間倒す
tiltLeftStick(Stick::NEUTRAL, Stick::MIN, 8000, Button::A); // Aボタンを連打しながら、左スティックを上に8秒間倒す
右スティックを操作するコマンド
tiltRightStick(uint8_t rx, uint8_t ry, int tilt_time, uint16_t button = NULL);
rx: 右スティックの x 軸
ry: 右スティックの y 軸
tilt_time: スティックを傾ける時間の長さ
button: 連打するボタン
使用例
tiltRightStick(255, 128, 100); // 右スティックを右に0.1秒間倒す
tiltRightStick(Stick::MAX, Stick::MIN, 10000); // 右スティックを右上に10秒間倒す
tiltRightStick(Stick::NEUTRAL, Stick::MAX, 30000, Button::X); // Xボタンを連打しながら、右スティックを下に30秒間倒す
左右のスティックを同時に操作するコマンド
tiltLeftAndRightStick(uint8_t lx, uint8_t ly, uint8_t rx, uint8_t ry, int tilt_time, uint16_t button = NULL);
lx: 左スティックの x 軸
ly: 左スティックの y 軸
rx: 右スティックの x 軸
ry: 右スティックの y 軸
tilt_time: スティックを傾ける時間の長さ
button: 連打するボタン
使用例
tiltLeftAndRightStick(128, 255, 0, 128, 1000); // 左スティックを下に、右スティックを左に1秒間倒す
tiltLeftAndRightStick(Stick::MAX, Stick::MAX, Stick::MIN, Stick::MIN, 30000); // 左スティックを右下に、右スティックは左上に、30秒間倒す
tiltLeftAndRightStick(Stick::NEUTRAL, Stick::MAX, Stick::MIN, Stick::MAX, 2000, Button::B); // Bボタンを連打しながら、左スティックを下に、右スティックは左下に、2秒間倒す
Stick
定義一覧
Stick::MIN
Stick::NEUTRAL
Stick::MAX
左スティックをぐるぐるするコマンド
spinLeftStick(int spin_time, uint8_t speed = 5, bool direction = 1);
spin_time: ぐるぐるさせる時間(1 回転に満たない端数の時間が生じた場合は切り捨てとなります)
speed: 1 秒あたりの回転数
direction: 方向(1: 時計回り, 0:反時計回り)
使用例
spinLeftStick(10000); // 10秒間左スティックを時計回りで、1秒に5回ぐるぐるする
spinLeftStick(30000, 1); // 30秒間左スティックを時計回りで、1秒に1回ぐるぐるする
spinLeftStick(25000, 3, 0); // 25秒間左スティックを反時計回りで、1秒に3回ぐるぐるする
右スティックをぐるぐるするコマンド
spinRightStick(int spin_time, uint8_t speed = 5, bool direction = 1);
spin_time: ぐるぐるさせる時間(1 回転に満たない端数の時間が生じた場合は切り捨てとなります)
speed: 1 秒あたりの回転数
direction: 方向(1: 時計回り, 0:反時計回り)
使用例
spinRightStick(5000); // 5秒間右スティックを時計回りで、1秒に5回ぐるぐるする
spinRightStick(9000, 10, 0); // 9秒間右スティックを反時計回りで、1秒に10回ぐるぐるする
spinRightStick(3000, 4, 1); // 3秒間右スティックを時計回りで、1秒に4回ぐるぐるする
このライブラリは SwitchControlLibrary のコマンドも内蔵しているため、合わせて使用することもできます。(v2 系を採用しています。v1 系とは互換性がないことに注意してください)
上記のもので対応できないものがある場合には、活用してみるといいかもしれません。
サンプルとして、ポケモン剣盾でバックアップデータの読み込みを行うコマンドを用意してみました。
SwitchControlLibrary().pressButton(Button::B);
SwitchControlLibrary().pressButton(Button::X);
SwitchControlLibrary().pressHatButton(Hat::UP); // ※SwitchControlLibraryと異なり、moveHatは使えません。 pressHatButtonに統合されています。
SwitchControlLibrary().sendReport(); // B、X、↑ボタンが同時に送信される
delay(100);
SwitchControlLibrary().releaseButton(Button::B);
SwitchControlLibrary().releaseButton(Button::X);
SwitchControlLibrary().releaseHatButton(); // ※SwitchControlLibraryと異なり、引数は指定しません。(十字キーをニュートラルポジションに戻す処理となる)
SwitchControlLibrary().sendReport(); // B、X、↑ボタンを同時に離す
このライブラリは暫定的なものなので、要望や改善案、追加してほしい機能などありましたら、Issuesから気軽に投げかけてくださいませ。
画像認識のような高度なものを作るのは難しいかもしれませんが、入力プログラムの応用の範囲でしたら対応できるかと思います。