マリオWiiの有名な改造作品の中に、Another Super Mario Bros. Wiiというやつがあります。 以下からダウンロードできます。
ただし、上の公式サイトには以下のような記載があります。
This mod is compatible with all US game discs, and version 1 of the European release. Japanese discs and European v2 are not supported.
「日本版に対応してないのかよ」と思うのですが、実は日本版もサポートされています。実際にダウンロードしたファイルに同梱されているマニュアルを読むと、以下のように記載されています。
どっちが正しいねん、と思うんですけどまあ同梱されているファイルの方がより最新版であると一般的には考えられるでしょう。
で、これで動いてくれるならいいのですが、改造まとめWikiに以下のような記載がある通り、2-城で進行不可能になるバグが存在します。
手っ取り早い処置は02-24.arcを削除してしまうことなのですが、それではもったいないです。なので、今回はこれを修正します。
パッチの修正
改造まとめWikiではステージを改変することによりバグを回避していますが、そもそもパッチが日本語版でもちゃんと適用されるようにすればいいはずです。そういうわけで、ここでは直接Riivolutionのパッチを修正することにします。
事前準備: RAMのダンプ
パッチを修正するにあたってメモリの中身を直接確認しながら作業する必要があるので、Geckoのコードを変換するときのようにマリオWiiのメモリダンプが必要です。
メモリダンプはどのように用意してもいいですが、自分はパソコン内で作業を完結させたかったのでDolphinの機能を利用しました。ここではその手順を載せておきます。
必要なものは以下の通りです。
- Dolphin 5.0(バージョンは最新の開発版を使いました)
- 日本版のNewスーパーマリオブラザーズWiiのROM
まず、Dolphinを起動するときに"-d"というオプションを付けて起動します。Windowsの場合、以下のようなショートカットを作成すればよいです。
Dolphinが起動したら、メニューから「表示」をクリックして「Memory」にチェックマークを付けます。この状態でゲームを起動してエミュレーションを一時停止し、Memoryウィンドウの右下にある「Dump MRAM」を押すことでMEM1領域、「Dump ExRAM」を押すことでMEM2領域をダンプできます。ダンプしたデータが保存される場所は設定の「フォルダ」タブから確認・変更できます。
以上でmem1.raw
とmem2.raw
というファイルが入手できます。今回のケースではMEM1領域のデータしか使いませんが、他のゲームでMEM2領域のデータが必要になった場合はこの方法でメモリダンプを自分で準備することができます。
バイナリエディタでmem1.raw
を開き、最初の6バイトがゲームID(今回の場合はSMNJ01)になっていればおそらく正しくメモリのダンプができています。
メモリダンプを基にパッチを修正する
適当なテキストエディタでAnother.xml
を開きます。自分はVS Codeを使います。
最初開いたときはインデントが崩れていたので、直しました。
今回問題となっているのは、patchというブロックの下の方にあるmemoryという要素です。Riivolutionは基本ファイルの置き換えをするツールという認識だと思いますが、メモリの書き換えも行うことができます。
memoryという要素はoffsetに指定されているアドレスの位置の値をvalueで指定されているものに書き換えるという処理を行う*1のですが、ここに問題があります。それは、offsetがディスクのリージョンごとに違うという問題です。
先ほどメモリダンプを用意しましたが、同じゲームでも日本版と海外版で異なるデータが得られます。まあ、当然と言えば当然なのですが、これが少し厄介です。本来これを修正しようと思ったら海外版のメモリダンプも必要になってしまうのですが、今回は日本版ディスクにも対応しているNewer Super Mario Bros. Wiiのパッチを参考にすることにします。
NewerSMBW.xml
を見てみます。Anotherと同じアドレスをしているものが無いかなと探してみると、ありました。
どうやら、0x802F118Cあたり(US版基準)の値を書き換えることでセーブデータファイルの名前を変更していて、0x80328130あたりの値を変えることで何か特殊なことをしているっぽいです。(記事下部に追記あり)実際、日本版のmem1.raw
の0x2F0FACから8バイト先あたりまでの値を見てみると、以下のようにセーブデータファイルの名前の位置に対応しています。
AnotherとNewerのどちらも共通して0x80001800からの値を書き換えているのですが、Newerのパッチから察するにリージョンに依存しないのかなという感じなので、とりあえず放置です。
以上の方法で修正したAnotherのパッチは こちら に置いておきます。(パスはanotherです)
今実機環境がすぐに用意できないので動作チェックしてないのですが、多分動いてくれるはず…。
追記
パッチの仕組みをよく考えないまま記事を書いていました。すいません。
Anotherのパッチの本体は0x80001800の位置に挿入しているやつです(パッチの一番下に書いてある一番長いやつ)。これを日本版にも適用してあげれば、多分バグが直ってくれるはずです。
で、0x80327E98の位置に0x80001800という値を挿入していているわけです。これは完全に間接アドレス指定方式と同じ構図です。なんで気が付かなかったのか。エンジニア名乗るのやめたら?
というわけで、多分何らかの専用のプログラムをメモリ上の0x80001800の位置に展開していて、それを読み込ませているということなんでしょうね。
自分としても、もやもやがスッキリしました。別に書き換えたパッチ自体は正しいので、ファイルを新たに書き換える必要はないです。
*1:originalというパラメータはこれに合致しているものだけを置換するようにするということだと思います