MZ-1500版ドルアーガの塔(勝手移植) まとめ
定義済みのPCGだけを使って画面を更新するぶんには、全画面更新してもVRAMへの転送量は高々2000バイトですので、非常に高速に動作します。60fpsも余裕。やってることはMZ-700と同じですしね。
2014-10-19 13:05:28しかし、ゲーム中に動的にPCG定義をしようとすると、MZ-1500は途端に重いマシンに変わります。まず、PCG定義RAMへのアクセスウェイトが重い。水平ブランキング期間にしかアクセスできない(垂直はダメ)ので、最悪170クロックのウェイトが無慈悲にかかります。
2014-10-19 13:13:36こういうウェイト系の話は回路図をちゃんと読んでさらに実機検証しないとわからないのよね…エミュだと「必要に応じて実装する」ものであり不要なら実装されないわけで twitter.com/youkan700/stat…
2014-10-19 14:28:19ウェイトのかかり方自体はVRAMとほぼ同様なのですが、PCGは1個定義するのに8バイト×RGB面で24バイト分のアクセスが必要です。処理量が少ないから成立していた「不可能はない」が、処理量の増加によっていかんともしがたくなってしまいます…。
2014-10-19 13:21:11というわけで、MZ-1500で重ね合わせ有りの描画をしたければ、「可能な限り定義済みのPCGで画面を覆う」「重ね合わせによるPCGの再定義は最小限にする」という方針でやることになります。
2014-10-19 13:25:33ちなみに当時からこれに近いことをやっているのが1500版「サンダーフォース」で、地上を定義済みPCGで、空中物の部分だけを重ね合わせ・再定義して表示しています。サンダーフォースはあの重いPCGRAM上で直にガンガン重ね合わせをしてもあの速度なので、そのくらいの実力はあるともいえる
2014-10-19 13:32:32さてドルアーガでは、いかにもPCGですという見た目にしたくなかったため、4ドットスクロール・4ドット単位移動・完全な重ね合わせを目標にしました。4ドットスクロールは、隣り合う背景チップの全組み合わせをあらかじめPCG定義しておけば、VRAM転送だけで実現できます。
2014-10-19 13:39:21隣り合う背景チップの全組み合わせというとPCG定義数が爆発しそうですが、ドルアーガの迷路画面は幸いにも非常に規則的な構成になっていますので、結果150個程度で済みました。あとは、仮想VRAMにスクロール「+0ドット用」と「+4ドット用」を用意して、転送元アドレスを変えるだけです。
2014-10-19 13:45:12重ね合わせ用のPCGは、必要数とPCGRAMへの転送量との兼ね合いで、60個×2セットとしました。再定義中に画面が乱れないよう、ダブルバッファ的に使います。60個(1440バイト)転送するのに144ラスタかかります。
2014-10-19 13:49:471500版ドルアーガの続き。4ドット単位で移動することにすると、AC版のギルがジェットブーツ時1ドット/frameで動くことに鑑み、1500版は4ドット/4frame、つまり15fpsで動作する必要があります。これが実現可能かどうかはやってみないとわかりませんでした。
2014-10-19 14:32:4215fpsだと、使えるCPU時間は262×4=1048ラスタ。重ね合わせ用PCG60個をPCGRAMへ転送するのに144ラスタ、仮想VRAMから実VRAMへの転送に1フレーム弱、残り約2フレーム強でゲーム本体の処理・重ね合わせ・サウンド処理等々をまかなわねばなりません。
2014-10-19 14:36:49ドルアーガの塔のキャラクタは基本16×16ドット。MZ-1500のPCGで描くと2×2です。これが横に4ドット移動またはスクロールすると3×2、縦だと2×3、両方だと3×3のパターンも必要になり、1スプライトあたり計25個のPCGが必要。これが2パターン・4方向とかになると…
2014-10-19 14:47:44いかにMZ-1500が1024個のPCGを定義可能とはいえ、すぐに枯渇してしまいます。しかし、よく考えれば横向き用のパターンに縦4ドットずれたパターンは不要ですし、スライムや呪文など8ドット単位にしか移動しないもの・マジシャンのように交差点の中央にしか現れないものも同様です。
2014-10-19 14:52:35ギルやナイトの歩行パターンは、上半身は同じで足だけ動いているので、変化のある部分だけを定義し、他は使い回します。(ブルーナイト系などは盾も動くので「足だけ」ではないですが、目立たずに端折れる部分は端折ります)
2014-10-19 15:01:314ドットずれパターンに関しては、単なる空白になるパターンが結構ありますので、そういうところも当然省きます。このように、本当にPCG定義が必要なものだけを定義していきます。 pic.twitter.com/oIqLAYRR09
2014-10-19 15:22:57さて、フロアに登場するキャラクタのパターンを可能な限りPCG定義したら、いよいよ描画です。まず、仮想画面には迷路と鍵・扉だけのPCG番号が書かれています。ちなみに仮想画面は、Y座標が下位8ビット、X座標が上位8ビットとなるアドレスに配置し、INC/DECだけで隣のマスに移動可能。
2014-10-19 18:47:19キャラクタを構成するPCG1個を仮想画面に置く処理を考えます。まず、仮想画面のPCG番号をチェック。床のPCGなら、仮想画面にキャラクタのPCG番号2バイトを書くだけで終わり。最も高速に済むケースで、これでなるべく速度を稼ぐことになります。
2014-10-19 18:54:25描画先が床のPCGではなかった場合でも、半分が床のPCGの床部分のみにキャラクタを描画する場合、重ね合わせはせずに、描画先PCGの半分とキャラクタPCGの半分を単純に組み合わせた新しいPCGを定義します。4ドットスクロール時には多発するケースなので、完全重ね合わせより軽く済みます
2014-10-19 19:01:15そうでない場合、完全な重ね合わせが必要になります。MZ-1500には88SRのALUのような便利なものはないので、ソフトでRGB3面分をマスクでANDしてパターンをORして…とやるしかありません。重いです。
2014-10-19 19:05:10さて、重ね合わせ対象となるPCGは「床の上にいるキャラクタのパターン」なのに対し、重ね合わせ用のパターンは「キャラクタのみのパターン」です。前者はPCGRAM上には存在しますが、高速に処理するためにはメインメモリ上にコピーが必要です。
2014-10-19 19:10:33PCGRAM24Kバイトぶんのパターンのコピー、および対応する重ね合わせ用のパターンをメインメモリ上に持つとすると、それだけでほとんどのメモリを使い尽くしてしまいます。これはもうどうしようもないので、潔く「要RAMファイル」にすることにしました。
2014-10-19 19:13:59