皆さま、自粛期間いかがお過ごしでしょうか。音ゲーマーにとってはゲーセンの閉店が一番きついかもしれませんね。
というわけで、beatmania IIDX(以下、弐寺)のコントローラー自作について書いていこうかと。初回は目次を兼ね、今後投稿する予定の記事のダイジェストみたいなものを投稿します。3~5記事くらいでしょうか。
はじめに
自作とはいいますが、正確には「ごく一部を残して大幅に改造」です。このコントローラーはもともとDAOコンでした。現存する最も古い姿の写真です(非常に良い条件で譲って頂いて、ありがたい限りです…)
しんのきさんから譲り受けたDAOコン、直せるところは直したが1P側の基板が死んでるので自作しないとな。 pic.twitter.com/DeWmFc5zTz
— しありす (@cialis438) March 8, 2019
これでも機械的な部分のオーバーホール(ターンテーブル軸のベアリングのグリス交換、底面パネルのネジ山修整、断線したケーブルを新品でリプレース、ボルトとナットを全てステンレス製の新品に交換、アームレストの布張り替えなど…)が終わったところです。この辺楽しくないと思うのでブログ記事にはしません。写真を一枚だけ。このときついでに背面パネルも改造済みです。しかしまだまだ以下のような不満点があります。
- ポーリングレートなど性能の決して高くない&ケーブル着脱式にするのが難しいプレステ2コントローラーとして回路が作製されている
- 基板設計が全体的にイケていない。コンバーターを噛ませない限りプレステ2にしか対応しないし、ボタンを光らせる必要がないときでも補助電源の接続が必要
- ターンテーブルの表面処理がアーケードとかなり違ってちょっとダサい
- 皿の感度が悪い
- 最新のINFINITASコントローラーはファンクションキーが4つあるが、2つしか実装されていない
などなど。
とりあえず、一番困ったのは時代遅れなプレステ2コントローラーである点ですね。コンバーターの遅延を気にしながら音ゲーをするのはキツいので基板ごと入れ替えてしまいましょう。現在、このコントローラーが対応しなければならない用途は以下の3つです。
- CS弐寺: プレステ2タイトルですね。
- INFINITAS: コナミ公式が配布、運営するPCゲームです。
- BMS: やねうらお氏が規格を制定したことで有名ですね。有志による実装が何種類かそれぞれPCゲーとして配布されています。
見ての通り、一番上がプレステ2で他がPCなわけですが、少し考えたらプレステ3初期型でプレステ2タイトルがプレーできることに思い至りました。これならUSB接続のみに絞ることが出来てハッピーです。
しかしPS3とINFINITASはコントローラーがオフィシャルなものかチェックされるため普通にコントローラーとして実装しても非公式品とバレてしまい動きません。コントローラーとしての仕様もそれぞれ異なるため適当な出来合いの基板ベースで作れない、困った…
マイコンプログラミング編
仕方がないのでUSB機能の載ったマイコンの勉強から始めましょう(は?)。AT90USB646 - 8-bit AVR Microcontrollers
これですかね。チップ自体は500円ちょっと、48ピンもGPIOが引き出せます。
実装すべきファームウエアは実機のリバースエンジニアリングで得るよりほかありません。自作コントローラーの最大のコミュニティであるGIMXのadmin、matloさんがUSBスニファの使い方などを公開してくれているので、ありがたく使わせて頂きましょう。
github.com
USBのホスト側とゲスト側、両方のコネクタを持つBBBというミニPCをUSBの信号中継器のように使って、通ったパケットを全部dumpする感じですね。USBケーブルを使って通信している以上、原理上コントローラーの全ての動作が確認できます。ビューワにはWiresharkを使えて非常に便利です。[PS3]-[BBB]-[コントローラー]という構成でPS3との通信を監視します。結果から言うと特別なパケットのやり取りなどはしておらず(PS3のコントローラーって怪しいVendor definedのUsageをいくつか持っているので疑っていましたが…)、USB HID descriptorとDevice descriptorが同一であればPS3が「既知のコントローラー」として認識してくれるという感じみたいです。オフィシャルの、動くコントローラーからデバイスの情報をベタ書き移植すれば十分動きます。この点、実はGIMXコミュニティーでも知られていなかったようなのでフォーラムに投稿しましておきました。ニッチながら世界初です(?)
お次はマイコンプログラミングですが、5年位前から自作コン自体は作りたくて、マイコンの勉強ちまちましていて本当によかったです。450ページもあるデータシートとにらめっこしつつ、実装します。普段のC++を使ったプログラミングと比べて変わったところがあるとすればレジスタの扱いを強く意識しなければならないのと、ほとんどRAMがない(64kBとか)ってところでしょうか。小さめの簡単なデバイスから順に作って経験を積むうちに大抵扱えるようになりましたが、このマイコンが問題なく扱えるようになるまで年単位で時間がかかってしまいましたね。USB2.0の規格そのものの勉強(バイブル)も結構必要でしたし。
メモリも限られているためUSB HIDとしてのディスクリプタは通常定数としてハードコードしますが、複数のファームウエアを切り替えながら動作することを想定し、全てPROGMEMへのポインタという形で持っておき実行時に参照します。これでメモリを食わずにデカい定数をハードコードすることを避けられます。あとは起動時にポインタにアドレスをセットするようにすればUSB機器としてのファームウエアを切り替えることができます。このトリックについては後日また改めて記事にします。ともあれできたコードがこれ。
github.com
ついでに他機種にも対応可能な汎用性を持たせてみました。コントローラー製作の一番の推しポイントなので詳しめの記事に出来るよう頑張ります。