Danmakufu .dat Format
Danmakufu 0.12m .dat archive format
The Danmakufu 0.12m file format looks roughly like this. All values
are little endian, and there is no padding.
struct thdnh_012m_header {
// Always "PACK_FILE\0"
char magic[10];
// Number of files in the archive.
uint32_t file_count;
// Entries are dynamically sized
thdnh_012m_entry entries[file_count];
}
struct thdnh_012m_entry {
// Length of the file name
uint32_t name_length;
// File name, encoded as a zero terminated string.
char name[name_length];
// Offset of the file data in the archive
uint32_t file_offset;
// Length of the full file data
uint32_t file_length;
}
The file data is handled somewhat specially. If the file data begins
with "COMPRESS_ZIP\0"
, it is parsed as the following
structure. Otherwise, the whole file is treated as uncompressed
data.
struct thdnh_012m_compressed {
// Always "COMPRESS_ZIP\0"
char magic[13];
// Size of the uncompressed data.
uint32_t uncompressed_size;
// The file data, compressed with zlib. Fills the rest of the file data.
char data[];
}
Danmakufu ph3 .dat archive format
Danmakufu ph3 adds support for directories. Same as with 0.12m, all
values are little endian and there is no padding.
struct thdnh_ph3_header {
// Always "ArchiveFile"
char magic[11];
// Number of files in the archive.
uint32_t file_count;
// true if the file list is compressed, false otherwise.
bool is_compressed;
// Compressed size of the file list. Ignored if is_compressed is false.
uint32_t file_list_size;
// If is_compressed is true, a zlib compressed list of thdnh_ph3_file_entrys.
// If is_compressed is false, an uncompressed thdnh_ph3_file_entrys.
char file_list[];
}
struct thdnh_ph3_file_entry {
// The size of the file entry, *not* including this field.
uint32_t entry_size;
// The length of the directory name in characters.
uint32_t dir_name_length;
// The directory name in UTF-16. Not zero terminated.
wchar_t dir_name[dir_name_length];
// The length of the file name in characters.
uint32_t file_name_length;
// The file name in UTF-16. Not zero terminated.
wchar_t file_name[file_name_length];
// Whether the file data is zlib compressed.
uint32_t is_compressed;
// The uncompressed length of the file.
uint32_t uncompressed_len;
// The compressed length of the file. Ignored if is_compressed is false.
uint32_t compressed_len;
// Offset of the file data in the archive
uint32_t offset;
}
The file data is a plain zlib stream if is_compressed
is
true, and a plain uncompressed stream if it is false.