エミュレータ開発で、C++からJavaScriptへ変換し、さらにJavaへ移植するという話

東日本大震災の影響で、
東京に1年半ぐらい行かされて、
ごたごたした日々が続いてましたが、
ようやく落ち着きました。


システムエンジニアなんて、
天災の影響が少なそうな業種だと思ってたんですが、
そうでもなかったです。


仙台は、自治体とか電力とかNTTとかの案件がメインです。
一般企業向けのシステム開発も無くはないですが、首都圏と比べると比率的に少ないです。


震災で電力系とかは、新規のシステム開発やってる場合じゃなくなってしまい、
そのため、一時期は仙台でシステムエンジニアの仕事がなくなってしまったわけです。


今は、仕事も安定して、忙しくも無く暇でもなく、ちょうどいい感じです。
そんなわけで、趣味のエミュレータ開発をまた始めることにしました。


Docomoiアプリ用につくったPCエンジンエミュレータがあったのですが、
CD-ROM2に対応させるといったきり、放置プレイになってしまいました。


iアプリもオワコンのような気がしますが、作るといったからには作ったほうが
心残りが少なくていいかもしれません。


そのiアプリ用のPCエンジンエミュレータは、ixpceという名前ですが、
ベースのソースはxpceというエミュレータのものです。
これは、Huカードのゲームのみ対応しているエミュレータでした。


このixpceに、他のエミュレータからCD-ROM2対応のコードを移植しようとしてたんですが、
なかなか大変な感じです。
最初っから、CD-ROM対応のエミュレータを移植しなおしたほうがはやそうだと判断しました。


候補としてあがったのが、Ootakeとmednafenです。
どちらもいい感じのエミュレータなので、PCEのエミュレーションとしては申し分ありません。
なので、単純に移植しやすい方を選べばよさそうと判断しました。


また、今回は移植に新たなツールを使ってみることにしました。
emscriptenというツールです。
これは、なにをするツールかというと、
C++で書かれたソースコードを、JavaScriptに自動変換してくれるツールです。


とは行っても、ソースコードレベルの変換を行っているわけではありません。
emscriptenでは、
ClangというC++コンパイラを使用して、
元のC++ソースコードLLVMの中間コードに変換し、
そのLLVMの中間コードを、JavaScriptに変換するという処理を行っているようです。


今回はiアプリなので、Javaに移植したいわけで、JavaScriptじゃだめなんじゃないの?という話になりますが、
JavaScriptに変換であっても、
C++からJavaに移植した場合に発生する色々と厄介な作業と同様のことを、
自動でやってくれるため、
有用と判断しました。


JavaScriptJava同様に、unsigned(符号無し)の型がありません。
C++でunsigned charなどの符号無しの型で演算を行っている箇所には、
Javaに移植する際に、
その全部を探し出して、
8bitの変数なら & 0xFF、
16bitの変数なら & 0xFFFF といった、
AND演算のマスクをつける必要があります。
これがものすごく箇所が多い上に、
CPUエミュレーションのコアという重要な部分で、
たくさん出てくるので、
かなり厄介です。


ixpceを移植したときは、ソースを地道に読んで、 & 0xFF のマスクをつけていきました。
たぶん、付け忘れたところもあって、そういうところはバグってるはすです。


emscriptenを使うことで、JavaScriptに変換した際に、&0xFFのマスクが勝手に付いてくるはずなのです。
これなら、移植バグを入れる心配が減ります。


また、C言語のポインタ演算や、マクロ、共用体も厄介な存在です。
これらもJavaScriptには無い概念です。
同時にJavaにも無い概念なので、移植の際の妨げになりますが、
それらも全部emscriptenが、CからJavaScriptへ変換する過程で、
全部消してくれます。



そして、emscriptenが生成したJavaScriptソースをJavaソースへ手作業で移植すれば、
unsigned型も、ポインタも、マクロも、共用体も気にする必要が無くなるので、
手作業でバグを入れてしまう危険性も下がるため、
精度よく移植できるのではないかという
もくろみをしています。


で、実際にやってみたんですが、
Windowsに、
Subversion入れて、
Python入れて、
SCONS入れて、
V8入れて、
GnuWin32入れて、
LLVMとClang入れてビルドして、
なんとかemscriptenを動かせる環境ができあがり(ここまでで半日かかってる)
Ootakeをビルドしようとしました。
しかし、ClangはWindowsSDK内のコードでビルドエラーになっちゃう部分がけっこうあるみたいです。
OotakeはWindows用のコードがあちこちにあるので、Clangでビルド通すのがけっこう難しそうです。


しょうがないので、
VMWareubuntuを入れて、
Subversion入れて、
git入れて、
V8を入れて、
Node.jsを入れて、
SCONSを入れて、
g++を入れて、
LLVMとClangを入れてビルドして、
cmakeを入れて、
ようやくlinuxemscriptenを動かせる環境ができました。
で、mednafenをビルドしようとしたのですが、途中でビルドエラーが出ます。
でも、けっこうおしい感じで、ちょっと直せばビルド通りそうです。


雰囲気的には、
Ootakeベースよりは
Mednafenベースのほうが
移植が楽そうな印象をうけました。


しかし、Mednafenはマルチエミュレータなので、
PCE以外のソースを削らないと、あまりにもソースの量が多すぎるので、
まずは、PCE用のコードを切り出す作業をやろうと思います。