SEENファイルのフォーマット

ホーム>SEENファイルのフォーマット

KanonやAirなどのKeyのゲームをインストールしたフォルダの中の DAT フォルダを開いてみて下さい。 SEEN.TXT というファイル(勝手にSEENファイルと呼びます)があると思います。 ゲームのシナリオはこのファイルの中に入っています。 このファイルのファイルフォーマットを調べてみました。 途中までしか分かりません(というか、これ以降調べる根気がなかった)でしたが、テキスト読める程度にはなります。
なお、テキストを吸い出すツールは既に存在します。テキストを吸い出すためにこのページを見る意味はありません。
また、このページの内容を確認したのはAir通常版、Kanon全年齢対象版のみです。
あと、このページ内のファイルフォーマット関係の用語は私が勝手につけたものです。

1.ファイル概要

FILEHADER
DATAHEADER 1
DATAHEADER 2
:
DATAEHADER n
DATA 1
DATA 2
:
DATA n

SEENファイル中には複数のデータ(Airで99個)が含まれます。 各データはそれぞれ圧縮されています。 圧縮よりも、データを読めなくする意味の方が大きいようです。
SEENファイル全体の構造は左の用になっています。 先頭から順に FILEHEADER、データ個数分の DATAHEADER、同じくデータ個数分の DATA です。
リトルエンディアン(上位バイトと下位バイトが逆)で保存されています。

2.FILEHEADER

FILEHEADER は32バイトです。

オフセット名前サイズ備考
0x00signature0x10シグネチャです。先頭4バイトが PACL、残りは '\0' です。
0x10datanum0x4データの個数です。
0x14unknown0xC使われていないようです。全て0です。

特別なことはないです。

3.DATAHEADER

これは、データ個数分繰り返されます。1つにつきサイズは32バイトです。

オフセット名前サイズ備考
0x00name0x10データの名前です。SEEN000.TXT のようになっています。
0x10offset0x4対応するデータのファイル先頭からのオフセットです。
0x14compsize0x4対応するデータのファイル中でのサイズです。
0x18orgsize0x4対応するデータを展開した時のサイズです。
0x1Cdatatype?0x4分かりません。1です。

これも、特別なことはないです。データは圧縮されて保存されているので、圧縮前と後のサイズが記録されています。

3.DATA

ファイルの残りの部分は DATA です。DATA はそれぞれ DATAHEAD と DATABODY に分かれます。

3(1).DATAHEAD

各 DATA の先頭に存在します。長さは16バイトです。 DATAHEADER と紛らわしいですか? まあ、私が適当に付けた名前なんで……。

オフセット名前サイズ備考
0x00signature0x84バイトが PACL 残りが0です。
0x08orgsize0x4データの展開した時のサイズです。
0x0Ccompsize0x4データのファイル中でのサイズです。

signature がある以上、他の形式も考慮されているのかもしれません。 私は、PACL 以外は見たことがありませんが。 orgsize と compsize は DATAHEADER と一緒です。 順番が逆になっていることだけ気を付けて下さい。

3(2).DATABODY

DATA の残りの部分です。問題はここです。ちょっと分かりにくいので例を出して説明したいと思います。
FC 54 50 43 33 32 00 0F  00 0F 00 85 01 1F 01 0F
Airの1番最初の DATABODY の先頭16バイトです。 これを実際に解凍してみます。

まず、FC です。 2進数で書けば 1111 1100(2) です。
それぞれのビットが、立っている場合は1バイト、立っていなければ2バイトの以降のバイトに対応します。
例えば、FC (1111 1100) の最上位ビットは 54 に、最下位ビットは2度目の 0F FF に対応します。
FC 54 50 43 33 32 00 0F  00 0F 00 85 01 1F 01 0F

ビットが立っている場合、対応するバイトをそのまま出力します。6ビット目までを処理すれば以下の用になります。
54 50 43 33 32 00

ビットが立っていない場合、対応する2バイトを入れ換え(リトルエンディアンなので)12ビットと4ビットに分けます。 0F 00 の場合は 00 0F になり、000 と F に分かれます。 これをそれぞれ、d と l とすると、 今までに出力した最後のバイトの位置を0として d バイト前から l + 2 バイトを出力する意味になります。
この場合、d = 0l = F なので 00 から F + 2 = 17(10) このバイトを出力します。
残っている2つの寝ているビット(どちらも 0F 00 を指す)を処理すると、下の様になります。
54 50 43 33 32 00 00 00  00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00

となります。くどいですが、00 を17バイトではなく、00 から17バイトです。 出力したばかりのバイトも繰り返しの対象になります。

次の 85 (1000 0101) も初めの FC と同じように処理します。
最初のビットは立っているので対応する 01 をそのまま出力。 次のビットは寝ていて対応するビットは 1F 01 なので、011 = 17(10) バイト前から F + 2 = 17(10) バイト出力……、と繰り返します。
出力したバイト数がヘッダの orgsize になれば終了です。


展開したデータはシナリオをエンコードしただけだろうから、解析すればシナリオの改変もできるかも。
誰かの役に(立つわけないけど)立てば、嬉しいです。
間違い等ありましたら、教えて下さい。
一応、プログラム書いてみました。 上の処理を行うだけです。使い方は同梱の readme.txt を見て下さい。

Download (30.9KB)


(2002/08/31)
hiko_bae@yahoo.co.jp
hikobae
1