2016年12月18日日曜日

ゲーム機エミュレータの技術的な話

割と古めのエミュレータのソースコードを眺めてみて、プラットフォーム依存(主にWindows依存)の実装がモリモリと入っているものが多いなと。

エミュレータのコア部分は、必ずしもプラットフォームに依存する必要はなくて、Cの標準ライブラリやC++のSTLだけで実装できるものです。

何処までがプラットフォーム非依存(PIL)で、何処からがプラットフォーム依存(PDL)か。
その線引は、以下のようになります。

【プラットフォーム非依存】(PIL)
・CPUなどのエミュレーション全般
・プラットフォーム依存(PDL)間のブリッジ

【プラットフォーム依存】(PDL)
・映像出力
・音声出力
・入力機器からの入力

コードで書いた方が分かり易いので、LaiNESというファミコンエミュレータの実装をベースに見てみると分かり易いです。

オリジナルのLaiNESは、PIL と PDL が若干入り乱れているので、純粋な PIL だけを切り離した LaiNES を私の方で作ってみました。
https://github.com/suzukiplan/LaiNES

上記のSUZUKI PLANカスタム版LaiNESは純粋なPILのみ実装している キレイなエミュレータ なので、ターミナル上でファミコンを動かすこともできてしまいます。上記リポジトリのtest.cppが実際にターミナル上でファミコンを動かすプログラムの例です。

ファミコンを動かすといっても、ターミナル上でPDL(の全て)を再現するのは厳しいので、PDL部分(namespace HALの部分の実装)はダミーですが。

それだとあんまりなので、このSUZUKI PLANカスタム版LaiNESを用いてAndroidでPDLを実装してみた例も作ってみました。
https://github.com/suzukiplan/nes-view-android

なお、動作についてはPublic DomainのROMで確認してます。