-
Notifications
You must be signed in to change notification settings - Fork 0
/
tswRev.rb
192 lines (181 loc) · 22.5 KB
/
tswRev.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# encoding: binary
# asm codes: tswRev.asm
# Other fixes:
# - Solve 49F sorcerer show-up animation bug: addressed in tswMod.asm [tswMod #0 (12)]
# - Allow data loading during events: addressed in tswSL.asm [tswSL (13)]
# - Properly process consecutive sound effects: addressed in tswBGM.asm [tswBGM_1 (14)]
# - Do not change BGM and WAV settings when loading data: addressed in tswBGM.asm [tswBGM_2 (15)]
$check = true # whether to inspect whether the current TSW executable bytes match with the original or patched bytes
$dryrun = false # whether to perform a dry run: when false, do the actual patch; when false, only show checking results
# customize the parameters below to best fit your gaming experience
$sleep = [ 10, 14, 28, 42] # sleep durations between each time the player (or monster) moves 1/4 of one tile distance in Superhigh/High/Middle/Low speed modes
# note: unless otherwise noted, all time units are milliseconds, all values should be no less than 10 nor greater than 255
$interval0 = [125, 125, 200, 275] # original Timer3 intervals (for OrbOfFlight when holding down left mouse button) in Superhigh/High/Middle/Low speed modes
$interval1 = [120, 135, 150, 225] # initial waiting time when you first press an arrow key (keyboard repeat delay) in Superhigh/High/Middle/Low speed modes
$interval2 = [ 50, 70, 150, 225] # interval for consecutive unidirectional movement when you hold down an arrow key (keyboard repeat rate) in Superhigh/High/Middle/Low speed modes
# note: for $interval0 and $interval2 elements, their value should not be less than 50 nor greater than 305
$pause = [ 2, 2, 0, 0] # to avoid misoperation, before opening a door or battling with a monster, pause this number of cycles of intervals when holding an arrow key, in Superhigh/High/Middle/Low speed mode. A larger number can better avoid misoperation but increase the feeling of lag; 0 means no pause
$font = ["Verdana", "ホ「ネ樰ナコレ"] # default popup message box font for English/Chinese version (the latter one, 'Microsoft YaHei', should be encoded in GBK), whose length should not exceed 15
class Rev
@@address = [[0x41c1f, 0x425ef, 0x42613, 0x7f464], # Rev0
[0x41bfe, 0x7f47f, 0x7f534, 0x7f548, 0x7f558, 0x7f568, 0x7f5a5, 0x7d387, 0x7d7fa, 0x839dc, 0x83c96, 0x83e64, 0x846f8, 0x7f5ab], # Rev1
[0x42b23], # Rev2
[0x24114, 0x172c0, 0x894a6], # Rev3
[0x4c0d6, 0x4c114, 0x803e6, 0x807b2], # Rev4
[0x52c26, 0x52c96, 0x53029, 0x53167], # Rev5
[0x42e78, 0x42eee, 0x5433b, 0x54492, 0x544d5, 0x547b4], # Rev6
[0x53a2a, 0x660d0], # Rev7
[0x54e0b, 0x73723, 0x740be], # Rev8
[0x7ff54], # Rev9
[0x60be2, 0x60c6f, 0x60d78, 0x60e24, 0x60ed0, 0x4bc18, 0x61763, 0x617b6, 0x6179e], # Rev10
[0x84ffa], # Rev11
[0x637dd], # tswMod #0 (12)
[0x5084d], # tswSL (13)
[0x312cb], # tswBGM_1 (14)
[0x7ebad, 0x7ec3a, 0x55aab], # tswBGM_2 (15)
]
@@oldbyte = [["\x7C\xF4\x47\x00\x09speedhigh", "\x64", "\x74\xF4",
"\xE8\x13\x00\x00\x00\xC3\x8B\xC0\xE8\x6F\x00\x00\x00\xC3\x8B\xC0\xE8\xCB\x00\x00\x00"], # Rev0
["\x44\xF5\x47\x00\x08speedlow",
"\xBA\x96\x00\x00\x00\x8B\x83\xB4\x01\x00\x00\xE8\xD5\xCF\xFA\xFF\xBA\x96\x00\x00\x00\x8B\x83\xEC\x02\x00\x00\xE8\xC5\xCF\xFA\xFF\xBA\x96\x00\x00\x00\x8B\x83\x0C\x03\x00\x00\xE8\xB5\xCF\xFA\xFF\xB2\x01\x8B\x83\xA8\x03\x00\x00\xE8\x34\x0E\xF9\xFF\x33\xD2\x8B\x83\xAC\x03\x00\x00\xE8\x27\x0E\xF9\xFF\x33\xD2\x8B\x83\xB0\x03\x00\x00\xE8\x1A\x0E\xF9\xFF\xC6\x05\x9F\x9B\x48\x00\x01\x5B\xC3\x90\x53\x8B\xD8\xBA\xFA\x00\x00\x00\x8B\x83\xB4\x01\x00\x00\xE8\x71\xCF\xFA\xFF\xBA\xFA\x00\x00\x00\x8B\x83\xEC\x02\x00\x00\xE8\x61\xCF\xFA\xFF\xBA\xFA\x00\x00\x00\x8B\x83\x0C\x03\x00\x00\xE8", "\x00\xE8\xB6\x0D\xF9\xFF\xC6\x05\x9F\x9B\x48\x00\x02",
"\x5E\1", "\x5E\1", "\x5E\1", "\x5B\xC3",
"\xC6\x05\x9F\x9B\x48\x00\x02\x8B\x83\xA8\x03\x00\x00\x80\x78\x28\x01\x75\x07\xC6\x05\x9F\x9B\x48\x00\x01\x8B\x83\xB0\x03\x00\x00\x80\x78\x28\x01\x75\x07\xC6\x05\x9F\x9B\x48\x00\x03",
"\x33\xD2\x8B\x83\xA8\x03\x00\x00\xE8\xE9\x2A\xF9\xFF\x33\xD2\x8B\x83\xAC\x03\x00\x00\xE8\xDC\x2A\xF9\xFF\x33\xD2\x8B\x83\xB0\x03\x00\x00\xE8\xCF\x2A\xF9\xFF\x8A\x46\x03\xFE\xC8\x74\x0A\xFE\xC8\x74\x15\xFE\xC8\x74\x20\xEB\x2B\xB2\x01\x8B\x83\xA8\x03\x00\x00\xE8\xB1\x2A\xF9\xFF\xEB\x1C\xB2\x01\x8B\x83\xAC\x03\x00\x00\xE8\xA2\x2A\xF9\xFF\xEB\x0D\xB2\x01\x8B\x83\xB0\x03\x00\x00\xE8\x93\x2A\xF9\xFF",
"\x84\x8A\xFA\xFF", "\xCA\x87\xFA\xFF", "\xFC\x85\xFA\xFF", "\x8B\x83\x80\x04\x00\x00\xE8\xFD\xED\xF8\xFF\xB2\x01\x8B\x83\x84\x04\x00\x00\xE8\xF0\xED\xF8\xFF\xA1\x10\xC5\x48\x00\xC6\x80\x18\x01\x00\x00\x01\x33\xD2\x8B\x83\xEC\x02\x00\x00\xE8\x2B\x7D\xFA\xFF",
"\x8B\x83\xAC\x03\x00\x00\x80\x78\x28\x01\x75\x07\x8B\xC3\xE8\x22\xFF\xFF\xFF\x8B\x83\xA8\x03\x00\x00\x80\x78\x28\x01\x75\x07\x8B\xC3\xE8\xAB\xFE\xFF\xFF\x8B\x83\xB0\x03\x00\x00\x80\x78\x28\x01\x75\x07\x8B\xC3\xE8\x60\xFF\xFF\xFF\x5B\xC3"], # Rev1
["\x8B\x45\xFC\x8B\x80\x20\x04\x00\x00"], # Rev2
["\x8D\x95\xFF\xFE\xFF\xFF",
"\x0FMS Pゴシック", "\x0FMS Pゴシック"], # Rev3 ('MS PGothic')
["\x8B\x83\xA8\x03\x00\x00\x80\x78\x28\x01\x75\x0A\x85\xF6", "\x89\x3D\x5C\xC5\x48\x00\x8B\x83\x54\x02\x00\x00\x8B\x40\x2C\x85\xC0\x79\x03\x83\xC0\x03\xC1\xF8\x02\x3B\xF0\x75\x0D\xA1\x5C\xC5\x48\x00\xC1\xE0\x02\xA3\x5C\xC5\x48\x00\x8B\x83\x54\x02\x00\x00\x8B\x40\x2C\xD1\xF8\x79\x03\x83\xD0\x00\x3B\xF0\x75\x0C\xA1\x5C\xC5\x48\x00\x03\xC0\xA3\x5C\xC5\x48\x00",
"\x85\xED\x0F\x8E\xCE\x03\x00\x00\xC7\x04\x24\x01\x00\x00\x00", "\xFF\x04\x24\x4D\x0F\x85\x39\xFC\xFF\xFF\x8B\x83\x54\x02\x00\x00\x8B\x40\x2C"], # Rev4
["\xBE\x1B", "\x4E\x1B",
"\x6A\x00\xA1\xAC\xC5\x48\x00\x8D\x04\x40\x0F\xBF\x04\x45\x50\xC7\x48\x00\x48\x50\xA1\x24\xC5\x48\x00\xE8\x91\xAA\xFC\xFF\x8B\xD0\x33\xC9\x8B\x83\xB0\x01\x00\x00\xE8\xEE\x4D\xFC\xFF\xA1\xAC\xC5\x48\x00\x8D\x04\x40\x0F\xBF\x04\x45\x48\xC7\x48\x00\xA3\xA8\xC5\x48\x00\x8B\xC3\xE8\x9E\x1B\x00\x00\x6A\x00\xA1\xAC\xC5\x48\x00\x8D\x04\x40\x0F\xBF\x04\x45\x48\xC7\x48\x00\x48\x03\x05\x54\xC5\x48\x00\x50\xA1\x1C\xC5\x48\x00\xE8\x42\xAA\xFC\xFF\x8B\xD0\x33\xC9\x8B\x83\xB0\x01\x00\x00\xE8\x9F\x4D\xFC\xFF\xA1\xAC\xC5\x48\x00\x8D\x04\x40\x0F\xBF\x04\x45\x4A\xC7\x48\x00\xA3\xA8\xC5\x48\x00\x8B\xC3\xE8\x4F\x1B\x00\x00\x6A\x00\xA1\xAC\xC5\x48\x00\x8D\x04\x40\x0F\xBF\x04\x45\x4A\xC7\x48\x00\x48\x03\x05\x54\xC5\x48\x00\x50\xA1\x20\xC5\x48\x00\xE8\xF3\xA9\xFC\xFF\x8B\xD0\x33\xC9\x8B\x83\xB0\x01\x00\x00\xE8\x50\x4D\xFC\xFF\x8B\xC3\xE8\xA1\x12\xFF\xFF\xA1\xAC\xC5\x48\x00\x8D\x04\x40\x0F\xBF\x0C\x45\x4E\xC7\x48\x00\x8B\xC1\xBE\x0B\x00\x00\x00\x99\xF7\xFE\x8B\x83\x54\x02\x00\x00\x0F\xAF\x50\x2C\x89\x15\x4C\xC5\x48\x00\xA1\xAC\xC5\x48\x00\x8D", "\x14"], # Rev5
["\x14", "\x66\xC7\x04\x46\x00\x00\x66\xC7\x44\x46\x02\x00\x00\x66\xC7\x44\x46\x04\x00\x00\xFF\x03\x8B\x03\x8D\x04\x40\x66\xC7\x04\x46\x01\x00\x66\xC7\x44\x46\x02\x09\x00\x66\xC7\x44\x46\x04",
"\x0F\xBF\x04\x4D\x50\xC7\x48\x00\xA3\x70\xC5\x48\x00\xA1\x70\xC5\x48\x00\x0F\xB6\xB8\x1F\x9B\x48\x00\x8B\xC7\x8B\x93\x54\x02\x00\x00\x8B\x72\x2C\xF7\xEE\x6B\xD6\x0B\x8B\xF2\x99\xF7\xFE\x89\x15\x4C\xC5\x48\x00\xA1\x70\xC5\x48\x00\x8B\xC7\x8B\x93\x54\x02\x00\x00\x8B\x72\x30\xF7\xEE\x6B\xD6\x0B\x8B\xFA\x99\xF7\xFF\xF7\xEE\xA3\x50\xC5\x48\x00\x66\x8B\x04\x4D\x4E\xC7\x48\x00\x66\x83\xE8\x01\x72\x0B\x0F\x84\x35\x01\x00\x00\xE9\x3F\x04\x00\x00\x83\x3D\xEC\x87", "\1", "\x0F\x03\x00\x00", "\x83\x3D\x70\xC5\x48\x00\x79"], # Rev6
["\x8B\xC3\xE8\xAF\x36\x02\x00\xE9\xB2\x0D\x00\x00", "\x53\x56\x57\x51\x89\x04\x24\xB8\xAC\xC5\x48\x00\xBA\x4C\xC7\x48\x00\xBE\x58\xC5\x48\x00\x8B\x08\x8D\x0C\x49\x0F\xBF\x5C\x4A\x02\x89\x1E\x0F\xBF\x5C\x4A\x04\x89\x1D\x5C\xC5\x48\x00\x66\xC7\x04\x4A\x00\x00\x66\xC7\x44\x4A\x02\x00\x00\x66\xC7\x44\x4A\x04\x10\x00\xFF\x00\x8B\x08\x8D\x0C\x49\x66\xC7\x04\x4A\x0D\x00\x8B\x18\x8D\x1C\x5B\x66\x8B\x0E\x66\x89\x4C\x5A\x02\x8B\x38\x8D\x3C\x7F\x66\x8B\x1D\x5C\xC5\x48\x00\x66\x89\x5C\x7A\x04\xFF\x00\x8B\x38\x8D\x3C\x7F"], # Rev7
["\x33\xD2\x8B\x83\xCC\x01\x00\x00\xE8\xE8\xE6\xFB\xFF\x33\xD2\x8B\x83\xD0\x01\x00\x00\xE8\xDB\xE6\xFB\xFF\x33\xD2\x8B\x83\xD4\x01\x00\x00", "\x66\xC7\x04\x46\x00\x00\x8B\x03\x8D\x04\x40\x66\xC7\x44\x46\x02\x00\x00\x8B\x03\x8D\x04\x40\x66\xC7\x44\x46",
"\x66\xC7"], # Rev8
["\xFF\x57\x0C\xFF\x75\xF4\x68\x7C\x02\x48\x00\x8D\x55\xF0\xA1\xB8\xC5\x48\x00\x03\xC0\x8B\x04\xC5\x1C\x99\x48\x00\xE8\xF7\x5B\xF8\xFF\xFF\x75\xF0\x8D\x4D\xEC\x8B\x45\xFC\x8B\x80\x4C\x04\x00\x00\x8B\x80\x00\x01\x00\x00"], # Rev9
["\x83\x3D\xAC\xC5\x48\x00\x00\x7D\x07\x33\xC0\xA3\xAC\xC5\x48\x00\x8B\x83\x28\x03\x00\x00\x80\x78\x29\x01\x0F\x85\xA1\x04\x00\x00\x83\x3D\xAC\xC5\x48\x00\x00\x0F\x85\x94\x04\x00\x00", "\xC7\x05\x90\xC5\x48\x00\x01\x00\x00\x00\x6B\x05\xA4\x86\x4B\x00\x0B\x03\x05\xA0\x86\x4B\x00\xA3\x80\xC5\x48\x00\xC7\x05\xE8\x87\x4B\x00\x04\x00\x00\x00\xA1\x80\xC5\x48\x00\x83\xE8\x0B\xA3\x84", "\xC7\x05\x90\xC5\x48\x00\x02\x00\x00\x00\x6B\x05\xA4\x86\x4B\x00\x0B\x03\x05\xA0\x86\x4B\x00\xA3\x80\xC5\x48\x00\xC7\x05\xE8\x87\x4B\x00\x02\x00\x00\x00\xA1\x80\xC5\x48\x00\x48\xA3\x84\xC5\x48\x00\x83\x3D\xA0\x86\x4B\x00\x00\x0F\x84\xED\x02\x00\x00\x8B\xC3\xE8\xD3\x36\xFE\xFF\xE9\xE1\x02\x00\x00", "\xC7\x05\x90\xC5\x48", "\xC7\x05\x90\xC5\x48",
"\x38\x08\xFE\xFF",
"\x66\xA1\xC6\xC5\x48\x00\x66\x83\xE8\x01\x72\x07\x74\x14\xE9\x82\x01\x00\x00\x33\xD2", "\xA1\xA4\x86\x4B\x00\x6B\xD0\x0B\x03\x15\xA0\x86\x4B\x00\x89\x15\x80\xC5\x48\x00\x8B\x15\x80\xC5\x48\x00\x83\xEA\x0B\x89\x15\x84\xC5\x48\x00\x85\xC0\x0F\x84\x17\x01\x00\x00\x8B\xC3\xE8\xA8\x2C\xFE\xFF\xE9\x0B\x01\x00\x00\x6B\x15\xA4\x86\x4B\x00\x0B\xA1\xA0\x86\x4B\x00\x03\xD0\x89\x15\x80\xC5\x48\x00\x8B\x15\x80\xC5\x48\x00\x4A\x89\x15\x84\xC5\x48\x00\x85\xC0\x0F\x84\xE2\x00\x00\x00\x8B\xC3\xE8\x73\x2C\xFE\xFF\xE9\xD6\x00\x00\x00\x6B\x15\xA4\x86\x4B\x00\x0B\xA1\xA0\x86\x4B\x00\x03\xD0\x89\x15\x80\xC5\x48\x00\x8B\x15\x80\xC5\x48\x00\x42\x89\x15\x84\xC5\x48\x00\x83\xF8\x0A\x0F\x84\xAC\x00\x00\x00\x8B\xC3\xE8\x3D\x2C\xFE\xFF\xE9\xA0\x00\x00\x00\xA1\xA4\x86\x4B\x00\x6B\xD0\x0B\x03\x15\xA0\x86\x4B\x00\x89\x15\x80\xC5\x48\x00\x8B\x15\x80\xC5\x48\x00\x83\xC2\x0B\x89\x15\x84\xC5\x48\x00\x83\xF8\x0A\x74\x78\x8B\xC3\xE8\x09", "\xB6\x17\x46\x00\xED\x17\x46\x00\x22\x18\x46\x00\x58\x18\x46\x00"], # Rev10
["\x33\xD2\xA1\x10\xC5\x48\x00\xE8\xB2\xE0\xF8\xFF\xA0\xA4\x9B\x48\x00\x2C\x01\x72\x07\x74\x74\xE9\xD9\x00\x00\x00\xA1\xFC\xA6\x48\x00\xE8\x88\xEB\xF9\xFF\x3D\x80\x02\x00\x00\x7F\x32\xBA\xFC\xFF\xFF\xFF\xA1\x10\xC5\x48\x00\xE8\x62\xE0\xF8\xFF\xBA\xA8\x01\x00\x00\xA1\x10\xC5\x48\x00\xE8\xD7\xC4\xF9\xFF\xBA\x88\x02\x00\x00\xA1\x10\xC5\x48\x00\xE8\x84\xE0\xF8\xFF\xE9\x96\x00\x00\x00\x33\xD2\xA1\x10\xC5\x48\x00\xE8\x33\xE0\xF8\xFF\xBA\xA8\x01\x00\x00\xA1\x10\xC5\x48\x00\xE8\xA8\xC4\xF9\xFF\xBA\x88\x02\x00\x00\xA1\x10\xC5\x48\x00\xE8\x55\xE0\xF8\xFF\xEB\x6A\xA1\xFC\xA6\x48\x00\xE8\x19\xEB\xF9\xFF\x3D\x20\x03\x00\x00\x7F\x2F"], # Rev11
["\xFF\3"], # tswMod #0 (12)
["\x33\xD2"], # tswSL (13)
["\x80\xBB\xE2\1\0\0\0\x74\x17\x80\xBB\xE0\1\0\0\0\x74\7\x83\x8B\xDC\1\0\0\2\xC6\x83\xE2\1\0\0\0\x80\xBB\xE4\1\0\0\0\x74\x18\x83\x8B\xDC\1\0\0\4\x8B\x83\xF0\1\0\0\x89\x44\x24\4\xC6\x83\xE4\1\0\0\0"], # tswBGM_1 (14)
["\x6A\0\xBA\x34\x89\x4B\0\xB9\x81\x18\0\0\xB8\0\xC6\x48\0\xE8\x91\x56\xF8\xFF\xE8\x48\x3B\xF8\xFF\x6A\0\xBA\x88\x86\x4B\0\xB9\xAC\2\0\0\xB8\0\xC6\x48\0\xE8\x76\x56\xF8\xFF\xE8\x2D\x3B\xF8\xFF\xB8\0\xC6\x48\0\xE8\xCB\x56\xF8\xFF\xE8\x1E\x3B\xF8\xFF\xC7\5\x8C\xC5\x48\0\x86\0\0\0", "\x6A\0\xBA\x34\x89\x4B\0\xB9\x81\x18\0\0\xB8\0\xC6\x48\0\xE8\4\x56\xF8\xFF\xE8\xBB\x3A\xF8\xFF\x6A\0\xBA\x88\x86\x4B\0\xB9\xAC\2\0\0\xB8\0\xC6\x48\0\xE8\xE9\x55\xF8\xFF\xE8\xA0\x3A\xF8\xFF\xB8\0\xC6\x48\0\xE8\x3E\x56\xF8\xFF\xE8\x91\x3A\xF8\xFF\xC7\5\x8C\xC5\x48\0\x86\0\0\0",
"\x83\xBE\x64\1\0\0\0\x75\x0D\xB2\1\x8B\x83\x2C\3\0\0\xE8\x2F\xA8\xFB\xFF\x83\xBE\x68\1\0\0\0\x74\x14\xB2\1\x8B\x83\x30\3\0\0\xE8\x19\xA8"] # tswBGM_2 (15)
]
@@newbyte = [["\x64\xF4\x47\x00\x09DisTEdit8", "\x7C", "\x44\xF5",
"\x8B\x80\xC8\x01\x00\x00\xEB\x08\xE8\x6F\x00\x00\x00\xC3\x8B\xC0\xE8\xCB\x40\xF9\xFF"], # Rev0
["\xd8\xF4\x47\x00\x08speedsup",
"\x6A\x01\x8B\x04\x24\xA2\x9F\x9B\x48\x00\xB9\x0A\x00\x00\x00\xBA\x7D\x00\x00\x00\x48\x75\x02\xB1\x32\x48\x75\x04\xB1\x64\xB2\xC8\x52\x51\x52\x84\xC0\x0F\x94\xC2\x8B\x83\xAC\x03\x00\x00\xE8\x3E\x0E\xF9\xFF\x5A\x8B\x83\xB4\x01\x00\x00\xE8\xA6\xCF\xFA\xFF\x5A\x8B\x83\xEC\x02\x00\x00\xE8\x9A\xCF\xFA\xFF\x5A\x8B\x83\x0C\x03\x00\x00\xE8\x8E\xCF\xFA\xFF\xEB\x10\x53\x89\xC3\x6A\x00\xEB\xA2\x90\x53\x8B\xD8\x6A\x02\xEB\x9A\x90\x80\x3C\x24\x01\x0F\x94\xC2\x8B\x83\xA8\x03\x00\x00\xE8\xF6\x0D\xF9\xFF\x31\xD2\x8B\x83\xB0\x03\x00\x00\xE8\xE9\x0D\xF9\xFF\x58\x84\xC0\x0F\x94\xC2\xEB\x27",
"\x31\xD2\x8B\x83\x58\x03\x00\x00\xE8\xAF\x0D\xF9\xFF",
"\x13\1", "\x96\0", "\x13\1", "\xEB\x8D",
"\x31\xD2\x8D\x8B\xA8\x03\x00\x00\x8B\x01\x80\x78\x28\x01\x75\x01\x42\x8B\x41\x04\x80\x78\x28\x01\x75\x02\xB2\x02\x8B\x41\x08\x80\x78\x28\x01\x75\x02\xB2\x03\x88\x15\x9F\x9B\x48\x00", "\x8A\x46\x03\x50\x3C\x03\x0F\x94\xC2\x8B\x83\xB0\x03\x00\x00\xE8\xE2\x2A\xF9\xFF\x80\x3C\x24\x02\x0F\x94\xC2\x8B\x83\xAC\x03\x00\x00\xE8\xD0\x2A\xF9\xFF\x80\x3C\x24\x01\x0F\x94\xC2\x8B\x83\xA8\x03\x00\x00\xE8\xBE\x2A\xF9\xFF\x58\x84\xC0\x0F\x94\xC2\x8B\x83\x58\x03\x00\x00\xEB\x18\x90\xB2\x01\x8B\x83\xAC\x03\x00\x00\xE8\xA2\x2A\xF9\xFF\xEB\x0D\xB2\x01\x8B\x83\xB0\x03\x00\x00\xE8\x93\x2A\xF9\xFF",
"\xE0\xBB\xFF\xFF", "\x26\xB9\xFF\xFF", "\x58\xB7\xFF\xFF", "\x8D\xB3\x80\x04\x00\x00\x8B\x06\xBF\x00\x35\x41\x00\xFF\xD7\xB2\x01\x8B\x46\x04\xFF\xD7\xC6\x83\x18\x01\x00\x00\x01\x8D\xB3\xEC\x02\x00\x00\x8B\x06\x31\xD2\xE8\x30\x7D\xFA\xFF\xE8\xAF\xAE\xFF\xFF",
"\x0F\xB6\x0D\x9F\x9B\x48\x00\x83\xF9\x03\x74\x90\x51\xE9\xC4\xFE\xFF\xFF\xC3\x66\x90\x0F\xB6\x0D\x9F\x9B\x48\x00\x85\xC9\x74\xF2\x41\x0F\xAF\xD1\xC1\xEA\x02\xE9\x8D\xCE\xFA\xFF\x90\x8B\x46\x48\x31\xD2\xE8\x96\x0D\xF9\xFF\x8B\xC3\xEB\xC2"], # Rev1
["\x80\x3D\xA1\x9B\x48\x00\x01\xEB\x04"], # Rev2
["\xBA\x74\x8E\x48\x00\x90",
nil, nil], # Rev3 (the second and third one will be processed later)
["\xC1\xEE\x02\xBD\x04\x00\x00\x00\xEB\x29" +
$sleep.pack('C4'), # sleep durations for SpeedMode 0/1/2/3
"\x8B\xC7\xF7\xE6\xA3\x5C\xC5\x48\x00\x68\x5E\xC1\x44\x00\x66\x90\x0F\xB6\x05\x9F\x9B\x48\x00\x8A\x80\xE0\xC0\x44\x00\x50\xA1\xFC\x9B\x48\x00\x85\xC0\x75\x1A\x68\xFC\xB5\x4B\x00\xE8\x6B\x51\xFB\xFF\x68\x58\xC1\x44\x00\x50\xE8\x34\x8A\xFB\xFF\xA3\xFC\x9B\x48\x00\xFF\xD0\xC3Sleep\0",
"\xC1\xED\x02\x89\x2C\x24\x0F\x1F\x40\x00\xE8\x2F\xBD\xFC\xFF", "\x01\x2C\x24\x8B\xC5\xC1\xE0\x02\x39\x04\x24\x0F\x86\x2D\xFC\xFF\xFF\x66\x90"], # Rev4
["\x3C\x05","\xCC\x04",
"\x6B\x05\xAC\xC5\x48\x00\x06\x05\x4C\xC7\x48\x00\x50\x31\xD2\x31\xC9\x8A\x48\xF4\x80\xE9\x04\x80\xF9\x01\x77\x2A\x75\x09\x6B\x0D\xE8\x87\x4B\x00\x08\xB5\x01\x80\xE9\x02\x80\x78\xDC\x09\x74\x09\x88\x15\xD2\xC5\x48\x00\x8B\xCA\x42\x51\x8B\x83\xB4\x01\x00\x00\xE8\xE6\x93\xFD\xFF\x5A\x59\x0F\xBF\x41\x02\x50\x0F\xBF\x41\xFE\x00\xD0\x28\xF0\x50\x50\x0F\xBF\x41\xFC\x50\xA3\xA8\xC5\x48\x00\x0F\xBF\x41\x04\x00\xD0\x00\xF0\x48\xBA\x24\xC5\x48\x00\xE8\x74\x00\x00\x00\xE8\x6F\x1B\x00\x00\x58\x48\x03\x05\x54\xC5\x48\x00\xBA\x1C\xC5\x48\x00\xE8\x5D\x00\x00\x00\x8F\x05\xA8\xC5\x48\x00\xE8\x52\x1B\x00\x00\x58\x48\x03\x05\x54\xC5\x48\x00\xBA\x20\xC5\x48\x00\xE8\x40\x00\x00\x00\xE8\xC7\x12\xFF\xFF\xA1\x18\xC5\x48\x00\xE8\xF9\xA9\xFC\xFF\x8B\xF8\x58\xB1\x0B\xF6\xF1\x88\xE2\x8B\xB3\x54\x02\x00\x00\xF6\x66\x2C\x8B\xC8\x88\xD0\xF6\x66\x2C\x8B\xD0\x8B\xC7\xFF\x35\x1C\xC5\x48\x00\xE8\xB1\x74\xFC\xFF\xA1\x14\xC5\x48\x00\xEB\x5D\x66\x90\x6A\x00\x50\x8B\x02\xE8\xBE\xA9\xFC\xFF\x8B\xD0\x31\xC9\x8B\x83\xB0\x01\x00\x00\xE8\x1B\x4D\xFC\xFF\xC3\x90", "\x18"], # Rev5
["\1", "\x31\xD2\x89\x14\x46\x66\x89\x54\x46\x04\xFF\x03\x83\xC0\x03\x89\x54\x46\x02\x80\x3D\x9F\x9B\x48\x00\x01\x0F\x93\xC2\x66\x89\x14\x46\x0F\x96\xC2\x80\xC2\x09\x88\x54\x46\x02\xEB\x02",
"\x31\xFF\x47\x80\x3D\x9F\x9B\x48\x00\x01\x77\x21\x47\x73\x1E\xD1\xE7\xEB\x1A\x83\x3D\x70\xC5\x48\x00\x79\x0F\x84\x62\x04\x00\x00\x4F\x0F\x84\x86\x04\x00\x00\xFF\x0D\xAC\xC5\x48\x00\x6B\x35\xAC\xC5\x48\x00\x06\x81\xC6\x4E\xC7\x48\x00\x0F\xB7\x46\x02\xA3\x70\xC5\x48\x00\x0F\xB6\x80\x1F\x9B\x48\x00\xB1\x0B\xF6\xF1\x88\xE2\x8B\x8B\x54\x02\x00\x00\xF6\x61\x2C\xA3\x50\xC5\x48\x00\x88\xD0\xF6\x61\x2C\xA3\x4C\xC5\x48\x00\x80\x3E\x00\x74\x1E\xE9\x2C\x01\x00\x00", "\2", "\x82\xFE\xFF\xFF", "\xE9\x95\xFB\xFF\xFF\x66\x90"], # Rev6
["\x68\xE8\x47\x45\x00\xE9\xDC\x26\x01\x00\x66\x90", "\x50\xE8\x4A\xD0\xFD\xFF\x58\xE8\x44\xD0\xFD\xFF\xBA\xAC\xC5\x48\x00\x6B\x02\x06\x05\x4C\xC7\x48\x00\xFF\x0A\x8B\x50\x02\xB9\x10\x00\x00\x00\xC7\x00\x00\x00\x00\x00\x89\x48\x04\xC6\x40\x06\x0D\x89\x50\x08\x83\xC0\x0C\x83\x05\xAC\xC5\x48\x00\x02\xE2\xE4\xC3\xA0\x9F\x9B\x48\x00\xFE\xC8\x3C\x01\x0F\x96\xC2\x00\xD0\xB1\x02\x28\xC1\xBA\xAC\xC5\x48\x00\x6B\x02\x06\x05\x4A\xC7\x48\x00\x84\x08\x74\x08\x83\x2A\x02\x83\xE8\x0C\xEB\xF4\x8B\xC3\xE9\x9E\x0F\x01\x00\x90"], # Rev7
["\x31\xFF\x31\xD2\x8B\x84\xBB\xCC\x01\x00\x00\xE8\xE5\xE6\xFB\xFF\x47\x83\xFF\x03\x75\xEC\xA0\x46\x99\x4B\x00\xA2\x5C\x99\x4B\x00\xEB\x05", "\x8D\x04\x46\x31\xD2\x89\x10\x66\x89\x50\x04\xC6\x05\x46\x99\x4B\x00\x06\xC6\x05\x5C\x99\x4B\x00\x06\xEB\x03",
"\xEB\x48"], # Rev8
["\x89\x45\xEC\xFF\x57\x0C\xFF\x75\xF4\x68\x7C\x02\x48\x00\xA1\xB8\xC5\x48\x00\x01\xC0\x8B\x04\xC5\x1C\x99\x48\x00\x8B\x15\x04\x87\x4B\x00\x42\xF7\xE2\x8D\x55\xF0\xE8\xEB\x5B\xF8\xFF\xFF\x75\xF0\x8D\x4D\xEC\x8B\x01\x90"], # Rev9
["\x31\xC0\x8A\x16\x80\xEA\x25\x80\xFA\x03\x76\x21\x39\x05\xAC\xC5\x48\x00\x0F\x8F\xA9\x04\x00\x00\xA3\xAC\xC5\x48\x00\x8B\x83\x28\x03\x00\x00\x80\x78\x29\x01\x0F\x85\x94\x04\x00\x00", ([0xe9, 0x104] + # jmp 460d78
$interval1 +
$interval2.map {|i| i-50} +
$interval0.map {|i| i-50} + [
0x484bb0, 0x484b5c, 0x484c04, 0x484c58 # TTSW10.BitBtnXClick
]).pack('CLC12L4') +
"\x80\x3D\xC7\xC5\x48\x00\x25\x73\x05\xE8\xB6\xB7\xFC\xFF\xC3", "\x0F\xB6\x0E\x8B\x83\x0C\x03\x00\x00\xBA\xC7\xC5\x48\x00\x38\x0A\x0F\x84\x15\x03\x00\x00\x80\x3A\x00\x88\x0A\xBF\x50\x18\x46\x00\xBA\x0C\x18\x46\x00\x0F\x45\xFA\x8A\x0D\x9F\x9B\x48\x00\x8A\x89\x74\x0C\x46\x00\x89\x48\x24\xB2\x01\xE8\x9E\xB6\xFC\xFF\x0F\xB6\x06\xFF\xD7\xE9\xE3\x02\x00\x00\x66\x90", "\xE9\x4F\xFF\xFF\xFF", "\xE9\xA3\xFE\xFF\xFF",
"\x74\x50\x01\x00",
"\x31\xD2\x31\xC0\xA0\xC7\xC5\x48\x00\x3C\x25\x73\x46\x38\x15\xC6\xC5\x48\x00\x75\x0D",
"\x50\x50\xE8\x0F\x38\xFA\xFF\x31\xD2\x66\x85\xC0\x8B\x83\x0C\x03\x00\x00\xB9\x78\x0C\x46\x00\x78\x0F\x89\x14\x24\x88\x15\xC7\xC5\x48\x00\x88\x50\x20\x8D\x49\x04\x8A\x15\x9F\x9B\x48\x00\x8A\x14\x11\x83\xC2\x32\xE8\x75\xAC\xFC\xFF\x58\x85\xC0\x74\x05\xE8\x13\x00\x00\x00\x5B\xC3\x90" +
($pause + [
0, 4, 0, 4, # direction_offset
0, 0, 10, 10, # direction_bound
-1, -11, 1, 11 # direction_index_difference
]).pack('c16') +
"\xBA\xA0\x86\x4B\x00\x8D\x88\xDB\x17\x46\x00\x02\x11\x8A\x12\x3A\x51\x04\x74\x30\xB2\xA0\x8A\x61\x08\x6B\x4A\x04\x0B\x03\x0A\x00\xE1\xB4\x00\x6B\x52\xF8\x7B\x8A\x8C\x11\x36\x89\x4B\x00\x80\xE9\x04\x80\xF9\x39\x72\x0E\xB9\x34\x89\x4B\x00\x80\x39\x00\x74\x20\xFE\x09\xC3\x90\x83\x3D\xAC\xC5\x48\x00\x00\x7F\x13\x0F\xB6\x0D\x9F\x9B\x48\x00\x8A\x89\xFC\x17\x46\x00\x88\x0D\x34\x89\x4B\x00\x8D\x48\xDB\x8B\x83\x28\x03\x00\x00\x80\x78\x29\x01\x75\xD3\x8B\xC3\xFF\x24\x8D\x80\x0C\x46\x00", ([0x4618f8]*4).pack('L4')], # Rev10
["\x8D\x55\xEC\x8B\xC3\x6A\x00\x52\x6A\x00\x6A\x30\xE8\x65\xC3\xF9\xFF\xBE\x88\x02\x00\x00\xBF\xA8\x01\x00\x00\x80\x3D\xA4\x9B\x48\x00\x00\x74\x08\x66\xBE\x28\x03\x66\xBF\x12\x02\x03\x7B\x30\x2B\x7D\xF8\xE8\xFB\x01\xF8\xFF\x80\x7B\x5C\x00\x74\x12\x8B\x53\x24\xD1\xE2\x03\x53\x2C\x8B\x4B\x28\xD1\xE1\x03\x4B\x30\xEB\x0C\x8B\x55\xEC\x03\x55\xF4\x8B\x4D\xF0\x03\x4D\xF8\x29\xF2\xD1\xFA\x29\xF9\xD1\xF9\x8B\x45\xF4\x29\xF0\x40\x40\x39\xD0\x0F\x4C\xD0\x8B\x45\xF8\x29\xF8\x40\x40\x39\xC8\x0F\x4C\xC8\x8B\x45\xEC\x48\x48\x39\xC2\x0F\x4C\xD0\x8B\x45\xF0\x39\xC1\x0F\x4C\xC8\x56\x57\x8B\xC3\xE8\x1C\x17\xF9\xFF\x80\x4B\x5C\x07\xEB\x59"], # Rev11
["\x90\x90"], # tswMod #0 (12)
["\xEB\x0B"], # tswSL (13)
["\x8B\x43\4\x3B\x98\xD8\2\0\0\x74\x3D\x31\xD2\x89\x54\x24\4\5\x64\4\0\0\x3B\x18\x74\x1F\x3B\x58\xFC\xB2\4\x74\2\xB2\x40\xB8\x3B\xA1\x4B\0\x8A\x08\x39\x15\xAC\xC5\x48\0\x0F\x9F\0\x7F\x0C\x84\xC9\x75\x08\x83\x8B\xDC\1\0\0\4\x90"], # tswBGM_1 (14)
["\x31\xFF\xA1\0\xC6\x48\0\x50\x8D\x4D\xF8\x57\x51\x68\xAC\2\0\0\x68\x88\x86\x4B\0\x50\x57\x51\x68\x81\x18\0\0\x68\x34\x89\x4B\0\x50\xBE\xF0\x87\x4B\0\x87\x3E\xB8\x18\x89\x4B\0\x29\x38\x29\x78\4\xE8\xA8\x26\xF8\xFF\xE8\xA3\x26\xF8\xFF\xE8\x36\x26\xF8\xFF\x89\x3E\xC6\5\x8C\xC5\x48\0\x86\x90", "\x31\xFF\xA1\0\xC6\x48\0\x50\x8D\x4D\xF8\x57\x51\x68\xAC\2\0\0\x68\x88\x86\x4B\0\x50\x57\x51\x68\x81\x18\0\0\x68\x34\x89\x4B\0\x50\xBE\xF0\x87\x4B\0\x87\x3E\xB8\x18\x89\x4B\0\x29\x38\x29\x78\4\xE8\x1B\x26\xF8\xFF\xE8\x16\x26\xF8\xFF\xE8\xA9\x25\xF8\xFF\x89\x3E\xC6\5\x8C\xC5\x48\0\x86\x90",
"\xBF\xA3\x9B\x48\0\x80\x3F\0\x75\x0B\x8B\x83\x6C\4\0\0\xE8\xC8\xB6\xFD\xFF\xBA\xEC\x87\x4B\0\x8A\7\x88\2\x8A\x47\xFF\x84\xC0\x75\x17\x88\x42\4\xEB\x25"] # tswBGM_2 (15)
]
def initialize(filename, chinese=false)
@f = open(filename, 'r+b')
@c = chinese
font = $font[@c ? 1 : 0]
@ft = [font.size, font].pack('Ca15')
puts('
%s:
[State codes: 0=original; 1=patched; -1=unknown]' % filename) if $check
end
def patch(mode, index, i, offset, offset0=-0xC00)
@f.seek(offset+offset0)
oldbyte = @@oldbyte[index][i]
newbyte = @@newbyte[index][i]
newbyte = @ft unless newbyte
if $check
size = oldbyte.size
read = @f.read(size)
@f.seek(-size, 1)
if read == oldbyte
state = 0
elsif read == newbyte
state = 1
else
state = -1
end
puts('%d: %d' % [i, state])
end
@f.write(mode.zero? ? oldbyte : newbyte) unless $dryrun
end
# functions below can revise/restore the designated executable
# and they will return the corresponding file object to be closed after finishing processing
def rev(index) # revise only the index-th item
puts('
Rev: %d' % index) if $check
@@address[index].each_with_index {|x, i| patch(1, index, i, x)}
return @f
end
def res(index) # restore only the index-th item
print('
Res: %d' % index) if $check
@@address[index].each_with_index {|x, i| patch(0, index, i, x)}
return @f
end
def revAll() # revise all items
(0...@@address.size).each {|i| rev(i)}
return @f
end
def resAll() # restore all items
(0...@@address.size).each {|i| res(i)}
return @f
end
end
# Example of revising/restoring only certain items:
#obj = Rev.new('TSW.exe') # pass the executable path here
#obj.rev(0)
#obj.rev(1)
#obj.res(2)
#obj.res(3).close() # at the end, remember to close the file object
# Example of restoring all items:
#Rev.new('TSW.exe').resAll().close()
# to revise all items:
Rev.new('TSW.exe').revAll().close()
Rev.new('TSW.EN.exe').revAll().close()
Rev.new('TSW.CN.exe', true).revAll().close()
Rev.new('TSW.CNJP.exe', true).revAll().close()
system('pause')