Miyoo MiniのRetroArch Core(gpSP)をビルドする

Miyoo Mini用のレトロアーチ コアをビルドしてみた備忘録です。
2023/03/24 Onion V4.1.0について追記
2024/03/27 解決済みについて追記

解決済み

ポケモン不思議のダンジョン 赤の救助隊」のセーブについては、gpSP, mGBA共に修正されました!

mGBA

github.com

gpSP

github.com

ビルドしたい背景

ポケモン不思議のダンジョン 赤の救助隊」をgpSPでプレイしたいのですが、セーブが失敗し、セーブデータが保存されませんでした。
ステートセーブだけでも遊べなくはないですが、セーブできないのはモヤモヤします。

Miyoo Mini(Onion V3.11)にはいくつかGBA用のコアがあります。
VBA-Mだとセーブができるがなぜか動作が遅く、BGMの音割れもして遊べません。

セーブできない原因?

gpSPは「ポケモン不思議のダンジョン 赤の救助隊」のセーブデータを128KByte(1MBit)で保存します。
手元にあるカートリッジにはSSTの39VF512が搭載されています。
39VF512は64KByte(512Kbit)のフラッシュROMのようです。
(製造時期によっては128KByteのものもあったりするのでしょうか?)
セーブが成功するVBA-Mではセーブデータは64KByteで保存されています。
gpSPでセーブできない原因はセーブデータの形式によるものではないかと推測しました。

RetoroArch内のコアの設定からセーブデータの形式を変更できないか探してみましたが、それらしい設定項目はありませんでした。
gpSPはgame_config.txtというカートリッジ設定が保存された外部ファイルからセーブデータの設定を変更できるようですが、ソースコードを見る感じflash 128KBから64KBへ変更はできなさそうできした。(逆の64KBから128KBはできるようです。)

大元のカートリッジ設定はgba_over.hにあり、gpsp_libretro.soに組み込まれています。外部からの設定変更はあきらめて、gba_over.hを変更し、gpsp_libretro.soをビルドしなおすことにします。

ビルド環境

WindowsのWSL2を使って、Ubuntu 20.04.4 LTSでビルドしました。
Miyoo MiniのCPUはARM Cortex-A7なので、ARM用のバイナリでなければうごきません。
以下の手順でビルドできる環境を作りました。

まず、gitやmakeがなければインストールします。

sudo apt install git build-essential

Miyoo Mini用のツールチェーンはこちらを使用します。
github.com
ツールチェーンは解凍して、/opt/miyoominiに配置します。

wget https://github.com/MiyooMini/miyoo-toolchain/releases/download/v1.0/gcc-arm-8.2-2018.08-x86_64-arm-linux-gnueabihf.tar.gz
tar xzvf gcc-arm-8.2-2018.08-x86_64-arm-linux-gnueabihf.tar.gz
sudo cp -r gcc-arm-8.2-2018.08-x86_64-arm-linux-gnueabihf /opt/miyoomini

レトロアーチ用のgpSPはこちらを使用します。
github.com

git clone https://github.com/libretro/gpsp.git

Makefileにはmiyoo用の記述(おそらくPoketGo用?)があるので、流用します。

# Makefile
# MIYOO MINI
else ifeq ($(platform), miyoomini)
	TARGET := $(TARGET_NAME)_libretro.so
	CC = /opt/miyoomini/bin/arm-linux-gnueabihf-gcc
	CXX = /opt/miyoomini/bin/arm-linux-gnueabihf-g++
	AR = /opt/miyoomini/bin/arm-linux-gnueabihf-ar
	SHARED := -shared -nostdlib -Wl,--version-script=link.T
	fpic := -fPIC
	CFLAGS += -fomit-frame-pointer -ffast-math -marm -march=armv7ve -mtune=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4
	CFLAGS += -DSMALL_TRANSLATION_CACHE
	HAVE_DYNAREC := 1
	CPU_ARCH := arm

gbc_over.hのセーブデータの形式を変更します。

// gba_over.h
   {
      // Pokemon: Fushigi no Dungeon Aka no Kyuujotai (J)
      "POKE DUNGEON",              /* gamepak_title        */
      "B24J",                      /* gamepak_code         */
      "01",                        /* gamepak_maker        */
      0,                           /* flash_size           */
      FLASH_DEVICE_SST_64K,        /* flash_device_id      */
      0,                           /* save_type            */
      0,                           /* rtc_enabled          */
      0,                           /* idle_loop_target_pc  */
      0,                           /* translation_gate_target_1 */
      0,                           /* translation_gate_target_2 */
      0,                           /* translation_gate_target_3 */
   },

"FLASH_DEVICE_SST_64K"は"FLASH_DEVICE_MACRONIX_128KB"でなければなんでもよさそうです。

platformにmiyoominiを指定して、makeします。

cd gpsp/
make platform=miyoomini

Miyoo Mini用のgpsp_libretro.soができます。

動作確認

ビルドしたgpsp_libretro.soをMicro SD内のRetroArch/.retroarch/coresにコピーします。(元のgpsp_libretro.soはバックアップしておきます。)
Saves/CurrentProfile/states/gpSPの中にある「ポケモン不思議のダンジョン 赤の救助隊」のステートセーブを削除しておきます。
(ステートにはセーブ形式の設定も保存されているので、ステートを削除しておかないと前の情報が引き継がれて128KByteで保存されてしまいます。)
gpSPを起動し、セーブをしてみるとうまく保存されました。
他のゲームも特に問題はなくプレイできているので、とりあえずこれで遊ぼうと思います。

Onion V4.1.0以降

Onion V4.1.0よりGBAのデフォルトのコアがgpSPからmGBAになりました。gpSPはExpertから選択可能です。
mGBAも「ポケモン不思議のダンジョン 赤の救助隊」のセーブデータのサイズが128KByteとなっているので、64KByteに変更します。

// src/gba/overrides.c
// "B24J"の"SAVEDATA_FLASH1M"を"SAVEDATA_FLASH512"へ変更

	// Pokemon Mystery Dungeon
	{ "B24J", SAVEDATA_FLASH512, HW_NONE, IDLE_LOOP_NONE, false },
	{ "B24E", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
	{ "B24P", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
	{ "B24U", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
   },

今回はmiyoomini-buildbotを使って、GitHub Actionsでビルドしました。
github.com
ローカルにビルド環境を構築するより、buildbotを使った方が簡単でした。