なるべくRAMへ逃がす話

2017/10/29 | 投稿者: ghost

今回の開発で留意しようと思っていて実際にやっていることについて、途中で自分が忘れてしまわないようにメモ。以下に書くことは、目下の開発スタイルにある程度特化した話であり、必ずしも普遍的なものではないことを予めお断りしておく。

まず前提として、今回も前回同様に32KBのROMフォーマットを採用している。以前、メモリマップの概略図を示したことがあったかと思うが、32KB ROMフォーマットというのは、Z80の素のアドレス空間64KBを、MSX-BIOS ROMに16KB、ゲーム本体(ROMカートリッジ)に32KB、MSX本体のRAMに16KB配分して使うスタイル、ということになる。そしてこの方式を採用する場合、ゲームのプログラム、グラフィック・サウンドのデータは、当然のことながら32KBのROMの中に収まっていなければならない。

そもそもMSXというシステムは、基本的な入出力はBIOSサブルーチンがやってくれたり(その分、プログラマが書くコードは減る)、低メモリでもそれなりに複雑なグラフィックを描くことができるVDP TMS9918を採用していたり、と、小さなメモリ空間でもそれなりのことができるよう設計されている。その観点からすると、32KB=32,768バイトというのは開発開始時点では「こんなの使いきれるのか?」と思ってしまうほどに広大なメモリ空間なのだが、でありながら、ドラコニックスロウンの開発最末期には、メモリ不足への対応に苦労する羽目になった。

今「メモリ不足への対応に苦労」と書いたが、逆に言えば、労を惜しまなければ「メモリ不足」に陥らない「対応」の手段がいろいろある、ということでもある。敢えて仰々しい言い方をすれば、ある表現形とそれを実現するプログラム・データ構造は一対一対応はしておらず、絶対的情報量による限界に至るまでの間にメモリ節約については無限の好適手が存在し得る、ということなのだが、ドラコニックスロウンで「苦労」したのは、ほとんどゲームが完成した後でこのメモリ使用の最適化に着手したがために、既にその時点で確定している仕様に影響を与えないように等価かつ軽量なプログラム・データへ置き換えるのに「苦労」したのであって、これを開発当初から心がけておけば、これはしなくていい苦労じゃないか、というのが、まぁ、現時点での取らぬ狸の皮算用なのである。

さて、どのような対応手段があるだろうか。抽象的に一言でまとめると、あるデータ構造があるとして、そのデータが何らかの計算の結果得られるものであり、かつ、その計算のためのプログラム長がデータそのものよりも短くなるのであれば、データをプログラムから生成する、ということになる。


これは何を言っているのかと言うと、「あるデータ構造」をそのまま記述する場合、これはROMの容量をそのまま消費する。対して、同じデータ構造を生成できるプログラム……これもROM容量を消費するのだが……の長さがデータ構造よりも小さくできるのであれば、プログラムだけをROMに搭載し、ゲームの初期化処理中でそのプログラムを実行した結果をRAMに書き込み、ゲーム中はそのRAM上のアドレスを参照すれば、(本来のデータ構造の長さ)−(データを生成するプログラムの長さ)分だけROMの消費を節約できる、というまことに世知辛い話なのである。

ROMが32KBに対し、RAMは16KBしかないのだから、返って不都合なのでは?と思う人もいるかも知れないが、そもそもゲーム程度のプログラムが必要とするワークエリア(RAM)の容量はたかが知れており、かつ、RAMは書き換え可能なメモリであるがゆえに使い回しが効くので、そこは実用上は問題にはならない。


先に示したスクロールを題材に具体的に考えてみよう。

このスクロールは、微妙に異なるパターン……より厳密を期するならば、絵柄が左方向へ1ピクセルズレたパターン……を次々と画面に表示することで実現されている。スクロールの速度差、さらには、本来的には縦方向8ピクセル毎にしか変化させられないはずのパターンを擬似的に4ピクセル毎に分割して扱う都合もあって、必要なパターン(8×8ピクセルのタイル)の数は104種になっている。

この104種の絵柄の形状および色を、真正直にTMS 9918の仕様に準じたデータとして記述すると3,328バイトになる。32KB中の3KB強だから、結構なROM容量の消費だ。

が、上掲動画のスクロールが基本的に同じ図柄の繰り返しからなっていることを見ればわかるように、大元になっているパターンは実は6種しかなく、残り98種は、この6種をビットシフトして生成することができる。まさに「本来のデータ構造の長さ−データを生成するプログラムの長さ分だけROMの消費を節約できる」理想のケースだ、と言える。では、いかほど節約できただろうか。

何も考慮しない場合、前述の3,328バイトに加え、このデータ構造をVDPを経由してVRAMへ流し込み、結果として画面表示せしめる部分に48バイト必要なので、計3,376バイトが必要になる。

対して、今回おこなった実装では、前述した大元となる6種パターン分のビットデータ48バイトのみが恣意的な数値データになっていて、531バイトのプログラムで以って大元のデータを逐次変形させつつVRAMへ流し込み、結果的に3,376バイトを必要とする処理と同じことをやっている。これを圧縮と見做せば、圧縮率は16%ということになる。しかもこのロジックは、ステージ毎にスクロールする帯の色の組み合わせを変更する機能も含んでいるので、実質圧縮率はさらに高いものになっている。

まぁ、だから何だ、というワケではなくて、そもそも上に例を示した手法は決して普遍的なものではなく、本作の背景スクロールの設計構造に依存している(というか、このメモリ節約をしつつ最大限の演出効果を得るべくこのように設計した、というのが正しい)し、そもそもこのような考え方自体が事実上無限のメモリを扱い得る今日的なコンピューティングにおいてはまったく意味のないエネルギーの無駄遣いの極致なのであるが、こうして書き残しておかないと、何かの拍子に失念してROM容量を浪費し、完成間近になって再び自身の怠惰を呪う羽目に陥るのは必定なので、備忘しておくことにした。というか、ボクはこの備忘録の執筆も含めて、こうした無駄なことをするのが好きなのである。
タグ: MSX Z80



トラックバックURL

トラックバック一覧とは、この記事にリンクしている関連ページの一覧です。あなたの記事をここに掲載したいときは、「記事を投稿してこのページにお知らせする」ボタンを押して記事を投稿するか(AutoPageを持っている方のみ)、記事の投稿のときに上のトラックバックURLを送信して投稿してください。
→トラックバックのより詳しい説明へ




AutoPage最新お知らせ