はじめに
この記事はスマブラAdvent Calendar 2020 の13日目の記事です。 今年も各執筆者の視点からでしか書けないような、非常に濃い記事が投稿されています。
前日の12日は、たしきさんがスマブラへ取り組むモチベーションについて自身の経験を元に記してくれました。
この記事では、「なんか面白そうなことやりたいなー」と思った筆者がおっかなびっくりでものづくりしているよ、という報告をします。
本当は「(しょぼいけど)こんなものができたよ!」までやりたかったのですが、能力不足もあり全然間に合わなかったので取り組みだけ紹介します。
協力者・アドバイス随時募集中です。
概要
スマブラを遊んでいて、意図していない操作でミスをして負けるという経験を何度もしています。
普段ネスというキャラクターを使ってスマブラで遊んでいるのもあり、復帰のPKTAが崖に届かず、ましてや崖とは異なる方向に飛んでいって撃墜というのは日常茶飯事です*1。
しかし試合を見返したりトレーニングモードに潜って練習しても、自分がなぜ復帰ミスをしたのかや、どのタイミングで入れ込んだのかなど、あまり実感を持てないことがあります。
このとき、多くの格ゲーが持っているような、キーディスプレイ表示機能がスマブラにもあればなーと思うのですが、スマブラSPに本機能は搭載されていません。
キー入力の可視化方法として、有志が制作している外部ツール、NintendoSpyおよびそのフォーク*2であるRetroSpyを導入するというものがあります。
しかし、これはリアルタイムで入力状態を画像で表示するものなので、リプレイを止めながら振り返る際に、静止画で入力の流れがわかる格ゲーのようなキー入力の表示がほしいなあと思い立ちました。
そこで今回は、既存の有志ツールを参考にしながら、格ゲーにあるようなキー入力を記録・表示するキーロガーを作成することにしました。
参考としてギルティギアXrdRev2のスクリーンショットを掲載します。 画像左にあるように、入力があるたびにキー表示が上から追加されていくイメージです。 コンボによって技名を出すとかもしたいですが、さすがに無謀なので今回はパスです。
既存のものについて
スマブラ配信で、ゲーム画面と連動して動くコントローラーのアニメーションを見かけたことがある人もいるのではないでしょうか。
これはNintendoSpyもしくはRetroSpyというアプリケーションと、Arduinoというマイコンを用いて実現しているものです。 簡単に言うと、コントローラーの入力をPCに取り込んでアニメーションに変換してくれるものです。
RetroSpyはNintendoSpyを元にして作られたアプリケーションで、特に活発に改良が続けられており、任天堂以外のコントローラーにも多く対応しています。
NintendoSpyも最近ソースコードの更新があったようで、もしかしたらバージョンがそのうち上がるかもしれません。
RetroSpyの制作
目的とするキーロガーの作成のためには、なにはともあれGCコンの入力が取得できなければ始まりません。
試みの第一歩として、RetroSpyの導入を行いました。
作成については先駆者様の日本語解説記事や、RetroSpy公式の導入記事を参考にしました。
- nintendospyのお話(コントローラーの入力表示)(20/09/22):おりまが - ブロマガ
- コントローラー入力表示 RetroSpy(input display)導入方法:きごうのブロマガ - ブロマガ
- GameCube Controller Pinouts - Google スプレッドシート
- GCコンのケーブル内部に関する資料です
- NintendoSpy/tutorial-gamecube.md at master · jaburns/NintendoSpy · GitHub
ここではRetroSpyの導入方法については詳しく解説しないので、上のリンクをたどってみてください。
せっかくArduinoを買ったので光らせて遊んだりしつつ、
こんな感じでGCコンの延長ケーブルから抜き出して、
なんだかんだあってRetroSpyは動くようになったよ。やったね
とりあえず導入はできた pic.twitter.com/MqVfW7etGA
— 寝椅子 (@newenwere) 2020年12月8日
買ったケーブル内部のカラーコードのパターンはリンクにある資料と比べても違ったので、端子の側のケーブル皮膜をカッターで開いて確認しました。
これは赤がDATAで緑がGND(3)のタイプのようでした。 赤がデータを扱っているケーブルのようなので、これをArduinoのCOM5に挿すと、データがRetroSpy側で取得できました。
ただ、緑色のコードを本来挿すと安定するという話なのですが、これを上の画像のようにGNDに挿すと動かなくなるのですよね…… キー入力がアダプタレベルでゲーム機に行かなくなるから、多分誤った信号か電気が流れて、Switchのドック側で保護のために通信を受け付けなくなっている可能性があるかも? あくまでも憶測です。
そういえばこの状態でRetroSpyは反応してたっけ……それでもうちょっと状態が絞り込める気がします。要追跡調査。
RetroSpyの分析
目的となる本題はここからで、RetroSpyがやっている「GCコンの入力を取得し、入力の状態をリアルタイムで画像表示する」をどうやっているのかを調べていきます。
RetroSpyは上記のリンク先でソースコードがMITライセンスで公開されています。
ライセンスの話も長くなるので詳しくは省略するのですが、MITライセンスはゆるい規定で利用・改変が可能となっており、今回はその恩恵に預かります。
ソースコードは、ソフトウェア・アプリケーションと呼ばれるものの設計図であり、説明書であり、本体です。
なので、このソースコードを読み解けば、GCコンの入力を取得する手段がわかるはずです。
RetroSpyはC#およびC++というプログラミング言語で制作されているようで、今回はWindowsのPCにVisual Studioという開発環境を導入して、サイトからソースコードを入手して読解を行います。
わかっている(妄想している)知識として、
- シリアル通信でGCコンとゲーム機はデータ(キーの信号)を送受信している
- Arduino側でGCコンの通信を取得・処理している
- RetroSpyアプリケーション側でArduinoからデータを受け取って、アニメーションを作成している
というものがあります。
なので、ソースコードでこれらの機能が実装されている箇所を探して、読み解きたいわけです。
つまりは、
- GCコンの信号を取得・解釈している箇所
- ArduinoとRetroSpyがデータを受け渡ししている箇所
- RetroSpyが受け取ったデータを処理している箇所
- 処理したデータを元にRetroSpyのアニメーションを作っている箇所
を知りたい という目標が立ちます。
私自身はC#やC++が何もわからないし、Arduinoも全く触ってこなかったので、それっぽい英単語をソースコードの名前や記述から探してはそこが何をやっているのかを調べる ということを繰り返していきます。
そんなことをしている間に、記事投稿の当日を迎えました。
んんん??????????
現状
なんとなくコントローラーのデータ通信を取得することができました。
取れはしたけどこの1の増減がなんなのかわからないねえ pic.twitter.com/y3gU50qc7i
— 寝椅子 (@newenwere) 2020年12月12日
はい、以上です。
これはArduinoのシリアルモニタという通信を監視する機能の画面なのですが、データケーブルを右下の値を115200bpsに設定すると高速で1が並んだものが描画されていきます。 キー入力を行うと1行あたりに描画される1の数が増え、離すと減ります。
この1が末尾に追記されているのか1と1の間に挿入されているのかはわかりませんし、そもそも別の読み取り方をするともっとわかりやすくモニタリングできるのかもしれません。 これを人間が解釈できるように変換したかったのですが、調べ物をしたりコードを読んだりしているうちに、記事の締切的な意味でここでタイムアップとなりました。
無様だ……
C、C++をお勉強したのがN (N < 10) 年前で、それも基礎の基礎しかやっていないため、シリアル通信を扱うとか、アプリケーションを作るなどは完全に手探りで、「これどういう意味なの?」を無限に調べながらやっています。 基礎については意外と覚えているし(別の言語を触っていて共通知識は活かせるという話もある)、一方で全く知らないことは全く知らないです。
わかる・覚えているが1あったら知らないが200くらいあります。
雑にRetroSpyのGCコンのシリアル通信を解析しているところ・アプリケーション側で画像切替部分を理解すれば、キー入力をテキストで表示するところまではいけるかなーと甘く見積もっていたので、今回の記事作成でにはデモ版を動かすまでに至れませんでした。
自分が満足するまでは引き続きやっていきます。デモ版ができたらまた紹介記事を書きます。
以上です。
スマブラAdventCalendar2020 まだまだ続きます。
ハッシュタグガンガン使ってね。
#スマブラAdventCalendar2020 hashtag on Twitter
明日は行動力の鬼なトーナメントオーガナイザー:てんぷらさん(@tempra_chan)がオフ大会関係の記事を投稿してくれるようです。
お楽しみに。