0
|
1 The PBG3 format is an archive format used by Touhou 6 (The Embodiment of Scarlet Devil).
|
|
2
|
|
3 It is a bitstream composed of a header, a file table, and LZSS-compressed files.
|
|
4
|
|
5
|
|
6
|
|
7 Reading integers
|
|
8 ----------------
|
|
9
|
|
10 Integers in PBG3 files are never signed, they are not byte-aligned, and have a variable size.
|
|
11 Their size is given by two bits: 00 means the number is stored in one byte, 10 means it is stored in three bytes.
|
|
12
|
|
13 Ex:
|
|
14 0x0012 is stored as: 0000010010
|
|
15 0x0112 is stored as: 010000000100010010
|
|
16
|
|
17
|
|
18
|
|
19 Reading strings
|
|
20 ---------------
|
|
21
|
|
22 Strings are stored as standard NULL-terminated sequences of bytes.
|
|
23 The only catch is they are not byte-aligned.
|
|
24
|
|
25
|
|
26
|
|
27 Header
|
|
28 ------
|
|
29
|
|
30 The header is composed of three fields:
|
|
31 * magic (string): "PBG3"
|
|
32 * number of entries (integer)
|
|
33 * offset of the file table (integer)
|
|
34
|
|
35 The size of the header is thus comprised between 52 bits and 100 bits.
|
|
36
|
|
37
|
|
38
|
|
39 File table
|
|
40 ----------
|
|
41
|
|
42 The file table starts at a byte boundary, but as the rest of the file, isn't byte-aligned.
|
|
43 It consists of a sequence of entries.
|
|
44 Each entry is composed of five fields:
|
|
45 * unknown1 (int) #TODO
|
|
46 * unknown2 (int) #TODO
|
|
47 * checksum (int): simple checksum of compressed data
|
|
48 * size (int): size of uncompressed data
|
|
49 * name (string): name of the file
|
|
50
|
|
51 The checksum is a mere sum of the compressed data.
|
|
52 Files are compressed using the LZSS algorithm, with a dictionary size of 8192 bytes and a minimum matching length of 4 bytes.
|
|
53 The size of the offset component of (offset, length) tuples is 13 bits, whereas the size of the length component is 4 bits.
|
|
54 A file ends with a (0, 0) tuple, that is, 18 zero bits.
|
|
55
|
|
56 Uncompressing a LZSS-compressed file is quite easy, see lzss.py.
|
|
57
|