読者です 読者をやめる 読者になる 読者になる

ファミコンミニでスーファミエミュレータsnes9xを動かす

さて、2ボタンしかない日本のファミコンミニSNES入れてどうすんだといわれそうですが、
まぁ海外モデルでは複数ボタンもあるしどうにかなるんじゃね、ということで試していたSNESエミュレータがぼちぼち動きそうなので少しまとめておきます。

 

とりあえず、retroPiとかにも持っていかれる元のsnes9xを選定してみました。

GitHub - domaemon/snes9x-sdl: Snes9x - Portable Super Nintendo Entertainment System (TM) emulator

 

ここからcloneしてコンパイルします。
まず、ファミコンミニに非常に近いA33上で動かしてみることにします。

このA33にはLCDをつけていて、X11とかはちゃんと動いていますが、
適当にコンパイルした状態だと色がきちんと出ないうえに、
横に二つ並んで表示される、という困った状態になりました。

 

何となく推測すると、フレームバッファの色解像度と
出力されているLCDの解像度が合わない、ということのようです。
ここで早めに「きれいに2つ並んでるんだから、元が16bitで32bitディスプレイなんだな」と気づけばよかったんですが、そこに気付くまでには結構時間がかかりましたw

これは、結構早い段階でファミコンミニでも再現できていたため、
A33上で同じ現象が出る、ということはファミコンミニでも直すのに役立ちました。

↓のはpcDuinoでコンパイルした奴をファミコンミニに持って行ったものです。
結構前から動かせそうで動かせてなかったんですよね。

 

で、いろいろ調べてみたところ、ファミコンミニフレームバッファHDMI出力は
「1280x720 32bit」にすればきれいに出る、ということがわかりました。

ここで、snes9xのSDLポートはどうなっているかというと、

f:id:honeylab:20170206192342p:plain

見事に16bit固定のようです。さらに、

f:id:honeylab:20170206192426p:plain

のように、内部レンダリングも16bit固定になっていました。
もしかして、ここを変えればいいんじゃね?と思いましたが

f:id:honeylab:20170206192856p:plain

ここに指定できるのは、結局16bitカラーのみのようです。
エミュレーションの都合上仕方がないようなので、作成されたバッファを32bitに転送することで色変換を実現しました。

 

内部バッファと一緒にスクリーンは別途作って

f:id:honeylab:20170206193400p:plain

f:id:honeylab:20170206193510p:plain

フリップ時にいったん経由して描画する

そんな感じなのと、SDL1.2に依存しているので拡大縮小が出来ず、最大パフォーマンスが出ていませんが、SDL2に移行できればSDL_BlitScaledが使えて、
そうすると内部バッファとの関係でもう少しパフォーマンスが上がるかもしれません。

 

で、今のところはとりあえずこんなもんです。

上から下に移動してる青線はフレーム描画のテスト用に書いてるものです。 


ちょっとまだ遅いし、画面解像度の1280x800を使い切れていない(小さめで書いてる)ので、ぼちぼち調整して、あとはパッド対応をしたらどうにかなるかな。