SDK2/3 圧縮データの仕様SDK2/3では地形データ、グラフィックデータなどが圧縮されています。これら圧縮データの形式は以下の通りとなっています。
<頻度テーブル><圧縮コマンド><データ(あれば)><圧縮コマンド><データ(あれば)>・・・
1.頻度テーブル圧縮ヘッダは、出現頻度の高いデータをリスト化したもので、一部の圧縮コマンドによって暗黙的に入力されるデータとなります。
8bitデータ4つ、16bitデータ17個の計38バイトの大きさを持ちます。
byte0: 連続出現しやすい8bitデータ1 (最頻値)
byte1: 連続出現しやすい8bitデータ2
byte2: 単独出現しやすい8bitデータ1 (最頻値)
byte3: 単独出現しやすい8bitデータ2
byte4: 単独出現しやすい16bitデータ1 (最頻値)
byte6: 単独出現しやすい16bitデータ2
・・・
byte36: 単独出現しやすい16bitデータ17
なお、圧縮処理を実装する際、このサンプル選出、特に16bitサンプルにとりわけ注意を必要とします。
散発的に出現する16bit値W1と連続的に出現する傾向のある16bit値W2がソース内に同じ確率で現れる場合、W1を優位にしたほうがよい結果が得られます。これは以下の理由によります。
W1が頻度テーブルから漏れたとき、W1の書込み1回には最低2.5bytesのコストがかかるが、W1が頻度テーブルに入っていれば、W1の書込み1回には最大でも1byteのコストしかからない。
W2が頻度テーブルから漏れたときと漏れなかったときでは、せいぜい1~2bytes程度のコスト差しかない。
W1とW2の出現確率が同じ場合は、単発の書込み回数が多いW1のほうがコスト差が影響する。
W1と同じ優先度になる16bit値W3は、散発的にW1と同じ確率で現れるか、W3が連続している塊がW1と同じ確率で出現するような性質を持ったものとなります。
つまり、W3が連続的に出現する場合は、W1より高い確率でソース内に現れなければ同じ優先度になりません。
これが、頻度テーブルに採用される値の殆どが単独出現しやすいものとなっている理由です。
2.圧縮コマンド圧縮データはすべて4bit単位で取り扱われます。そのため、読み出し中に頻繁に4bitずれますが、コード側では適宜ビットシフトを行って対処しています。
[0X]
ROMからXバイトをコピーします。すなわち、0Xに続くデータをXバイト読み取ります。
Xが0の場合は展開処理の終了宣言です。すなわち圧縮データは00で終わる必要があります。
[1XX]
XXを1回入力します。
[2XXYY]
XXYYを1回入力します。(Big Endianであることに注意)
[3XYY]
YYをX+3回入力します。X+3回と定義されているのは、入力回数が2回以下の場合は別のコマンドのほうが効率がよいからです。
[4X]
頻度テーブルの連続出現8bit値1をX+3回入力します。
[5X]
頻度テーブルの連続出現8bit値2をX+3回入力します。
[6]
頻度テーブルの16bitデータ1を1回入力します。
[7]
頻度テーブルの単独出現8bit値1を1回入力します。
[8]
頻度テーブルの単独出現8bit値2を1回入力します。
[9X]
X+2バイト前から2バイトをコピーします。
[AXYY]
X+3+YYバイト前からX+3バイトをコピーします。[9X]の拡張コマンドです。
[BXYYZ]
YYZ+0x103バイト前からX+3バイトをコピーします。[AXYY]の拡張コマンドです。(Big Endianなのに注意)
[CXYYZZ]
YYZZバイト前からX+3バイトをコピーします。[BXYYZ]の拡張コマンドです。(Big Endianなのに注意)
[D]
直前の1バイトをコピーします。
[E]
直前の2バイトをコピーします。
[FX]
頻度テーブルの16bitデータX+1を1回入力します。
※[0X]以外のコピーコマンドのコピー元ソースは、
展開したデータを格納しているバッファ(通常7F:0000)です。圧縮データを参照するわけではありません。