ネタが枯渇しているので余り人気の無いお勉強のお時間です。マップ情報(フィールド、ダンジョン等)は全て圧縮されており、そのデコードルーチンは全て共通のようですが、フィールドマップとダンジョン,街など(便宜上サブマップと呼びます)ではデコード後の動作が大きく異なります。いろいろ見ていくと「フィールドマップの変更*1はかなり大変」というのが結論なのですが、データの構成を見ていきながらマップ周りの構成について説明していきます。フィールドマップに関してはバイナリwikiに乗っている情報とかぶります。
圧縮データのデコード方法は以前スレに解析した内容を投下してバイナリwikiに転載してもらったのですが、1回デコードルーチンをマップ表示のためにプログラムで書いた以降は仕組みをすっかり忘れてしまいました。人間が編集できる形に展開してさらにゲーム中で使用される形式に変換しているDQ3,6マップエディタは当然ながらエンコードルーチンも実装しているものと思われます(単に逆をやればいいだけですが)。この圧縮データのデコード方法は少なくともフィールドマップ、サブマップ(BG1,2,3まで)は全て同じです。通行構成情報については未確認ですが、これも恐らく同じではないかと推測します。
まずは、話が簡単なサブマップから先に説明します。サブマップの定義はサブマップインデックス($08C1F3-)で定義します。1つのサブマップはBG1,BG2,BG3を画像情報として持ち、さらに別途通行情報を持っています。それぞれの役割は以下のようになっています。
BG1 | キャラクターより描画優先度(Zオーダー?)が高い画像(街の壁など) |
BG2 | キャラクターより描画優先度が低い画像(街の床など) |
BG3 | 霧やダンジョン中の松明のエフェクトなど(必須ではない,昼夜で切り替え可) |
通行情報 | どの座標が通行可能か(ダメージ、回転なども含む) |
また、1つのサブマップにはどのマップパーツを使用するか、という情報を指定する必要があります。マップパーツ群データ($051450-)のインデックスを指定する必要があります。各マップパーツは異なる数のパーツを含んでおり、さらにその順番はマップパーツによって異なるので、当たり前のことながら違うマップパーツインデックスを指定するとぐちゃぐちゃになります。ちなみにマップパーツ群を0から定義しようとするのはかなり至難の業です。既存のものをコピーして一部変えるか、例えばDQ6からまるごとインポートならなんとかなるとは思いますが。マップの圧縮データというのはBG1,2,3,通行情報それぞれに対して存在しており、デコード後の1マスの番号はマップパーツのインデックスに相当します(多分)。それを重ねあわせて最終的なマップを構成する、という仕組みになっています。また、マップパーツを同じものを使う限り、圧縮データはどこにでも存在可能なので(開始アドレスをBG1,2,通行情報にセットすればいいだけ)、新しくマップを定義したい場合にもそれほど場所に困るわけではありません。
さて、問題のフィールドマップの構成ですが、サブマップと異なり、デコード後の1マスは16×16ピクセルではなくそれらが4×4マスで構成された「フィールドマップパターン」に相当します。さらにこのフィールドマップパターンのデータ形式が非常に問題で(バイナリwikiにも書いてありますが)、4×4マスの左上の情報が先に2621レコード(バイト)並び、次にその右の情報が2621レコード並んでいく…という構成になっています。
これは何を意味するかというと、「フィールドマップパターンを新規に定義するのが非常に難しい」ということです。フィールドマップの変更を行いたい場合、最終的な1マス(16×16ピクセル)の情報はこのフィールドマップパターンを変更することになるわけですが、そのフィールドマップパターンが別の場所でも使用されている場合、別の場所の地形も影響を受けます(まあ当たり前といえば当たり前)。DQ3SFC K.Mixでもフィールドマップパターンを変更してマイラまで陸続きにしたりダンジョンの入り口を配置したりしていますが、変更した地形が他で使用されていなかった特別地形だったから問題はありませんでした。これが複数箇所で使用されているような地形、例えば4×4マス全部海のパターンだった場合、絶海の孤島を定義しようとしてこのフィールドマップパターンを変えてしまうと、海中に島が出てくる、ということになってしまいます。じゃあどうすればいいのか、という話になりますが、新しくフィールドマップパターンを追加するほかありません。しかし、1マスごとの定義場所が16ヶ所に分かれているため、挿入場所が16ヶ所になります。さらに、各マスの開始アドレスがプログラム中でハードコードされており、その箇所が1マスに付き17ヶ所あるため、トータルで17x(16-1)=255ヶ所のアドレスを正しく書き換える必要があります。
実はこの作業はDQ3SFC K.Mixでロマリアとアッサラームの間の橋が壊れているフィールドマップパターンを追加するために行なったのですが、かなり神経を使う作業でした。バックアップをとってからこの作業のみを行ってその後エミュで動作確認する、という作業を一気に行い、変更が他の場所に影響を与えていないか、また変更部分が期待通りに動作しているか確認しましたが、イレギュラーな作業で二度とやらないから根を詰めてできた、というのが正直なところです。エフェクトの移植と並んで1,2を争うくらい「もうやりたくない」作業だったことは確かです(下手するとフィールドマップが壊れる非常に危険な作業)。もしこの作業をツール上で気軽に行おうとした場合、やるとしたら、上記4×4マスの配列にそれぞれ予め空き(200Byteくらい?)を持たせておき、ダブって使用されているフィールドマップパターンを変更する場合はその空き領域を使用して定義していく(この部分も人間で判断することは無理なのでダブって使用されているか調べるプログラムを書く必要がある)、くらいしか思いつきません。が、なにより自分自身にフィールドマップをドラスティックに変えたい、という需要がないために実際に行動を起こす気にはならないので、ここでは方法論だけを述べるにとどめます。
*1:局所的な変更は除く
コメント