Anbernic 353PS
celesteが面白かったのでpico-8を携帯できないかと思って中華端末を買ったが、飽きてきたのでホコリをかぶっていたサターンのソフトを引っ張り出して動かしてみた。
端末に入っているのはyabasanshiroとかいうエミュレータで、libretro版とか言われるものと、standalone版が入っている。
yabasanshiro-lr (libretro版)
古の名作Advanced World War 千年帝国の興亡を動かしてみたが、地味にコマ送り気味で遅い。ちょっと使うには厳しい性能。右上の色が変なのも気になる。
グランディアも動いたが、戦闘がかなり遅くて厳しい。
yabasanshiro-sa (standalone版)
速度はまあまあ、何とか使えるくらいの速度が出ているが、結構致命的な問題がいくつかある。
Advanced World Warだと武器のリストが何にも見えないので使い物にならない。
グランディアだと戦闘画面で死んでしまう。
yabasanshiro-saの修正
yabasanshiro-lrが遅いので、もっと早い端末が出れば、、としばらく待っていたが出る気配がない。何とかしたいと思って試行錯誤。
ROCKNIXというカスタムファームウェアを入れてみたが、改善はされていないようだ。ただ、dockerで開発環境が準備されているので何とかビルドできそう。
イメージ全部はビルドできずに途中で止まってしまったが、とりあえずyabasanshiroのビルドはできるようだ。
PROJECT=Rockchip DEVICE=RK3566 ARCH=aarch64 ./scripts/build yabasanshiro-sa
PROJECT=Rockchip DEVICE=RK3566 ARCH=aarch64 ./scripts/build yabasanshiro-lr
グランディアが死ぬ問題
VIDOGLVdp1ReadFrameBufferがopenglのスレッドとは別のスレッドから呼ばれ、_Ygl->smallfboを別スレッドから作ろうとして死ぬ。最初に作っておけば死にはしないが、やはり別スレッドからフレームバッファアクセスできず、キャラが表示されない。
どうやらyabasanshiro-lrはOpenGL?でyabasanshiro-saはOpenGLES?で動いていて、サブセットであるGLESだとなんかこういうのがNGになるのかもしれない。
とりあえずフレームバッファをコピーするイベントを追加して、アクセスに来た時に、フレームバッファがコピーされてないならイベントを発行してyieldし、コピーされるのを待つようにした。
グランディアはこれである程度使えそう。
Advanced World Warが真っ黒になる問題
yabasanshiro-lrの方が移植の再現度が高いようなので、とりあえず影響ありそうなソースを片っ端からコピーして持ってくる。lr並みに遅くなるかと思ったが、たいして速度に影響はなかった。libretroが悪いか、OpenGLESが早いのかだと思われる。
セガサターンの中にはいくつか画面があり、問題となるのはNBG3の表示(SSFだと各画面のON/OFFができるのでそれで確認)だ。他の関数呼び出しを止めたりして確認していき、Vdp2DrawPatternPosの中でYglIsCachedに入っているかどうかが関係ありそうな気がしたが、デバッグ用にprintfしたら現象が出なくなるなど、ちょっとお手上げ。
とりあえずNBG3専用にVdp2DrawPatternPosNBG3を作って、cacheaddrをいじったりして、原因不明だが表示はされるという状態になった。他の端末で動かしたら表示されなかったりしそうだが、まあ自分しか使わないので良しとする。
Advanced World Warの背景が変な色になる問題
これは簡単に解決した。色情報にinfo.cor/cog/cobを足しているが、おそらく255を超えているため、色が変になる。Y_MINで255にリミットすれば大丈夫。
r = Y_MIN(Y_MAX( ((dot & 0x1F) << 3) + info.cor, 0 ),255);
g = Y_MIN(Y_MAX( (((dot & 0x3E0) >> 5) << 3) + info.cog , 0),255);
b = Y_MIN(Y_MAX( (((dot & 0x7C00) >> 10) << 3) + info.cob, 0 ),255);
いい感じ?と思ったら音が途中からガタガタ言い始める。でも疲れたので終了。
追記:しばらく動かしていると死ぬようだ。変更前のものでも同じ。もとから何か問題があるようだ。メモリリークのせい?