ファミコンを改造? ~キンファミのご神体~
チャオ・アミーゴ! 読んでくれてありがとう。ここではサンチョ石際がキンファミを支える技術について説明します。
ファミコンをkintoneと連携させる
・・・とはいうものの、どのように連携させるのでしょうか? TeamKFCでは複数の方法を検討しましたので、ご紹介したいと思います。
ファミコンをクラウドシステムと同居させる方法として考案されたものは、次の4つです。
- ROMファイルをJavaScriptを利用してkintone上で動かす。
- 改造カセットを利用してPCと連動するソフトウエアを作成する。
- ファミコン自体をミニPCにしてしまい、ゲームパッドの信号を受ける。
- PCとゲームパッド自体を改造して直接PCへUSB接続する。
まず、1はnes-js(https://github.com/takahirox/nes-js)を利用して、ROMをJavaScript上で動かすことはできます。でもkintoneのデータをゲームから参照することはできません。また本物のファミコンとも同居が難しいです。
なので、最初の構想から外れました。
3と4については、改造の主体がゲームパッドにあり、可能ならば3が、不可能であれば4という妥協案を採る作戦です。ファミコンのゲームパッド基盤は改造キットがあり、USB接続でPCにゲームパッドとして認識させることができます。
2についてはFC-DEV-100というFC-ROMエミュレータがあり、PCと通信しながら動作をさせることが可能です。実際のプログラムはアセンブラを使用します。
3,4,2と技術を確認した結果、2については開発量が多すぎるので、スケジュールを鑑み3,4を採用しました。3,4であれば既存技術を応用できる点も大きかったです。
kinfamiのファミコン筐体
kinfamiのファミコン筐体(外装の部分)は本物のファミコンです。兵庫県のゲームショップで980円で売られているところを購入してきました。やはり本物の存在感にはかなわないので、もしやるなら最初から本物を使うことを決めていました。
これがファミコンの内部です。
ゲームパッドの基板を入れ替えてPCと接続して試します。
ゲームパッドを利用して画像が動いているのがわかると思います。
ゲームエンジン
ゲームというのは画像を一定間隔で描画して、刻一刻と変わる状態を管理するプログラムです。これらを管理するためのライブラリをゲームエンジンと呼びます。JavaScriptではEnchant.jsやPhaser3といったライブラリがあります。ただ、改造ゲームパッドの信号は市販のUSBゲームパッドと規格が違うので、うまく狙った動作や制御ができない問題が発生しました。
この問題に対応するにはJavaScript上でゲームの仕組み自体を最初から構築する必要がありました。
僕はふだんReactを利用してkintoneのカスタマイズやプラグインを作っているのですが、これを利用してゲームを作ってみたいと思っていました。ReactはDOMから入力を受けるのに特化しているので、本来であればCanvasベースの技術にしたほうがよかったのですが、この時は興味が勝ってしまって、Reactでできるところまでやることに決めました。
そういったわけで、kinfamiのJavaScriptで主に使用しているは下記です。
- gamecontroller.js:ゲームパッドの信号受け取りをリスナ式に変更する。
- React:いつもの。MUIも一緒に使っている。
- @kintone/rest-api-client:kintoneと連携する。
- typescript:開発言語
- webpack:バンドラー
ミニPCへの試み
ファミコン自体がPCとなり、kintoneに接続できたらとっても素敵ですよね。ファミコンの内部基板はすべて取り払い、USB化したゲームパッドを接続できるように、ファミコンの外装にRaspberryPiを埋め込もうとしました。
ただ、ゲームエンジンを自作したのが仇となり、ゲーム自体がかなり重たくなってしまいました。RespberryPiも3Aしか入手できなかったので、ブラウザを利用するにはかなり無理がありました。
これがご神体を後ろから撮影したものです。結局1コンと2コンをUSBゲームパッド化したうえで、USBハブでPCと接続します。ファミコン自体をミニPCとして独立させるのはあきらめました。時間もなかったですし。
といったわけで、キンファミの筐体=ご神体は2つのUSB化ゲームパッドです。
まとめ
kinfamiのご神体は本物の中古ファミコンです! しかし内部の基板が改造され、2つのUSB化ゲームパッドとして接続されています。ただし、信号は独特なので、ゲームエンジンは自作となっています。
今日はここまで。アディオス・アミーゴ!