PCエンジン時代の圧縮技術
1988年に初めてプロとしてハドソンでゲームを作れることになったとき、ハドソンではゲームを作るときデータ圧縮をするのが当たり前だった。
テキスト、グラフィック、マップ…ともかく圧縮できるものは全て圧縮するのが当たり前だった。
で「ウチは圧縮するのが当たり前になっているから、他よりゲーム規模が大きく出来てお得感があると思うんだよね」と(少々自慢気に)飛田さんが話していた。
確かにファミコン最初期の『ロードランナー』からして、普通に作ったのでは絶対に入らないはず(APPLEIIのディスク前提のゲーム、つまり128KBあるはずのものを16KBに移植している)なので、入れるためにはデータ圧縮になるよなあと思う。
だから、そこらへんの移植の経験から圧縮するようになったのだろうと想像していたのだけど、どうしてコレを始めたのかについての本当の理由がわからなくて、facebookでそこらへんを始めた頭目っぽい飛田さんと野沢さんに聞いたトコロ、答えがわかったので、メモ書き代わりに残しておく。
まず、技術的な話から始めると、当時ハドソンで使われていた圧縮の系列は2つあった。
一つがテキストの圧縮に使われていたhuffman。もうひとつがlzss。
huffmanは出現頻度に応じて長さの違うビットコードを割り当てることで圧縮する方法で、lzssはいわゆるスライド辞書法だ。
では、この二つをどうして使うようになったのか?
■飛田さん
なぜか(そもそもなぜ圧縮しようとしたか)といえばメモリ(ROM容量)が足りなくて少しでも有効にしようとしたからです。
ハフマンは有名で参考にするものが多かったから使ったんだけど今ひとつ圧縮率が悪かったので他のアルゴリズムを探してました。
その時確かPCVANでLZHの開発が進んでいて、その中のサンプルにlzssがあったのです。
展開時にメモリが少なくてすむアルゴリズムだったんで、その後かなり使ってました。
キャラクタ圧縮やメッセージ圧縮で主に使ってましたね。
PCVANは当時NECが展開していたパソコン通信のサービス。今のBIGLOBEにあたる。
LZHは当時pkarcというシェアウェアの圧縮が幅を利かせていたのだけど、いろいろな問題がありフリーウェアとしてlzh(lharc、のちのlha)が開発されていた。
完成したlzhは当時としては衝撃的な圧縮率で、日本の圧縮のデファクトスタンダードになり、windows時代になってzipが主流になるまで10年以上は日本の圧縮の主力になった。
■岩崎
ハフマンは当時のアスキーテキストは縮みますが…ですからねw
■飛田さん
ハフマンはバイトで扱うと最大でも1/8にしかならなくて、ツリーデータも必要でしたからね。データの偏りが大きくないと圧縮率が悪くなるし。
■岩崎
それで『凄ノ王』のときにはハフマン良く縮んだんだけど、イースになると縮まなくなったわけですよw
漢字仮名交じり文になりやがって、偏りが低下>コードが長めになるwwww
飛田さんが書いているようにバイトサイズでハフマン圧縮すると最良でも1/8、つまり理想的な圧縮度でも12.5%までしか縮まない(最小の長さで8bitが1bitになるなので、1/8までしか縮まないから、12.5%ということになる) とか様々な制限はあるのだけど、ハフマンはROM時代には、それでもテキストは良く縮んだ。
ところがこれが書いた通り、CDROMになると劇的にハフマンが縮まなくなった。
なぜか?
PCエンジンのCDROMではテキストはShift JISがそのままコードとして使われる構造になっていた。当時はもちろんそれが便利だったからだが、漢字かな交じり文で爆発的にコード種が増えた結果、ホワイトノイズに近くなってしまい圧縮率が低下してしまったのだ。
そしてスライド辞書法では特定の文字列が並ぶ構造がよく出る(例えば”……”があちこちに出ると4バイトのパターンがあちこちにバラまかれることになる)と圧縮率が上がる。加えてShift JISは特定の数値がやたら繰り返しで出る特徴があるのでLZSSの方がテキストは縮むことになった。
ところがlzssとhuffmanを比べた時、一つ非常に重要なポイントがあった。lzssはワークエリアがhuffmanよりはるかに大きく、当時のPCエンジンCDROMに最適化された自己書き換えバリバリコードでも256バイトのバッファが最低1個+少しのワークが必要だった。64KBしかメモリのなかったオリジナルのCDROM2では、256バイトはメインメモリの1/256で0.5%ぐらいの領域って話になるし、だいたいこの手のワークは、もっともメモリがきつい常駐領域に置かれなければならない。1バイトをケチってるプログラムで256バイトなんて贅沢なバッファの二つ目なんてアリエナイ。
対してhuffmanの場合にはツリーデータは必要だったが、それは非常駐領域におけるし、hufftreeを追いかけるポインタとデコード用のワーク程度で済むので、常駐領域の食われ方ではhuffmanに軍配が上がったので、huffmanを使い続けることになった。
今ならハフマンの圧縮率を上げる方法の解決策を思いつく(xorしてビットの偏りを意図的に作れば縮むようになる)のだけど、残念ながら当時はそこまで賢くなかったので、それは思いつけなかった。
と、これがPCエンジン時代の圧縮になる。
では、ファミコン時代は…?
■岩崎
ってことはファミコンの初期にはそこまで圧縮してない…?
■飛田さん
ファミコンの初期だとキャラクタROMだったんで圧縮できなかった。メッセージなんかは独自のビットストリーム的な圧縮を使ってました。
huffmanやlzssはPCエンジン以降だったと思う。
ファミコンの初期はキャラROMはそのままROMになっている構造なので、全く圧縮できなかった。だからベタで必ず置かれていた。
後期には転送可能にはなったが速度やワークエリアの問題もあり、無圧縮だったらしい。
■岩崎
え? ってことはロードランナーのマップもあんま圧縮してなかったんすか?
■飛田さん
どうやっていたのか知らないけど、それなりの圧縮はしていたと思う。ランレン系かな?
■野沢さん
スーファミかどうか覚えてないけど、キャラ定義できるタイプのcgーram系で本格的圧縮はじまったような感じ、rom物はコースとメッセージかな?
そう言う意味ではpcエンジンは画期的だったのさ。
音の波形も定義できたので。
そういやー、ロードランナーなんかの圧縮は単にビットパック程度だよ。タイルの種類が少ないので。
■岩崎
あーそういうことか! ビットでパックするだけで縮むのかw
というわけで、ファミコン時代はコースやメッセージの圧縮はしていたがキャラクタパターン、今でいうテクスチャはほぼ無圧縮だったわけだ。
ちなみに当時のコースの圧縮については、当の野沢さんがスターソルジャーでの圧縮について詳しく説明してくれているので、これを読むと、どんなことをやっていたのかわかると思う。
と、こんな風に当時のゲームマシンではデータ圧縮は行われていたのである。
※ 追記
当時のことが、奥村さんのウェブに残っていたのでリンクをここに貼っておく。
また、当時、奥村さんが出していた、この lzss.c が、まさにハドソンで我々が改造して使っていたlzssのベースになっている。
1件のコメント
コメントは現在停止中です。
AGENT: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
はじめまして こんばんわ
がんヘッド イース 天外魔境 スターそるじゃーと 当時の懐かしのハドソンソフトを遊んだ記憶がよみがえってきます。
あとのハドソン社といえば 桃太郎シリーズ PC原人シリーズ 高橋名人冒険島
かとちゃんけんちゃんなんかも好きだったなと
今はもうメガどころかギガだってがんがん使える時代ですからね
使ってないDouble型の変数が何個かあってもメモリ取りまくれますから
当時のゲームってでも少ない容量の中
面白いものっていうものが 単純に簡潔に表現されていて凄いですよね