他人の空似自作物置場

th06_pe.zip/th06dat.txt



・東方紅魔郷用datファイルフォーマット


= はじめに =

== 目的 ==
本文章は
 * 東方紅魔郷のツールを作成しより東方紅魔郷を楽しめるようにしたい
 * 自分がより東方紅魔郷を楽しむために動作を変更して使用したい
そういった目的の人たちを支援する目的の文章です。
決して作成元であるサークル「上海アリス幻樂団様」および作成者であるZUN氏に害を与えたり貶める目的の文章ではありません。
もし、これらの害が及んだ、もしくは及ぶ可能性があるとされた場合は即座に公開を中止いたしますので、テキスト末尾の連絡先よりご一報をお願いします。

== 東方紅魔郷用datファイルフォーマットとは ==
上海アリス幻樂団様作成の弾幕シューティングゲーム「東方紅魔郷」において用いられている
 * 紅魔郷MD.DAT
 * 紅魔郷CM.DAT
 * 紅魔郷ED.DAT
 * 紅魔郷ST.DAT
 * 紅魔郷TL.DAT
 * 紅魔郷IN.DAT
 * ST.dat
ファイルから入出力を行うために必要な各種情報である。

== 用語 ==
 * datファイル
   * 東方紅魔郷用datファイル
 * 長さ付き数値データ
   * ヘッダ情報/格納ファイル個数の項で説明している

== 参照 ==
本文章を作成するに当たって必要な情報の全ては
datファイルをリバースエンジニアリングすることで入手しており
作成元である上海アリス幻樂団様より情報提供は受けていない。



= 手順 =
実際に使用するに当たり、具体的にどのように行えばよいのか
アーカイブ展開とアーカイブ作成の二種に分けて例を挙げる。

なお、この項では詳細は述べないので、必要に応じてファイルフォーマット詳細を参照のこと

== アーカイブ展開 ==
 * datファイルを読み込みオープンする
 * ヘッダ情報の読み込み
   * ヘッダ情報の識別子をチェックし、datファイルであることを確認する
   * ヘッダ情報より格納ファイル数を取得する
   * ヘッダ情報より格納ファイル情報のアドレスを取得する
 * 格納ファイル情報の読み込み
   * 格納ファイル情報が格納されているアドレスまでファイルポインターを移動させる
   * ファイルごとの名称、アドレス、ハッシュ値、サイズを取得する
 * 格納ファイルデータの展開
   * 展開したいファイルのアドレスまでファイルポインターを移動させる
   * ハッシュ値の計算を行い、正しい事を検証する。
   * 名称のファイルを書き込みでオープンする
   * LZSSアルゴリズムに従いデータをデコードしつつファイルに出力する
   * 名称のファイルをクローズする
   * 以降、展開したいデータがなくなるまで繰り返す
 * datファイルをクローズする

== アーカイブ作成 ==
 * datファイルを書き込みオープンする
 * 格納ファイル情報の作成(その1)
   * ファイルの名称、サイズを取得する
   * 以降、格納したいファイルがなくなるまで繰り返す
 * ヘッダ情報の書き込み(その1)
   * 識別子を書き込む
   * 10byte無駄なデータを書き込む
 * 格納ファイルデータの書き込み
   * 該当ファイルの格納ファイル情報のアドレスに、現在のファイルポインターの位置を記録しておく
   * LZSSエンコードを施しつつファイルに出力する
   * 以降、格納したいファイル全て出力するまで繰り返す
 * ヘッダ情報の書き込み(その2)
   * 現在のファイルポインターの位置を格納ファイル情報のアドレスとして保存しておく
   * ヘッダ情報の識別子の直後までファイルポインターを移動する
   * 格納ファイル個数と格納ファイル情報アドレスで10byteの無駄データ部分を上書きする
 * 格納ファイル情報の作成(その2)
   * 格納ファイルデータからハッシュ値を計算し、該当する格納ファイル情報として記録しておく
 * 格納ファイル情報の書き込み
   * ファイル末尾にファイルポインターを移動する
   * 0、0、ハッシュ値、アドレス、サイズ、ファイル名称の順で出力する
   * 以降、格納ファイル全て出力するまで繰り返す
 * datファイルをクローズする

= ファイルフォーマット詳細 =

== 全容 ==
datファイルは以下の三つの要素からなる
 * ヘッダ情報
 * 格納ファイルデータ
 * 格納ファイル情報


== ヘッダ情報 ==
ヘッダ情報は以下の三つの要素からなる
 * 識別子
 * 格納ファイル個数
 * 「格納ファイル情報」アドレス

=== 識別子 ===
識別子は4byteであらわされ、1byte目から順に
0x50 0x42 0x47 0x33
であらわされる。
(※ASCII文字として解釈した場合「PBG3」となる)

=== 格納ファイル個数 ===
「格納ファイルデータ」および「格納ファイル情報」の個数が格納される。
10〜34bitの長さ付き数値データであらわされ、先頭2bitが長さ、残りが実データとなる。
先頭2bitと長さの関係を以下に示す。
11	長さ34bit(実データ32bit)
10	長さ26bit(実データ24bit)
01	長さ18bit(実データ18bit)
00	長さ10bit(実データ8bit)
以下に実際の例を示す
 * 元データ:0x40 0x60 0x00
 * 2進表記:010000000110000000000000
 * 長さ:18bit
 * 実データ:384

=== 「格納ファイル情報」アドレス ===
「格納ファイル情報」のうち先頭が格納されている絶対アドレスが格納される。
10〜34bitの長さ付き数値データであらわされる。



== 格納ファイルデータ ==
「ヘッダ情報/格納ファイル個数」だけ並んでいる。
各々の「格納ファイル個数」の間には単位をbyte単位まで切り上げるため、数bitの空き空間が存在しても良い。
サイズは次の「格納ファイルデータ」もしく「格納ファイル情報」のアドレスまで。
LZSSアルゴリズムを用いた圧縮が行われている。
圧縮の具体的な詳細を下記に示す。

8192byteの辞書データを持つ。
辞書データは初期の時点では全て0x00で埋められているものとする。
以後、一致不一致に関わらず1byte展開されるごとに
展開されたデータで0から埋めていき、8193byte目は再び0から埋めて行く。

「格納ファイルデータ」は0個以上の記号からなる。
記号は1bitの一致フラグを持つ。
一致フラグが1であれば8bitの不一致データを持ち、
一致フラグが0であれば13bitの辞書位置データと、4bitの長さデータを持つ。
辞書位置データが0である時、それはデータの末尾に達したことを表し展開を終了しなければならい。

不一致データを持つ場合は、その8bitをそのまま展開後データとして扱う。
辞書位置と長さを持つ場合、辞書中の辞書位置-1から長さ+3byteを展開後データとして扱う。

以下に例を示す。
例1:
 * 記号:0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
 * 展開内容:0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

例2:
 * 辞書:0x01 0x02 0x03 0x04 以後全て0
 * 記号:0x00 0x08 0x00
 * 展開内容:0x02 0x03 0x04

例3:
 * 辞書:0x00 0x00 0x00 0x00 0x00 0xCC 以後全て0
 * 辞書展開位置:6
 * 記号:0x00 0x18 0x80
 * 展開内容:0xCC 0xCC 0xCC 0xCC 0xCC

例4:
 * 辞書:辞書[0]=0x01 辞書[8190]=0xFF 辞書[8191]=0x00 他全て0
 * 記号:0x7F 0xFC 0x00
 * 展開内容:0xFF 0x00 0x01



== 格納ファイル情報 ==
「ヘッダ情報/格納ファイル個数」だけ並んでいる。
先頭の格納ファイル情報のみ「ヘッダ情報/「格納ファイル情報」アドレス」よりアドレスが取得できる。
先頭以外の格納ファイル情報を直接取得する方法は存在せず、先頭から順に読んでいくしかない。
各々の「格納ファイル情報」の間でには1bitの空きも存在しない。
格納ファイル情報は以下の6つの情報により構成される
 * 不明1
 * 不明2
 * ハッシュ値
 * 「格納ファイルデータ」アドレス
 * 展開後サイズ
 * ファイル名

=== 不明1 ===
用途は不明、実データ0であっても問題なく動作する。
10〜34bitの長さ付き数値データであらわされる。

=== 不明2 ===
用途は不明、実データ0であっても問題なく動作する。
10〜34bitの長さ付き数値データであらわされる。

=== ハッシュ値 ===
ファイルが破損していないかのチェックするために用いる値。
10〜34bitの長さ付き数値データであらわされる。
格納ファイルデータを単なるバイト列とした場合の全バイトの加算値であり
0x01 0x02 0x03 0x04の4byteデータであれば0x0000000Aがハッシュ値となる。

=== 「格納ファイルデータ」アドレス ===
対応する「格納ファイルデータ」のアドレス
10〜34bitの長さ付き数値データであらわされる。
「格納ファイルデータ」のサイズを計算する際にも用いられ、その際は
「格納ファイルデータ」サイズ = (次の「格納ファイルデータ」アドレス) − (「格納ファイルデータ」アドレス)
となる。

=== 展開後サイズ ===
対応する「格納ファイルデータ」を展開後のサイズ。
10〜34bitの長さ付き数値データであらわされる。

=== ファイル名 ===
対応する「格納ファイルデータ」の名称。
終端を0x00とするC言語文字列によって表現されるが
データ境界をbyte単位に切り上げず、bit上で表現する。



= 実装例 =
http://wordpress.click3.org/garakuta/th06_pe.zip



= この文章について =

== 信頼性 ==
本文章のすべてはバイナリエディタなどを用いたリバースエンジニアリングによって得た情報のみを元にしており
実際の仕様とは異なる恐れがあります。
また、その仕様差異など、本文章を原因としていかなる損害を受けたとしても、一切の保障を受ける事は出来ません。
そのことを承知の上でご使用ください。

== ライセンス ==
本文章は下記ライセンスの元に公開される。
・本ライセンスにおいて、全ての条項は「変更の有無を問わず、明示暗示を問わず、商業慈善を問わず、個人法人を問わず、保持使用を問わず、有料無料を問わず」と装飾されている物として扱う。
・著作権者は本ソフトウェアに関する一切の保障義務をもたない。
・上記条項唯一の例外として、本ライセンスに違反した場合を除いて著作権者から本ソフトウェアに関する一切の法的措置を受ける事が無い事のみ保証される。
・著作権者やその他保持者がこのライセンスの範囲で行う活動に支障が無い範囲であれば何を行っても構わない。
・上記条項の”何を行っても構わない”には本ソフトウェアの製作者を偽っての再配布も含まれる。
・全ての権利の行使において、著作権者への連絡、著作権者やライセンス条項の記載、適用ライセンスなどの制限は一切存在しない。
著作権者名:sweetie

== 作成者 ==
ハンドルネーム:sweetie
連絡先:bnryxx332a(あっと)mail.goo.ne.jp
Webページ:http://wordpress.click3.org/