Emscripten で、iP6 をブラウザ対応
Emscripten で、isioさんのiP6 をブラウザ対応させました。
https://github.com/windy6001/iP6-for-Emscripten
Emscripten とは、 C/C++で書かれたプログラムを、JavaScriptなどに変換して、ブラウザで動かすことができるようにするプログラムです。
なぜ、iP6 Plus でないかというと、まずはなるべく小規模から積み上げていきたかったからですね。。 iP6 Plus はかなりの大所帯ですし。。
まず、Emscriptenのビルド環境を作るのがすごい骨な訳ですが。。。汗
Download and install — Emscripten 1.39.8 documentation この辺を参考にしながら、Mac (Mojave) でなんとかできました。
そして、まず、iP6 のソースリストを落としてきて、SDL2 に対応させます。。。
(なぜ、SDL2かというと、Emscripten向けに移植されているからのようです。)
その過程で、X11の設定パネルとか、Unix専用関数とかをどんどん、削ぎ落として、SDL2の描画APIを置き換えたりしました。
そして、コンパイラを、emcc に変えて、ビルドしていくのですが、オプションが普通と違っていて、-s USE_SDL=2 で、SDL2が使用可能になります。あと、--preload-file hoge で、hogeディレクトリの中のファイルを、データとしてつけることができるようですね。
あと、-o hoge.html で、出力ファイルを切り替えます。 拡張子.html を指定すると、html ファイルや、jsファイルなどを出力してくれます。
あとは、ブラウザで読み込めばいいのですが、何度やっても動かないので、なぜ?と思っていたのですが、どうやら、file://〜ではなく、Webサーバー経由で読み込まないとダメなようです。。
以下で、Webサーバーを起動して、http://localhost:8000/iP6.html にアクセスします。
$ ruby -rwebrick -e 'WEBrick::HTTPServer.new(:DocumentRoot => "./", :Port => 8000).start'
これの問題点として、実機ROMを使った時に、外部サーバーに置いて、自由に使ってね。とすると、そこから拡散していってしまうという、頭の痛い問題がありますね。。orz
ダウンロードを禁止できればいいのですが。。って、ダウンロードできなくては動かないし。。やはり、互換ROMを使うのがベターな解決方法でしょうか。。
あと、最初の方、キー入力が全く効かなくて、困りました。あとで分かったのですが、Z80CPUの Z80関数の中のローカル変数が原因だったようです。
SDL2のデスクトップの方は、無限ループで動作していますが、EmscriptenでJavaScriptにした方は、定期的にコールバックされる方式なんですよね。なので、Z80 関数の中のローカル変数は、そのままだと、Z80関数が呼び出されるたびに、不定な数値になってしまったりするんじゃないかと。。
結局、Z80関数から追い出して、グローバル変数にしましたが、static をつけてもいけるかも? うーん。
ちなみに、互換ROMでも動きますが、どうも、キー入力の取りこぼしが気になりました。なぜだろう?
あと、どうもIntelの脆弱性対策で、ブラウザのJavaScriptのスレッドが無効化されているのがあるっぽいですね。。
音楽を鳴らすためには、スレッドが必須だし。。マルチスレッド前提のプログラムはどうやっているんでしょうか。。うーん。困った。。
というか、その前に、SDL2 で、音楽鳴らすようにするのが先だな。。
あと、デバッグなんですが、あれ?なんか動かないぞ!と思っていたら、よーーく見ると、例外が発生したから、JavaScriptのコンソール見て!とか出ていることがあります。
それがわかりにくい。。まぁ、基本的には、SDL2でデスクトップ版をビルドして、そこでかなりのデバッグを行なっておく。。というのがいいと思いますね。。
しかし、ここまで、すぐに動いてしまうのか。。。と、驚きがありました。
他のエミュレータも移植できればな。。
(なぜかというと、某iOS だと、エミュレータって、見かけないからです。。
あと、GUIとかどうするんでしょうか?
今のままだと、機種の切り替えはもちろんできませんし、テープを入れたりももちろんできません。汗
QUASI88のように、GUI ( のようなもの)を、テキストベースで描画して、そこでやるという手もありますが。。。汗 かなりの骨だなぁ。。汗