Mercurial > touhou-doc
annotate 06/t6rp.xhtml @ 13:2925b0e246c6 default tip
Fix a lot of things, and add a TODO.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 17 Feb 2012 12:54:08 +0100 (2012-02-17) |
parents | 9f0e37b7eeab |
children |
rev | line source |
---|---|
8 | 1 <?xml version="1.0" encoding="utf-8"?> |
2 <?xml-stylesheet type="text/css" href="../style.css"?> | |
3 <!DOCTYPE html> | |
4 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> | |
5 <head> | |
6 <title>T6RP format</title> | |
7 </head> | |
8 <body> | |
9 <h1>T6RP format</h1> | |
10 <p>The T6RP format is the replay format used by EoSD.</p> | |
11 | |
13
2925b0e246c6
Fix a lot of things, and add a TODO.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
11
diff
changeset
|
12 <p>It is composed of a header and an “encrypted” data section, which is itself composed of a header, per-stage structures and lists of keystates.</p> |
8 | 13 |
14 | |
15 <h2>Header</h2> | |
16 <pre> | |
17 typedef struct { | |
18 char magic[4]; // T6RP | |
13
2925b0e246c6
Fix a lot of things, and add a TODO.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
11
diff
changeset
|
19 uint16_t version; // 0x0102 for 1.02h |
8 | 20 uint8_t player; // 0 = ReimuA, 1 = ReimuB, 2 = MarisaA, 3 = MarisaB |
21 uint8_t rank; // 0 = Easy, 3 = Lunatic, 4 = Extra | |
22 uint32_t checksum; // (0x3f000318 + key + sum(c for c in decrypted_data)) % (2 ** 32) | |
11
9f0e37b7eeab
Some fixes in the replay format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8
diff
changeset
|
23 uint16_t unknown2; //TODO: seems to be ignored by the game. |
8 | 24 uint8_t key; |
25 char crypted_data[]; // crypted(a, i) = (a + key + 7*i) % 256 | |
26 // decrypted(c, i) = (c - key - 7*i) % 256 | |
27 } thrpy6_header_t; | |
28 </pre> | |
29 | |
11
9f0e37b7eeab
Some fixes in the replay format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8
diff
changeset
|
30 <h2>Decrypting the data section</h2> |
8 | 31 <p>As stated earlier, the data section is encrypted. Luckily, this encryption is quite simplistic, and encrypting/decrypting it is easy (see this snippet of python3 code):</p> |
32 <pre> | |
33 def decrypt(key, data): | |
34 return bytes((c - key - 7 * i) % 256 for i, c in enumerate(data)) | |
35 | |
36 def encrypt(key, data): | |
37 return bytes((c + key + 7 * i) % 256 for i, c in enumerate(data)) | |
38 </pre> | |
39 | |
40 <h2>Encrypted header</h2> | |
41 <pre> | |
42 typedef struct { | |
11
9f0e37b7eeab
Some fixes in the replay format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8
diff
changeset
|
43 uint8_t unknown; //TODO: seems to be ignored by the game. Padding? |
8 | 44 char date[9]; // null-terminated string |
45 char name[9]; // null-terminated string | |
11
9f0e37b7eeab
Some fixes in the replay format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8
diff
changeset
|
46 uint16_t unknown2; //TODO: seems to be ignored by the game. Padding? |
9f0e37b7eeab
Some fixes in the replay format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8
diff
changeset
|
47 uint32_t score; //TODO: Total score. seems to be ignored by the game. |
9f0e37b7eeab
Some fixes in the replay format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8
diff
changeset
|
48 uint32_t unknown3; //TODO: seems to be ignored by the game. |
8 | 49 float slowdown_rate; // As a percentage, not a proper rate |
11
9f0e37b7eeab
Some fixes in the replay format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8
diff
changeset
|
50 uint32_t unknown4; //TODO: seems to be ignored by the game. |
8 | 51 uint32_t stage1_offset; // Offset of a thrpy6_stage_t from the start of the file (including the unencrypted header) |
52 uint32_t stage2_offset; | |
53 uint32_t stage3_offset; | |
54 uint32_t stage4_offset; | |
55 uint32_t stage5_offset; | |
56 uint32_t stage6_offset; | |
57 uint32_t stage7_offset; | |
58 } thrpy6_encrypted_header; | |
59 </pre> | |
60 | |
61 <h2>Stage entry</h2> | |
62 <pre> | |
63 typedef struct { | |
64 uint32_t score; | |
65 uint16_t random_seed; | |
11
9f0e37b7eeab
Some fixes in the replay format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8
diff
changeset
|
66 uint16_t unknown1; //TODO: seems to be ignored by the game. |
8 | 67 uint8_t power; |
68 int8_t lives; | |
69 int8_t bombs; | |
70 uint8_t difficulty; //TODO: WARNING: This has a huge effect on the game! | |
13
2925b0e246c6
Fix a lot of things, and add a TODO.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
11
diff
changeset
|
71 // It is also called rank (but we use the term “difficulty” because “rank” is the official name for Easy/Normal/Hard/Lunatic/Extra) |
8 | 72 // See: http://en.touhouwiki.net/wiki/Embodiment_of_Scarlet_Devil/Gameplay#Rank |
13
2925b0e246c6
Fix a lot of things, and add a TODO.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
11
diff
changeset
|
73 uint32_t unknown3; //TODO: seems to be ignored by the game. Padding? |
8 | 74 thrpy6_keystate_t keystates[]; |
75 } thrpy6_stage_t; | |
76 </pre> | |
77 | |
78 <h2>Keystates</h2> | |
79 <pre> | |
80 struct { | |
11
9f0e37b7eeab
Some fixes in the replay format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8
diff
changeset
|
81 uint32_t time; // Time of the event, most probably exprimed in frames. |
9f0e37b7eeab
Some fixes in the replay format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8
diff
changeset
|
82 uint16_t keys; // 1 = shoot, 2 = bomb, 4 = focus, 8 = ?, 16 = up, 32 = down, 64 = left, 128 = right, 256 = skip dialogs |
9f0e37b7eeab
Some fixes in the replay format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8
diff
changeset
|
83 uint16_t unknown; //TODO: seems to be ignored by the game. |
8 | 84 } thrpy6_keystate_t; |
85 </pre> | |
86 </body> | |
87 </html> |