79 |
80 | ## 如果您愿意捐助一点小钱
81 |
82 | ### 支付宝:
83 | 
84 |
85 | ### 支付宝扫红包(使用支付宝扫一扫,你我都能得红包):
86 | 
87 |
88 | [AutoHotkey 1.1.30.01+]: https://autohotkey.com/
89 | [Releases]: https://github.com/wz520/thkmc/releases
90 | [喵玉殿论坛上的THKMC发布帖]: http://bbs.nyasama.com/forum.php?mod=viewthread&tid=78904
91 |
--------------------------------------------------------------------------------
/docs/GNUmakefile:
--------------------------------------------------------------------------------
1 | # Make documentation using mingw32-make
2 | #
3 | # Need additional programs: pandoc 2.7.2, gvim
4 |
5 |
6 | SHELL=cmd.exe
7 |
8 | TARGETS=help.html thkmc_sample_ini.html
9 |
10 | RM=del
11 |
12 | all: $(TARGETS)
13 |
14 | help.html: help.md
15 | pandoc -f markdown+multiline_tables+table_captions-implicit_figures -s --toc --toc-depth=4 --email-obfuscation=references -V lang=zh --css=style.css --metadata pagetitle="THKMC Help" -o $@ $<
16 |
17 | thkmc_sample_ini.html: ../thkmc_sample.ini | tohtmlhelper.vim
18 | gvim -S tohtmlhelper.vim $<
19 |
20 | .INTERMEDIATE: tohtmlhelper.vim
21 | tohtmlhelper.vim:
22 | @echo ---- Creating $@ ...
23 | echo set nonumber nofoldenable > $@
24 | echo set fenc=utf-8 bomb >> $@
25 | echo TOhtml >> $@
26 | echo g/^/normal cc^THKMC_SAMPLE^ >> $@
27 | echo sav! thkmc_sample_ini.html >> $@
28 | echo qa! >> $@
29 | @echo ---- END
30 |
31 |
32 | clean:
33 | -$(RM) $(TARGETS)
34 |
35 |
36 | .SUFFIXES:
37 |
38 | .PHONY: clean
39 |
--------------------------------------------------------------------------------
/docs/help.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | THKMC Help
8 |
14 |
15 |
18 |
19 |
20 |
37 | THKMC - 东方STG专用键盘映射修改工具
38 | 当前版本: 1.40
39 | 功能
40 | 众所周知,ZUN 制作的 东方STG 从来就不自带更改键盘键位的功能。为此,各路大神都写过各种键盘映射工具,但大多是外挂式的。随着新版本的 Windows 对系统安全性的要求越来越高,这些外挂式的改键工具都可能存在兼容性问题。
41 | THKMC(TouHou Keyboard Mapping Changer) 通过修改东方STG游戏主程序文件中与键盘映射相关的代码,实现自定义游戏键位。
42 | 东方STG获取键盘按键状态的方法有两种:使用 DirectInput
和 不使用 DirectInput
。 其中 使用 DirectInput
是通过调用 IDirectInputDevice8::GetDeviceState() 来获取键盘状态的;而 不使用 DirectInput
则是使用 Win32 API 中的 GetKeyboardState()。
43 | 本程序 只支持 对使用 DirectInput 方式获取的按键映射进行更改。所以要求在游戏自带的 custom.exe 程序中不能勾选 “不使用 DirectInput 获取键盘输入”。若勾选的话使用本程序改键将没有任何效果。(不过一般不会有人去勾选吧,因为游戏默认的不勾选也能工作得很好。)
44 | 特点
45 | 相比较其他常见的外挂式通用键位修改工具,因为 THKMC 是为特定的EXE文件量身定制的,所以只要游戏版本正确且用户写的配置文件内容无问题,改键后通常不会有出错或者失效的现象发生。
46 | 本程序可修改的键位不仅包括在STG中用到的各种控制键(↑、↓、←、→、Z、X、C、SHIFT、CTRL、ESC等),还包括:
47 |
48 | - 截图键(
Home
或P
)
49 | R
( ESC+R
可以快速 RETRY)
50 |
53 | D
(永夜抄 RESULT 画面会用到,可以将游戏纪录保存到文件中)
54 | - 以及其他游戏中用到的一切键位。
55 |
56 | - 不过 Windows 窗口程序的通用键位是改不了的,比如
Alt+Space
打开系统菜单, Alt+F4
关闭窗口什么的,这是 Windows 管的,本工具无法对这些系统组合键进行重映射。
57 |
58 |
59 | 除此之外,还有这些优点:
60 |
61 | - 对于同一个玩家来讲,改键位一般不是经常要干的事情。直接改 EXE 的方法可以做到一劳永逸,玩家运行游戏时无需再运行其他辅助工具。
62 | - 修改 EXE 只需操作者拥有对该 EXE 文件的读取和写入权限,所以通常不会有因为用户权限或内存布局等原因而导致修改失败的问题发生。
63 |
64 | 当然缺点也很明显,就是不通用,除了下面 支持的游戏版本
中所列出的游戏的主程序文件外,不支持任何其他的文件。
65 |
66 | - 另外,也不能为同一个功能映射多个按键,不过游戏本来就已经有多个映射的除外。
67 |
68 | - 比如在几乎所有的东方STG游戏中
小键盘8
的作用和 ↑
方向键 相同,属于一个功能有多个映射的例子,本程序可以分别将它们映射到不同的功能上。
69 |
70 |
71 | 支持的游戏版本
72 |
73 | - 东方红魔乡 1.02h 日文原版
74 | - 东方红魔乡 渔场汉化版(主程序需脱壳)
75 | - 东方妖妖梦 1.00b 日文原版、渔场汉化版
76 | - 东方永夜抄 1.00d 日文原版、渔场汉化版
77 | - 东方文花帖 1.02a 日文原版
78 | - 东方风神录 1.00a 日文原版、东方喝茶委员会汉化版
79 | - 东方地灵殿 1.00a 日文原版
80 | - 东方星莲船 1.00b 日文原版
81 | - 东方文花帖DS 1.00a 日文原版
82 | - 妖精大战争 ~ 东方三月精 1.00a 日文原版
83 | - 东方神灵庙 1.00c 日文原版
84 | - 东方辉针城 1.00b 日文原版、喵玉汉化版
85 | - 弹幕天邪鬼 1.00a 日文原版、喵玉汉化版
86 | - 东方绀珠传 1.00b 日文原版、喵玉汉化版
87 | - 东方天空璋 1.00a 日文原版、喵玉汉化版
88 | - 秘封噩梦日记 1.00a 日文原版
89 | - 东方鬼形兽 0.01a 体验版
90 | - 东方鬼形兽 1.00b 日文原版
91 | - 黄昏酒场 1.00a
92 |
93 | 注意:若有哪一作未提到支持汉化版,只是未测试而已,多数情况下只要游戏版本号相同应该也能支持
94 | 对于其他打了非官方补丁的版本,本程序可能也能识别,但不保证能达到正确的修改效果。
95 |
96 | - 喵玉汉化版请选择原版的 exe(比如 th14.exe),而不是带 c 的 exe(比如 th14c.exe。那只是个启动器而已,而非游戏主程序)。
97 | - 花映冢由于比较复杂,所以暂时坑掉。
98 | 地灵殿目前其实是可以打补丁的,但是打了补丁也没用,原因在ZUN。请参见下面的 常见问题
。 从 1.20 版起已经全面支持。
99 |
100 | 使用方法
101 |
102 | - 启动 thkmc.exe 。初次启动界面如图所示。
103 |
104 | 
105 | - 注意:启动时若 thkmc.ini 文件不存在,会提示该文件已被自动生成。
106 |
107 | - 点击左上角的“编辑 thkmc.ini”,会使用默认程序(通常是
记事本
)打开 thkmc.ini。你可以根据自己的喜好更改键位。
108 |
109 | 
110 | - 若你未修改过自动生成的 thkmc.ini 文件,则按照以下规则修改键位:
111 |
112 | - ↑=W
113 | - ↓=S
114 | - ←=A
115 | - →=D
116 | - Z=J
117 | - X=K
118 | - C=L
119 | - 左SHIFT=I
120 |
121 | - 若要改成其他键位请参考本程序源代码中的 KeyNamesDX.ahk 。
122 | - 举个栗子:比如如果要将
ESC
键映射为 `
键(即“反引号”键。通常位于主键盘数字 1
键的左边),则可以在 LSHIFT=i
下面插入一行 ESC=GRAVE
即可。
123 |
124 | 除了字母键外,thkmc.ini 文件中其他的按键都必须写键位名称,这需要使用者自行参考 KeyNamesDX.ahk,然后将其填入 INI 文件中。其中 THKMC_KeyNamesDX["XXX"]
中的 XXX
部分便是可以使用的键位名称。
125 | 比如该文件中有一行是:
126 | THKMC_KeyNamesDX["GRAVE"] := 0x29 ; accent grave `
127 | 如图: 
128 | 右边的注释 accent grave `
提示 GRAVE
是 `
键的名称。所以将 GRAVE
填入 INI 文件中即可。
129 | 完整的 INI 编写说明可参考 INI设置项说明 。
130 |
131 |
132 | - 编辑好后别忘了保存哦。怎么保存文件相信大家都会所以这里就不赘述啦(
133 | - 点击上面的“打开程序并应用补丁”按钮。(下图以
东方鬼形兽 0.01a 体验版
为例)
134 |
135 | 
136 |
137 | - 选择一个本程序支持的东方STG的主程序。具体支持哪些游戏主程序请参考上面的 支持的游戏版本 。
138 |
139 | 
140 |
141 | - THKMC 会自动根据 thkmc.ini 里设置的键位修改程序,并覆盖原EXE,然后报告结果。
142 |
143 |
144 |
145 | - {未指定} 就是INI文件中没有设置重映射,但是本游戏程序支持该键被重映射。比如说这个结果窗口里写了
{未指定} F10
,就说明东方鬼形兽支持 F10
键(切换全屏/窗口) 被重映射,如果你想要改成比如 F12
,你可以在INI文件里写 F10=F12
,那么以后按 F12
就可以切换全屏了。
146 | - 另外要注意,能被重映射的键位,不一定表示该键位一定有功能。比如
D
键,曾经在永夜抄里有作用,而后来的作品基本都用不到了。但是你可以看到东方鬼形兽还会监视 D
键,但是其实是没有功能的。所以我们可以写 RIGHT=D
来赋予 D
键新的功能。
147 |
148 | - 在覆盖原文件前, THKMC 会根据主界面中
备份到 *.thkmcbackup?
的设置,执行自动备份。
149 | - 如果主窗口的
测试模式
复选框处于选中状态,也会弹出该结果框,但并不会真正地修改游戏主程序,备份文件也不会被生成(且结果框底色通常会是原谅绿)。
150 |
151 | - 成功应用补丁的EXE会添加到列表中。
152 |
153 | 
154 | - 如果主窗口的
总是添加至列表
复选框处于选中状态,那么即使打补丁失败,其文件路径也会添加的列表中。
155 |
156 | - 什么?你说“上面的图里找不到
总是添加至列表
复选框”?嘛,还是那句话:图片仅供参考,请以实物为准
hhhhh 天之声:你就不会说你懒得再截图吗
157 |
158 | - 以后如果要换一套键位,可以先修改 INI 文件(记得保存文件!),然后通过上面的“应用补丁”按钮或者右键菜单中的“应用改键补丁”命令再次应用补丁,这样就可以使用新键位了。
159 | - 也可以通过双击直接运行该程序,甚至还可以在右键菜单中运行 vpatch、custom.exe 等。所以也可以把 THKMC 当一个简单的
东方STG游戏启动器
来使用。
160 |
161 |
162 | 使用时的注意事项
163 |
164 | 本程序仅仅通过 EXE 的文件大小和 PE 文件头中的UNIX时间戳(dwTimestamp) 来判断是哪个游戏,所以应该可以兼容各种打过第三方补丁(包括汉化补丁)的版本。
165 |
166 | - 【注意】一个例外是红魔乡渔场汉化版,这个版本的 EXE 因为是加过壳的,所以无法直接修改,必须要脱过壳的版本才可以。
167 |
168 | - 而且网上流传的红魔乡渔场汉化版与最新的日文版版本号不同,并非 1.02h (这也是为什么只有红魔乡的汉化版不能使用VP的原因)。为此有人针对 1.02h 做过一个汉化版,可以使用 VP。获取方式请参考 喵玉殿论坛上的THKMC发布帖 。
169 |
170 |
171 | 根据打补丁成功与否,“结果”窗口的底色(非文本框颜色)会有所不同。
172 |
173 | - 姨妈红:有错误。
174 | - 菊花黄:有警告(常见的情况是 INI 文件中有至少一个键位名称没有写对,导致 THKMC 无法识别)。
175 | - 原谅绿:测试模式已开启。改键补丁并未实际打到游戏程序上。请在主窗口中取消
测试模式
勾选,然后重试。
176 | - 正常颜色:打补丁成功。
177 | - 优先级为 姨妈红>菊花黄>原谅绿。
178 |
179 | - 假如既有错误,又有警告,又开启了测试模式,那么底色会是姨妈红,因为优先级最高。
180 |
181 |
182 | 由于作者患有懒癌晚期,本程序在修改前不会校验被修改的数据,所以如果有哪个第三方补丁修改的地方恰好与本程序相同,或者在补丁数据位置之前插入了其他数据导致位置发生了偏差,那么应用改键补丁后的结果将没有人知道!
183 |
184 | 使用技巧
185 |
186 | - 可以一次打开多个文件。
187 | - 可以一次对多个文件应用补丁。其结果会统一显示在一个结果窗口中。
188 | - 支持文件拖拽。
189 |
190 | - (1.40版起)如果拖入的是目录,会自动遍历其中的所有 .exe 文件(包括子目录)。
191 |
192 |
193 | INI设置项说明
194 | 请参阅软件目录下的 thkmc_sample.ini
文件。
195 |
198 | 常见问题
199 |
200 | 如何从打过补丁后的EXE中获取键位?
201 |
202 | 目前无法获取。
203 |
204 | 地灵殿键位修改无效。
205 |
206 | 请更新到最新版本的 THKMC。
207 |
208 | 各种杀软报毒?
209 |
210 | 本程序使用 AutoHotkey 语言编写,并使用 MPRESS 压缩。可能有些杀软对 MPRESS 壳敏感。若报毒请添加信任。
211 | 作者承诺决不暗藏任何恶意代码。不信自己看源代码吧。
212 |
213 |
214 | 联系作者
215 | @wz520 度娘贴吧ID: 天使的枷锁 邮箱
216 | 下载地址&更新历史
217 | 本程序的新版本可以在以下地址获取到:
218 | 编译版&更新历史:
219 |
223 | 源代码:
224 |
227 | 我编写的其他小程序:
228 |
231 |
232 |
233 |
--------------------------------------------------------------------------------
/docs/help.md:
--------------------------------------------------------------------------------
1 | # THKMC - 东方STG专用键盘映射修改工具
2 |
3 | 当前版本: `1.40`
4 |
5 | ## 功能
6 |
7 | 众所周知,ZUN 制作的 东方STG 从来就不自带更改键盘键位的功能。为此,各路大神都写过各种键盘映射工具,但大多是外挂式的。随着新版本的 Windows 对系统安全性的要求越来越高,这些外挂式的改键工具都可能存在兼容性问题。
8 |
9 | THKMC(TouHou Keyboard Mapping Changer) 通过修改东方STG游戏主程序文件中与键盘映射相关的代码,实现自定义游戏键位。
10 |
11 | 东方STG获取键盘按键状态的方法有两种:`使用 DirectInput` 和 `不使用 DirectInput` 。
12 | 其中 `使用 DirectInput` 是通过调用 [IDirectInputDevice8::GetDeviceState()] 来获取键盘状态的;而 `不使用 DirectInput` 则是使用 Win32 API 中的 [GetKeyboardState()]。
13 |
14 | 本程序 **只支持** 对使用 DirectInput 方式获取的按键映射进行更改。所以要求在游戏自带的 custom.exe 程序中不能勾选 “不使用 DirectInput 获取键盘输入”。若勾选的话使用本程序改键将没有任何效果。(不过一般不会有人去勾选吧,因为游戏默认的不勾选也能工作得很好。)
15 |
16 | ## 特点
17 |
18 | 相比较其他常见的外挂式通用键位修改工具,因为 THKMC 是为特定的EXE文件量身定制的,所以只要游戏版本正确且用户写的配置文件内容无问题,改键后通常不会有出错或者失效的现象发生。
19 |
20 | 本程序可修改的键位不仅包括在STG中用到的各种控制键(↑、↓、←、→、Z、X、C、SHIFT、CTRL、ESC等),还包括:
21 |
22 | * 截图键(`Home`或`P`)
23 | * `R`( `ESC+R` 可以快速 RETRY)
24 | + 鬼形兽 1.00b 除外。因为游戏本来就不支持该功能,疑似BUG。详见 [THBWIKI:官方游戏错误解决办法] 页面
25 | * `D`(永夜抄 RESULT 画面会用到,可以将游戏纪录保存到文件中)
26 | * 以及其他游戏中用到的一切键位。
27 | + 不过 Windows 窗口程序的通用键位是改不了的,比如 `Alt+Space` 打开系统菜单, `Alt+F4` 关闭窗口什么的,这是 Windows 管的,本工具无法对这些系统组合键进行重映射。
28 |
29 | 除此之外,还有这些优点:
30 |
31 | * 对于同一个玩家来讲,改键位一般不是经常要干的事情。直接改 EXE 的方法可以做到一劳永逸,玩家运行游戏时无需再运行其他辅助工具。
32 | * 修改 EXE 只需操作者拥有对该 EXE 文件的读取和写入权限,所以通常不会有因为用户权限或内存布局等原因而导致修改失败的问题发生。
33 |
34 | 当然缺点也很明显,就是不通用,除了下面 `支持的游戏版本` 中所列出的游戏的主程序文件外,不支持任何其他的文件。
35 |
36 | * 另外,也不能为同一个功能映射多个按键,不过游戏本来就已经有多个映射的除外。
37 | + 比如在几乎所有的东方STG游戏中 `小键盘8` 的作用和 `↑` 方向键 相同,属于一个功能有多个映射的例子,本程序可以分别将它们映射到不同的功能上。
38 |
39 | ## 支持的游戏版本
40 |
41 | * 东方红魔乡 1.02h 日文原版
42 | * 东方红魔乡 渔场汉化版(**主程序需脱壳**)
43 | * 东方妖妖梦 1.00b 日文原版、渔场汉化版
44 | * 东方永夜抄 1.00d 日文原版、渔场汉化版
45 | * 东方文花帖 1.02a 日文原版
46 | * 东方风神录 1.00a 日文原版、东方喝茶委员会汉化版
47 | * 东方地灵殿 1.00a 日文原版
48 | * 东方星莲船 1.00b 日文原版
49 | * 东方文花帖DS 1.00a 日文原版
50 | * 妖精大战争 ~ 东方三月精 1.00a 日文原版
51 | * 东方神灵庙 1.00c 日文原版
52 | * 东方辉针城 1.00b 日文原版、喵玉汉化版
53 | * 弹幕天邪鬼 1.00a 日文原版、喵玉汉化版
54 | * 东方绀珠传 1.00b 日文原版、喵玉汉化版
55 | * 东方天空璋 1.00a 日文原版、喵玉汉化版
56 | * 秘封噩梦日记 1.00a 日文原版
57 | * 东方鬼形兽 0.01a 体验版
58 | * 东方鬼形兽 1.00b 日文原版
59 | * 黄昏酒场 1.00a
60 |
61 |
62 | **注意**:若有哪一作未提到支持汉化版,只是未测试而已,多数情况下只要游戏版本号相同应该也能支持
63 |
64 | _对于其他打了非官方补丁的版本,本程序可能也能识别,但不保证能达到正确的修改效果。_
65 |
66 | * 喵玉汉化版请选择原版的 exe(比如 th14.exe),而不是带 c 的 exe(比如 th14c.exe。那只是个启动器而已,而非游戏主程序)。
67 | * **花映冢**由于比较复杂,所以暂时坑掉。
68 | * **地灵殿**目前其实是可以打补丁的,但是打了补丁也没用,原因在ZUN。请参见下面的 `常见问题`。 从 1.20 版起已经全面支持。
69 |
70 | ## 使用方法
71 |
72 | 1. 启动 thkmc.exe 。初次启动界面如图所示。
73 | * 
74 | * **注意**:启动时若 thkmc.ini 文件不存在,会提示该文件已被自动生成。
75 | 2. 点击左上角的“编辑 thkmc.ini”,会使用默认程序(通常是`记事本`)打开 thkmc.ini。你可以根据自己的喜好更改键位。
76 | * 
77 | * 若你未修改过自动生成的 thkmc.ini 文件,则按照以下规则修改键位:
78 | + ↑=W
79 | + ↓=S
80 | + ←=A
81 | + →=D
82 | + Z=J
83 | + X=K
84 | + C=L
85 | + 左SHIFT=I
86 | * 若要改成其他键位请参考本程序源代码中的 [KeyNamesDX.ahk] 。
87 | * **举个栗子**:比如如果要将 `ESC` 键映射为 `` ` `` 键(即“反引号”键。通常位于主键盘数字 `1` 键的左边),则可以在 `LSHIFT=i` 下面插入一行 `ESC=GRAVE` 即可。
88 | + 除了字母键外,thkmc.ini 文件中其他的按键都必须写键位名称,这需要使用者自行参考 [KeyNamesDX.ahk],然后将其填入 INI 文件中。其中 `THKMC_KeyNamesDX["XXX"]` 中的 `XXX` 部分便是可以使用的键位名称。
89 | + 比如该文件中有一行是:
90 |
91 | THKMC_KeyNamesDX["GRAVE"] := 0x29 ; accent grave `
92 | + 如图: 
93 | + 右边的注释 ``accent grave ` `` 提示 `GRAVE` 是 `` ` `` 键的名称。所以将 `GRAVE` 填入 INI 文件中即可。
94 | + 完整的 INI 编写说明可参考 [INI设置项说明] 。
95 | 3. 编辑好后**别忘了保存**哦。怎么保存文件相信大家都会所以这里就不赘述啦(
96 | 4. 点击上面的“打开程序并应用补丁”按钮。(下图以 `东方鬼形兽 0.01a 体验版` 为例)
97 | * 
98 | 5. 选择一个本程序支持的东方STG的主程序。具体支持哪些游戏主程序请参考上面的 [支持的游戏版本] 。
99 | * 
100 | 6. THKMC 会自动根据 thkmc.ini 里设置的键位修改程序,并覆盖原EXE,然后报告结果。
101 | * 
102 | - {未指定} 就是INI文件中没有设置重映射,但是本游戏程序支持该键被重映射。比如说这个结果窗口里写了 `{未指定} F10`,就说明东方鬼形兽支持 `F10` 键(切换全屏/窗口) 被重映射,如果你想要改成比如 `F12`,你可以在INI文件里写 `F10=F12` ,那么以后按 `F12` 就可以切换全屏了。
103 | - 另外要注意,能被重映射的键位,不一定表示该键位一定有功能。比如 `D` 键,曾经在永夜抄里有作用,而后来的作品基本都用不到了。但是你可以看到东方鬼形兽还会监视 `D` 键,但是其实是没有功能的。所以我们可以写 `RIGHT=D` 来赋予 `D` 键新的功能。
104 | * 在覆盖原文件前, THKMC 会根据主界面中 `备份到 *.thkmcbackup?` 的设置,执行自动备份。
105 | * 如果主窗口的 `测试模式` 复选框处于选中状态,也会弹出该结果框,但并不会真正地修改游戏主程序,备份文件也不会被生成(且结果框底色通常会是原谅绿)。
106 | 7. 成功应用补丁的EXE会添加到列表中。
107 | * 
108 | * 如果主窗口的 `总是添加至列表` 复选框处于选中状态,那么即使打补丁失败,其文件路径也会添加的列表中。
109 | - 什么?你说“上面的图里找不到 `总是添加至列表` 复选框”?嘛,还是那句话:`图片仅供参考,请以实物为准`hhhhh ~~天之声:你就不会说你懒得再截图吗~~
110 | * 以后如果要换一套键位,可以先修改 INI 文件(记得保存文件!),然后通过上面的“应用补丁”按钮或者右键菜单中的“应用改键补丁”命令再次应用补丁,这样就可以使用新键位了。
111 | * 也可以通过双击直接运行该程序,甚至还可以在右键菜单中运行 vpatch、custom.exe 等。所以也可以把 THKMC 当一个简单的 `东方STG游戏启动器` 来使用。
112 |
113 |
114 | ### 使用时的注意事项
115 |
116 | * 本程序仅仅通过 EXE 的文件大小和 PE 文件头中的UNIX时间戳(dwTimestamp) 来判断是哪个游戏,所以应该可以兼容各种打过第三方补丁(包括汉化补丁)的版本。
117 |
118 | - 【**注意**】一个例外是红魔乡渔场汉化版,这个版本的 EXE 因为是加过壳的,所以无法直接修改,必须要脱过壳的版本才可以。
119 | + 而且网上流传的红魔乡渔场汉化版与最新的日文版版本号不同,并非 1.02h (这也是为什么只有红魔乡的汉化版不能使用VP的原因)。为此有人针对 1.02h 做过一个汉化版,可以使用 VP。获取方式请参考 [喵玉殿论坛上的THKMC发布帖] 。
120 |
121 | * 根据打补丁成功与否,“结果”窗口的底色(非文本框颜色)会有所不同。
122 | - 姨妈红:有错误。
123 | - 菊花黄:有警告(常见的情况是 INI 文件中有至少一个键位名称没有写对,导致 THKMC 无法识别)。
124 | - 原谅绿:测试模式已开启。改键补丁并未实际打到游戏程序上。请在主窗口中取消 `测试模式` 勾选,然后重试。
125 | - 正常颜色:打补丁成功。
126 | - 优先级为 姨妈红>菊花黄>原谅绿。
127 | + 假如既有错误,又有警告,又开启了测试模式,那么底色会是姨妈红,因为优先级最高。
128 |
129 | * ~~由于作者患有懒癌晚期,~~本程序在修改前不会校验被修改的数据,所以如果有哪个第三方补丁修改的地方恰好与本程序相同,或者在补丁数据位置之前插入了其他数据导致位置发生了偏差,那么应用改键补丁后的结果将**没有人知道**!
130 |
131 |
132 | ### 使用技巧
133 |
134 | * 可以一次打开多个文件。
135 | * 可以一次对多个文件应用补丁。其结果会统一显示在一个结果窗口中。
136 | * 支持文件拖拽。
137 | + (1.40版起)如果拖入的是目录,会自动遍历其中的所有 .exe 文件(包括子目录)。
138 |
139 | ## INI设置项说明
140 |
141 | 请参阅软件目录下的 `thkmc_sample.ini` 文件。
142 |
143 | * 或者直接用浏览器看 [带高亮版的 thkmc_sample.ini](https://wz520.github.io/thkmc/thkmc_sample_ini.html) 。
144 |
145 |
146 | ## 常见问题
147 |
148 | * 如何从打过补丁后的EXE中获取键位?
149 |
150 | > 目前无法获取。
151 |
152 | * **地灵殿键位修改无效。**
153 |
154 | > 请更新到最新版本的 THKMC。
155 |
156 | * 各种杀软报毒?
157 |
158 | > 本程序使用 [AutoHotkey](https://autohotkey.com/) 语言编写,并使用 [MPRESS](http://www.matcode.com/mpress.htm) 压缩。可能有些杀软对 MPRESS 壳敏感。若报毒请添加信任。
159 | >
160 | > 作者承诺决不暗藏任何恶意代码。不信自己看源代码吧。
161 |
162 | ## 联系作者
163 |
164 | @wz520
165 | 度娘贴吧ID: [天使的枷锁](http://tieba.baidu.com/home/main?id=f861cceccab9b5c4bccfcbf83d00&fr=userbar)
166 | [邮箱](mailto:wingzero1040@gmail.com)
167 |
168 |
169 | ## 下载地址&更新历史
170 |
171 | 本程序的新版本可以在以下地址获取到:
172 |
173 | 编译版&更新历史:
174 |
175 | * Github:
176 | * [喵玉殿论坛上的THKMC发布帖]
177 |
178 | 源代码:
179 |
180 | * Github:
181 |
182 |
183 | 我编写的其他小程序:
184 |
185 | *
186 |
187 |
188 | [thkmc_sample.ini]: https://github.com/wz520/thkmc/blob/master/thkmc_sample.ini
189 | [IDirectInputDevice8::GetDeviceState()]: https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.idirectinputdevice8.idirectinputdevice8.getdevicestate(v=vs.85).aspx
190 | [GetKeyboardState()]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms646299(v=vs.85).aspx
191 | [IDirectInputDevice8::SetCooperativeLevel]: https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.idirectinputdevice8.idirectinputdevice8.setcooperativelevel(v=vs.85).aspx
192 | [CreateWindowEx()]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms632680(v=vs.85).aspx
193 | [KeyNamesDX.ahk]: https://github.com/wz520/thkmc/blob/master/KeyNamesDX.ahk
194 | [喵玉殿论坛上的THKMC发布帖]: http://bbs.nyasama.com/forum.php?mod=viewthread&tid=78904
195 |
196 | [THBWIKI:官方游戏错误解决办法]: https://thwiki.cc/%E5%AE%98%E6%96%B9%E6%B8%B8%E6%88%8F/%E9%94%99%E8%AF%AF%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95
197 |
--------------------------------------------------------------------------------
/docs/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | /* font-family: Segoe UI, "Microsoft YaHei", Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; */
3 | font-family: Segoe UI, "Microsoft YaHei", Arial, sans-serif, 宋体, PMingLiU, serif;
4 | font-size: 10.5pt;
5 | line-height: 1.5;
6 | padding-top: 10px;
7 | padding-bottom: 10px;
8 | background-color: #222222;
9 | color: white;
10 | padding: 10px;
11 | }
12 |
13 | strong {
14 | font-size: 1.4em;
15 | background-color: yellowgreen;
16 | color: blue;
17 | border: 3px ridge slateblue;
18 | border-radius: 5px;
19 | transition: color 0.5s, background-color 0.5s;
20 | }
21 | strong:hover {
22 | color: red;
23 | background-color: bisque ;
24 | }
25 | em {
26 | font-size: 1.2em;
27 | }
28 |
29 | /* DEPRECATED */
30 | /*
31 | em:before {
32 | content: "❢ ";
33 | font-size: 1.5em;
34 | color: crimson;
35 | }
36 | em:after {
37 | content: " ❢";
38 | font-size: 1.5em;
39 | color: crimson;
40 | }
41 | */
42 | em:before {
43 | content: "☢CAUTION!!☢ ";
44 | font-size: 1.5em;
45 | color: crimson;
46 | font-style: normal;
47 | font-weight: bold;
48 | }
49 | em:after {
50 | content: " ☢CAUTION!!☢";
51 | font-size: 1.5em;
52 | color: crimson;
53 | font-style: normal;
54 | font-weight: bold;
55 | }
56 |
57 |
58 | nav#TOC:before {
59 | content: "目录:";
60 | font-size: 1.5em;
61 | }
62 | nav#TOC{
63 | border: 3px solid white;
64 | border-radius: 5px;
65 | line-height: 30%;
66 | padding-top: 1em;
67 | width: 25em;
68 | background-color: darkgreen;
69 | }
70 | nav#TOC ul{
71 | /* list-style-type: square; */
72 | /* display: inline; */
73 | }
74 | nav#TOC ul li{
75 | /* display: inline; */
76 | }
77 | nav#TOC ul li a{
78 | color: yellow;
79 | transition: background-color 0.5s, color 0.5s;
80 | }
81 | nav#TOC ul li a:active {
82 | color: red;
83 | }
84 | nav#TOC ul li a:hover {
85 | /* color: fuchsia; */
86 | /* background-color: darkblue; */
87 | color: orange;
88 | background-color: darkred;
89 | border: 4px inset gray;
90 | }
91 |
92 | body > *:first-child {
93 | margin-top: 0 !important;
94 | }
95 | body > *:last-child {
96 | margin-bottom: 0 !important;
97 | }
98 |
99 | a {transition: color 0.5s;}
100 | a:link {color:skyblue;}
101 | a:visited {color:skyblue;}
102 | a:hover {color:yellow;background-color:blue;}
103 | a:active {color:red;}
104 |
105 | h1 a:link, h1 a:visited {
106 | color: hotpink;
107 | }
108 | h1 a:hover {color:yellow;background-color:blue;}
109 | h1 a:active {color:red;}
110 |
111 | h2 a:link, h2 a:visited {
112 | color: aqua;
113 | }
114 | h2 a:hover {color:yellow;background-color:blue;}
115 | h2 a:active {color:red;}
116 |
117 | h2:before {
118 | content: "❀ ";
119 | }
120 |
121 | h2.author a:link, h2.author a:visited {
122 | color: chartreuse;
123 | }
124 | h2.author:before {
125 | content: "✍ ";
126 | color: red;
127 | }
128 | h2.author a:hover {color:yellow;background-color:blue;}
129 | h2.author a:active {color:red;}
130 |
131 | h3:before {
132 | content: "☯ ";
133 | }
134 |
135 | /* ADDED */
136 | h4:before {
137 | /* content: "❂ ";*/
138 | content: "✦ ";
139 | }
140 |
141 |
142 | h1, h2, h3, h4, h5, h6 {
143 | margin: 20px 0 10px;
144 | padding: 0;
145 | font-weight: bold;
146 | -webkit-font-smoothing: antialiased;
147 | cursor: text;
148 | position: relative;
149 | }
150 | h1 {
151 | font-size: 28px;
152 | color: magenta;
153 | text-align: center;
154 | }
155 | h2 {
156 | font-size: 24px;
157 | border-bottom: 1px solid #cccccc;
158 | color: aqua;
159 | }
160 | h3 {
161 | font-size: 18px;
162 | color: gold;
163 | }
164 | h4 {
165 | font-size: 16px;
166 | }
167 | h5 {
168 | font-size: 14px;
169 | }
170 | h6 {
171 | color: #777777;
172 | font-size: 14px;
173 | }
174 | p, blockquote, ul, ol, dl, li, table, pre {
175 | margin: 15px 0;
176 | }
177 | hr {
178 | background: transparent;
179 | /* border: 0 none; */
180 | color: #333333;
181 | height: 4px;
182 | padding: 0;
183 | }
184 | body > h2:first-child {
185 | margin-top: 0;
186 | padding-top: 0;
187 | }
188 | body > h1:first-child {
189 | margin-top: 0;
190 | padding-top: 0;
191 | }
192 | body > h1:first-child + h2 {
193 | margin-top: 0;
194 | padding-top: 0;
195 | }
196 | body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child {
197 | margin-top: 0;
198 | padding-top: 0;
199 | }
200 |
201 | h1 p, h2 p, h3 p, h4 p, h5 p, h6 p {
202 | margin-top: 0;
203 | }
204 | li p.first {
205 | display: inline-block;
206 | }
207 | ul, ol {
208 | padding-left: 30px;
209 | }
210 |
211 |
212 | /* DEPRECATED */
213 | /*
214 | ol > li {
215 | border-bottom-width: 1px;
216 | border-bottom-style: dotted;
217 | border-color: goldenrod;
218 | }
219 | */
220 | ol > li {
221 | border-width: 1px;
222 | border-style: solid;
223 | border-color: goldenrod;
224 | }
225 |
226 | ul :first-child, ol :first-child {
227 | margin-top: 0;
228 | }
229 | ul :last-child, ol :last-child {
230 | margin-bottom: 0;
231 | }
232 | dl {
233 | padding: 0;
234 | }
235 | dl dt {
236 | font-size: 1.2em;
237 | font-weight: bold;
238 | font-style: italic;
239 | padding: 0;
240 | margin: 15px 0 5px;
241 | }
242 | dl dt:first-child {
243 | padding: 0;
244 | }
245 | dl dt > :first-child {
246 | margin-top: 0;
247 | }
248 | dl dt > :last-child {
249 | margin-bottom: 0;
250 | }
251 | dl dd {
252 | margin: 0 0 15px;
253 | padding: 0 2em;
254 | }
255 | dl dd > :first-child {
256 | margin-top: 0;
257 | }
258 | dl dd > :last-child {
259 | margin-bottom: 0;
260 | }
261 | blockquote {
262 | border-left: 4px solid silver;
263 | padding: 0 15px;
264 | color: silver;
265 | }
266 | blockquote > :first-child {
267 | margin-top: 0;
268 | }
269 | blockquote > :last-child {
270 | margin-bottom: 0;
271 | }
272 | table {
273 | padding: 0;
274 | border: 4px ridge lightgray;
275 | /* width: 50%; */
276 | caption-side: bottom;
277 | }
278 | table tr {
279 | border-top: 2px solid yellow;
280 | background-color: #202020;
281 | margin: 0;
282 | padding: 0;
283 | }
284 |
285 | /* table tr:nth-child(2n) { */
286 | /* background-color: #101010; */
287 | /* } */
288 | table tr.even {
289 | background-color: #101010;
290 | }
291 |
292 | table tr th {
293 | font-weight: bold;
294 | border: 1px solid yellow;
295 | text-align: center;
296 | margin: 0;
297 | padding: 6px 13px;
298 | color: aqua;
299 | }
300 | table tr td {
301 | border: 1px solid silver;
302 | margin: 0;
303 | padding: 6px 13px;
304 | color: deeppink;
305 | }
306 | table tr th :first-child, table tr td :first-child {
307 | margin-top: 0;
308 | }
309 | table tr th :last-child, table tr td :last-child {
310 | margin-bottom: 0;
311 | }
312 | img {
313 | max-width: 100%;
314 | border: 2px groove gray;
315 | }
316 | code {
317 | margin: 0 2px;
318 | padding: 0 5px;
319 | white-space: nowrap;
320 | border: 1px solid #3a3a3a;
321 | background-color: blue;
322 | border-radius: 3px;
323 | color: lightgreen;
324 | }
325 | pre {
326 | background-color: #3a2a1a;
327 | border: 5px ridge silver;
328 | font-size: 13px;
329 | line-height: 19px;
330 | overflow: auto;
331 | padding: 6px 10px;
332 | border-radius: 3px;
333 | width: 50%;
334 | transition: background-color 0.3s;
335 | }
336 | pre:hover {
337 | background-color: #333;
338 | }
339 | pre code {
340 | margin: 0;
341 | padding: 0;
342 | white-space: pre;
343 | border: none;
344 | background: transparent;
345 | background-color: transparent;
346 | transition: inherit;
347 | }
348 |
349 | pre, code.sourceCode {
350 | color: mintcream;
351 | background-color: black;
352 | }
353 |
354 | del {
355 | color: black;
356 | background-color: black;
357 | text-decoration: none;
358 | }
359 |
360 | /* mysign */
361 | span a {
362 | border: 3px outset gray;
363 | background-color: darkblue;
364 | }
365 | span.mail a:before {
366 | font-size: 1.5em;
367 | content: "✉ ";
368 | }
369 |
370 | /* footnotes */
371 | div.footnotes ol:before {
372 | content: "✎ 脚注: ";
373 | color: deeppink;
374 | }
375 |
376 | /* dl, dt, dd */
377 | dl {
378 | border: 3px ridge green;
379 | }
380 | dt {
381 | width: 20em;
382 | color: lightgreen;
383 | }
384 | dd {
385 | color: violet;
386 | width: 50em;
387 | }
388 | dd:before {
389 | content: "☞ ";
390 | }
391 |
--------------------------------------------------------------------------------
/docs/thkmc_sample_ini.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | THKMC_SAMPLE
6 |
7 |
8 |
9 |
10 |
11 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | [Default]
40 | UP=W
41 | DOWN=S
42 | LEFT=A
43 | RIGHT=D
44 |
45 |
46 |
47 | Z=j
48 | X=k
49 | C=l
50 | LSHIFT=i
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 | [th125]
139 | S=ScrollLock
140 |
141 |
142 |
143 | [th8]
144 | D=ScrollLock
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | [th10]
155 |
156 |
157 | ESC=th8:D
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 |
--------------------------------------------------------------------------------
/gamedata.ahk:
--------------------------------------------------------------------------------
1 | ;; THKMC_GameDataXXX 的基类
2 | class THKMC_GameDataBase {
3 | __New( gamename, gamenameCN, timestamp, minfilesize ) {
4 | this._setEXEInfo( gamename, gamenameCN, timestamp, minfilesize )
5 |
6 | ; 一串正则表达式,用于从 patchdata 中取出与键位码相关机器指令的操作数的 HEX 子串(取第一个子表达式。不能没有子表达式)
7 | ; 其中 0fb6 是 MOVZX R32, BYTE PTR SS:[EBP+CONST32] 系列指令的头两个字节
8 | ; 该表达式不适用于所有游戏,所以有些子类的构造函数会修改它。
9 | this.addrPattern := "i)\b0fb6[0-9a-f]+\s([0-9a-z]{2}f[ef]ffff)\s"
10 | }
11 |
12 | _setEXEInfo( gamename, gamenameCN, timestamp, minfilesize ) {
13 | this.gamename := gamename ;; 游戏代号(目前用于 INI 文件中的段名)
14 | this.gamenameCN := gamenameCN ;; 游戏的中文描述(显示给用户看的)
15 |
16 | ; PE 头中的时间戳。用于确定EXE文件的游戏版本
17 | this.timestamp := timestamp
18 |
19 | ;; EXE 的【最小】文件大小。为了支持给EXE添加了区段的第三方补丁,所以并不指定精确的文件大小
20 | this.minfilesize := minfilesize
21 | }
22 |
23 | _setPatchData( patchaddr, patchaddrjmpto, patchVAfix, patchvaluefix, patchdata ) {
24 | this.patchaddr := patchaddr ;; 补丁数据的起始地址(VA,即OD中所看到的地址)
25 | this.patchaddrjmpto := patchaddrjmpto ;; 目标地址,补丁最后的一个 jmp 指令的目标地址,也就是补丁的结束地址
26 | ;; VA - File_Offset(EXE内偏移)
27 | ;; 在 OD 的 CPU 窗口中随便选择一条EXE领空中的指令,右键菜单->查看->可执行文件,然后将 CPU 窗口中的地址减去“可执行文件”窗口中相同指令的地址即可算出该值
28 | ;; 对于大多数东方STG的EXE,该值都是 0x400c00,不过也有例外,比如永夜抄就是 0x400200
29 | this.patchVAfix := patchVAfix
30 | ;; 在 OD 中从 patchaddr 向上查找 LEA R32, [ebp-XXX],取其中的 XXX
31 | this.patchvaluefix := patchvaluefix
32 |
33 | ; 补丁的二进制数据的HEX字符串表示。所有非 HEX 字符都将被忽略
34 | this.patchdata := patchdata
35 |
36 | ; SplitPath, A_ScriptFullPath, , , , scriptname
37 | ; this.inifilepath := A_ScriptDir . "\" . scriptname . ".ini"
38 | this.inifilepath := "thkmc.ini"
39 | }
40 |
41 | ; 用于与按键映射无关的自定义补丁代码。
42 | ; 比如 TH07/TH08 需要加入破解自校验的代码才可以让修改过的 EXE 正常运行
43 | ; 目前用于被 7,8 两个子类覆盖。本基类并不做任何事
44 | doCustomPatch( pEXEData ) {
45 | }
46 |
47 | ; 把使用 HEX 字串表示的数值转换成 AHK 中的整数形式
48 | ; 被转换的 HEX 字串必须是32位小端格式
49 | ; 如果返回字符串 "OUT",则认为超出范围,应该被跳过
50 | str2KeymapValue( s ) {
51 | KeymapValue := ToSigned(BSwap32_ahk( Pad0x(s)+0 ))
52 | KeymapValue := KeymapValue + this.patchvaluefix
53 |
54 | if ( KeymapValue > 0xff || KeymapValue < 0 ) {
55 | return "OUT" ; 超出范围, 忽略
56 | }
57 |
58 | return KeymapValue
59 | }
60 |
61 | ; 上面的反函数
62 | keymapValue2Str( k ) {
63 | k := ToUnsigned( k - this.patchvaluefix )
64 | return PadLeadingZero( UnPad0x(ToHex( BSwap32_ahk( k ) )), 8 )
65 | }
66 | }
67 |
68 |
69 |
70 | #include gamedata\gamedata6.ahk
71 | #include gamedata\gamedata6cn.ahk
72 | #include gamedata\gamedata7.ahk
73 | #include gamedata\gamedata8.ahk
74 | #include gamedata\gamedata95.ahk
75 |
76 | #include gamedata\gamedata10.ahk
77 | #include gamedata\gamedata11.ahk
78 | #include gamedata\gamedata12.ahk
79 | #include gamedata\gamedata125.ahk
80 | #include gamedata\gamedata128.ahk
81 |
82 | #include gamedata\gamedata13.ahk
83 | #include gamedata\gamedata14.ahk
84 | #include gamedata\gamedata143.ahk
85 | #include gamedata\gamedata15.ahk
86 | #include gamedata\gamedata16.ahk
87 | #include gamedata\gamedata165.ahk
88 | #include gamedata\gamedata17tr.ahk
89 | #include gamedata\gamedata17.ahk
90 |
91 | #include gamedata\gamedataalcostg.ahk
92 |
93 |
94 | ; 类名 "THKMC_GameDataXXX" 的 XXX 部分
95 | THKMC_GameIDList := [ "6", "6cn", "7", "8", "95", "10", "11", "12", "125", "128", "13", "14", "143", "15", "16", "165", "17tr", "17", "alcostg" ]
96 |
97 | ; 获取所有支持的游戏列表字符串(目前用于“关于”对话框)
98 | THKMC_GetGameNameList()
99 | {
100 | global THKMC_GameIDList
101 | result := []
102 | for k, id in THKMC_GameIDList {
103 | gamedata := new THKMC_GameData%id%()
104 | result.Push( Format("[{:s}]`t{:s}", gamedata.gamename, gamedata.gamenameCN) )
105 | }
106 | return array_join(result)
107 | }
108 |
--------------------------------------------------------------------------------
/gamedata/buildgamedata.vim:
--------------------------------------------------------------------------------
1 | " 用于把从 OD 粘贴过来的反汇编list转换成 patchdata 格式的辅助脚本。
2 | "
3 | " 粘贴过来的代码首先要手动把左边的地址去掉(用可视块模式(CTRL+Q)很容易解决,所以就不搞替换命令了),然后在每一行的机器码和汇编码之间加分号(同样用可视块手动来做就够了)。
4 | "
5 | " 当然,要使用本脚本里定义的命令,别忘了先 :source 一下。
6 |
7 |
8 | " ** 用于 th128+
9 | "
10 | " **【注意】程序通常使用 MOVZX 获取按键状态的指令,但也可能是 MOV。
11 |
12 | " and r32, 80h ,将 80h 改成 edi,精简字节码,这样 EXE 中才有空间使用下面的
13 | " KMOVZX 系列命令。
14 | "
15 | " 用了本系列命令后,别忘了在前面加上:
16 | " 57 ; PUSH EDI
17 | " BF 80000000 ; MOV EDI,80
18 | " 代码最后要加上:
19 | " 5F ; POP EDI
20 | com! KEAX80EDI %s/^.\+and eax,80$/21f8 ; and eax,edi/gc
21 | com! KEDX80EDI %s/^.\+and edx,80$/21fa ; and edx,edi/gc
22 | com! KECX80EDI %s/^.\+and ecx,80$/21f9 ; and ecx,edi/gc
23 | com! KESI80EDI %s/^.\+and esi,80$/21fe ; and esi,edi/gc
24 |
25 | " 与上面类似,只不过源操作数改成了 EBX
26 | com! KEAX80EBX %s/^.\+and eax,80$/21d8 ; and eax,ebx/gc
27 | com! KEDX80EBX %s/^.\+and edx,80$/21da ; and edx,ebx/gc
28 | com! KECX80EBX %s/^.\+and ecx,80$/21d9 ; and ecx,ebx/gc
29 |
30 | " 修改 MOVZX R32, BYTE PTR [EBP-XXX]
31 | " 将8位操作数(XXX)改成32位
32 | com! KMOVZXBYTEEAX %s/^0fb645 \(\x\{2}\>\)/0fb685 \1ffffff/gc
33 | com! KMOVZXBYTEEDX %s/^0fb655 \(\x\{2}\>\)/0fb695 \1ffffff/gc
34 | com! KMOVZXBYTEECX %s/^0fb64d \(\x\{2}\>\)/0fb68d \1ffffff/gc
35 |
36 |
37 | " ** 用于使用 ESP 访问局部变量的游戏(th10, th11, th12, th125, alcostg)
38 |
39 | " 与 KXXX80EBX 类似,只不过源操作数改成了 BL,且目标操作数也都是 8 位(AL, CL, DL)
40 | com! KAL80BL %s/^.\+and al,80$/20d8 ; and al,bl/gc
41 | com! KCL80BL %s/^.\+and cl,80$/20d9 ; and cl,bl/gc
42 | com! KDL80BL %s/^.\+and dl,80$/20da ; and dl,bl/gc
43 |
44 | " 修改 MOVZX R32, BYTE PTR [ESP+XXX]
45 | " 将8位操作数(XXX)改成32位
46 | com! KESPMOVZXBYTEESI %s/^0fb67424 \(\x\{2}\>\)/0fb6b424 \1000000/gc
47 | com! KESPMOVZXBYTEEAX %s/^0fb64424 \(\x\{2}\>\)/0fb68424 \1000000/gc
48 | com! KESPMOVZXBYTEECX %s/^0fb64c24 \(\x\{2}\>\)/0fb68c24 \1000000/gc
49 | com! KESPMOVZXBYTEEDX %s/^0fb65424 \(\x\{2}\>\)/0fb69424 \1000000/gc
50 |
51 | " 修改 MOVZX R32, BYTE PTR [ESP+XXX]
52 | " 将32位操作数(XXX)改成8位
53 | com! K32T8ESPMOVZXBYTEESI %s/^0fb6b424 \(\x\{2}\)000000\>/0fb67424 \1/gc
54 | com! K32T8ESPMOVZXBYTEEAX %s/^0fb68424 \(\x\{2}\)000000\>/0fb64424 \1/gc
55 | com! K32T8ESPMOVZXBYTEECX %s/^0fb68c24 \(\x\{2}\)000000\>/0fb64c24 \1/gc
56 | com! K32T8ESPMOVZXBYTEEDX %s/^0fb69424 \(\x\{2}\)000000\>/0fb65424 \1/gc
57 |
58 | " 同上注意与上面的不同之处,这是 MOV 不是 MOVZX,目标操作数是 8 位
59 | com! K32T8ESPMOVBYTEAL %s/^8a8424 \(\x\{2}\)000000\>/8a4424 \1/gc
60 | com! K32T8ESPMOVBYTECL %s/^8a8c24 \(\x\{2}\)000000\>/8a4c24 \1/gc
61 | com! K32T8ESPMOVBYTEDL %s/^8a9424 \(\x\{2}\)000000\>/8a5424 \1/gc
62 | com! K32T8ESPMOVBYTEBL %s/^8a9c24 \(\x\{2}\)000000\>/8a5c24 \1/gc
63 |
64 | " 修改 OR R8, BYTE PTR [ESP+XXX]
65 | " 将32位操作数(XXX)改成8位
66 | " 同上注意与上面的不同之处,这是 MOV 不是 MOVZX,目标操作数是 8 位
67 | com! K32T8ESPORBYTEAL %s/^0a8424 \(\x\{2}\)000000\>/0a4424 \1/gc
68 | com! K32T8ESPORBYTECL %s/^0a8c24 \(\x\{2}\)000000\>/0a4c24 \1/gc
69 | com! K32T8ESPORBYTEDL %s/^0a9424 \(\x\{2}\)000000\>/0a5424 \1/gc
70 |
71 | " 对 [ESP+xxx] 或 [ESP-xxx] 中的 xxx 进行十六进制加减运算,并将替换掉原来的值
72 | " --- 这个用于操作分号左边的机器码
73 | com! -nargs=1 -range=% KADD ,s/^\%(0fb6\|8a\|0a\)\x\{2}24\s\zs\x\{2}\ze\>/\=AddHex(submatch(0),)/gc
74 | " --- 这个用于操作分号右边的注释
75 | com! -nargs=1 -range=% KADDForComment ,s/ESP\zs[+-]\x\{1,2}\ze/\=AddHexForComment(submatch(0),)/gc
76 |
77 | fun! s:AddHex( m, n ) "{{{
78 | let result = str2nr(a:m,16) + a:n
79 | if result < 0
80 | let result = and(result, 0xff)
81 | endif
82 | return printf("%02X", result ) " 只需 8-bit
83 | endfunction "}}}
84 |
85 | fun! s:AddHexForComment( m, n ) "{{{
86 | let result = str2nr(a:m,16) + a:n
87 | if result < 0
88 | " let result = and(result, 0xff)
89 | let result = -result
90 | return printf("-%02X", result ) " 只需 8-bit
91 | else
92 | return printf("+%02X", result ) " 只需 8-bit
93 | endif
94 | endfunction "}}}
95 |
96 |
--------------------------------------------------------------------------------
/gamedata/gamedata10.ahk:
--------------------------------------------------------------------------------
1 | ; 本作很坑爹的按 [ESP+XX] 来访问局部变量...
2 |
3 | class THKMC_GameData10 extends THKMC_GameDataBase {
4 | __New( ) {
5 | base.__New("th10", "东方风神录 1.00a", 0x46b23cd0, 487936)
6 | pd =
7 | (LTrim Comment
8 |
9 | 53 ; PUSH EBX
10 | B380 ; MOV BL,80
11 |
12 | 81C4 94000000 ; add esp, 94 ; 后面的地址总共 -0x90。使用 KADD 和 KADDForComment 命令
13 |
14 | 8A4C24 AA ; MOV CL,BYTE PTR SS:[ESP-56]
15 | 8A5424 AD ; MOV DL,BYTE PTR SS:[ESP-53]
16 | 8A4424 AC ; MOV AL,BYTE PTR SS:[ESP-54]
17 | 80E2 BF ; AND DL,0BF
18 | D0E8 ; SHR AL,1
19 | 0AD0 ; OR DL,AL
20 | D0EA ; SHR DL,1
21 | 8A4424 81 ; MOV AL,BYTE PTR SS:[ESP-7F]
22 | 80E1 9F ; AND CL,9F
23 | 0AD1 ; OR DL,CL
24 | 8A4C24 C8 ; MOV CL,BYTE PTR SS:[ESP-38]
25 | D0EA ; SHR DL,1
26 | 24 8F ; AND AL,8F
27 | 0AD0 ; OR DL,AL
28 | 0a4c24 48 ; OR CL,BYTE PTR SS:[ESP+48]
29 | 8a4424 50 ; MOV AL,BYTE PTR SS:[ESP+50]
30 | D0EA ; SHR DL,1
31 | 80E1 87 ; AND CL,87
32 | 0AD1 ; OR DL,CL
33 | 0A4424 D0 ; OR AL,BYTE PTR SS:[ESP-30]
34 | 8A4C24 CB ; MOV CL,BYTE PTR SS:[ESP-35]
35 | D0EA ; SHR DL,1
36 | 24 83 ; AND AL,83
37 | 0AD0 ; OR DL,AL
38 | 0a4c24 4B ; OR CL,BYTE PTR SS:[ESP+4B]
39 | 8A4424 CD ; MOV AL,BYTE PTR SS:[ESP-33]
40 | D0EA ; SHR DL,1
41 | 80E1 81 ; AND CL,81
42 | 0AD1 ; OR DL,CL
43 | 0a4424 4D ; OR AL,BYTE PTR SS:[ESP+4D]
44 | 8A4C24 93 ; MOV CL,BYTE PTR SS:[ESP-6D]
45 | D0EA ; SHR DL,1
46 | 20d8 ; and al,bl
47 | 0AD0 ; OR DL,AL
48 | 8A4424 A0 ; MOV AL,BYTE PTR SS:[ESP-60]
49 | 66:0FB6FA ; MOVZX DI,DL
50 | 20d9 ; and cl,bl
51 | 20d8 ; and al,bl
52 | 66:0FB6D1 ; MOVZX DX,CL
53 | 66:0FB6C8 ; MOVZX CX,AL
54 | 8A4424 9C ; MOV AL,BYTE PTR SS:[ESP-64]
55 | 20d8 ; and al,bl
56 | D1E2 ; SHL EDX,1
57 | 0BD1 ; OR EDX,ECX
58 | 66:0FB6C8 ; MOVZX CX,AL
59 | 8A4424 99 ; MOV AL,BYTE PTR SS:[ESP-67]
60 | D1E2 ; SHL EDX,1
61 | 0BD1 ; OR EDX,ECX
62 | 0a4424 47 ; OR AL,BYTE PTR SS:[ESP+47]
63 | 20d8 ; and al,bl
64 | 66:0FB6C8 ; MOVZX CX,AL
65 | 8A4424 9F ; MOV AL,BYTE PTR SS:[ESP-61]
66 | D1E2 ; SHL EDX,1
67 | 20d8 ; and al,bl
68 | 0BD1 ; OR EDX,ECX
69 | 66:0FB6C8 ; MOVZX CX,AL
70 | 8A4424 90 ; MOV AL,BYTE PTR SS:[ESP-70]
71 | D1E2 ; SHL EDX,1
72 | 20d8 ; and al,bl
73 | 0BD1 ; OR EDX,ECX
74 | 66:0FB6C8 ; MOVZX CX,AL
75 | 8A4424 9D ; MOV AL,BYTE PTR SS:[ESP-63]
76 | D1E2 ; SHL EDX,1
77 | 20d8 ; and al,bl
78 | 0BD1 ; OR EDX,ECX
79 | 66:0FB6C8 ; MOVZX CX,AL
80 | D1E2 ; SHL EDX,1
81 | 0BD1 ; OR EDX,ECX
82 | D1E2 ; SHL EDX,1
83 | 0BFA ; OR EDI,EDX
84 | 8A5424 C9 ; MOV DL,BYTE PTR SS:[ESP-37]
85 | 20da ; and dl,bl
86 | F6DA ; NEG DL
87 | 1BD2 ; SBB EDX,EDX
88 | 81E2 90000000 ; AND EDX,90
89 | 0BFA ; OR EDI,EDX
90 | 8A4424 CF ; MOV AL,BYTE PTR SS:[ESP-31]
91 | 8A4C24 C7 ; MOV CL,BYTE PTR SS:[ESP-39]
92 | 8A5424 D1 ; MOV DL,BYTE PTR SS:[ESP-2F]
93 |
94 | 81EC 94000000 ; sub esp, 94 ; 恢复ESP
95 | 5B ; pop ebx
96 | )
97 | ; OD中向上找 44a75b 处是 call dword ptr ds:[edx+24],这正是 "CALL IDirectInputDevice8::GetDeviceState()"
98 | ; 其参数有 lea ecx,dword ptr ss:[esp+10],于是 0x90-0x10=0x80
99 | this._setPatchData( 0x44a796, 0x44a88d, 0x400c00, 0x80, pd )
100 | this.addrPattern := "i)(?:\b0fb6|\b[80]a[45])[0-9a-f]+\s([0-9a-z]{2})\s"
101 | }
102 |
103 | ; 如果返回字符串 "OUT",则认为超出范围,跳过
104 | ; 这个类只需要处理一个字节即可
105 | str2KeymapValue( s ) {
106 | KeymapValue := (Pad0x(s)+0)
107 | ; 转换成8位有符号
108 | KeymapValue := KeymapValue > 0x7f ? -(0x100-KeymapValue) : KeymapValue
109 | KeymapValue += this.patchvaluefix
110 |
111 | if ( KeymapValue > 0xff || KeymapValue < 0 ) {
112 | return "OUT" ; 超出范围, 忽略
113 | }
114 |
115 | return KeymapValue
116 | }
117 |
118 | keymapValue2Str( k ) {
119 | k := (k - this.patchvaluefix) & 0xff ; 转换成8位无符号
120 | return PadLeadingZero( UnPad0x(ToHex( k )), 2 )
121 | }
122 | }
123 |
124 |
--------------------------------------------------------------------------------
/gamedata/gamedata11.ahk:
--------------------------------------------------------------------------------
1 | ; 本作很坑爹的按 [ESP+XX] 来访问局部变量...
2 |
3 |
4 | class THKMC_GameData11 extends THKMC_GameData10 {
5 | __New( ) {
6 | base.__New()
7 | this._setEXEInfo("th11", "东方地灵殿 1.00a", 0x489526fa, 688128)
8 | pd =
9 | (LTrim Comment
10 |
11 | 53 ; PUSH EBX ; 这里 PUSH 了,后面的 ESP+XX 要 +4
12 | BB 80000000 ; MOV EBX,80
13 |
14 | 21de ; AND ESI,EBX
15 | 21d8 ; and eax,ebx
16 |
17 | 81C4 88000000 ; add esp, 88 ; 后面的地址总共 -80-4=-84
18 |
19 | 0FB67424 C4 ; MOVZX ESI,BYTE PTR SS:[ESP-3C]
20 | 0FB64424 93 ; MOVZX EAX,BYTE PTR SS:[ESP-6D]
21 | 0FB64C24 A0 ; MOVZX ECX,BYTE PTR SS:[ESP-60]
22 | 0FB65424 9C ; MOVZX EDX,BYTE PTR SS:[ESP-64]
23 | 81E6 80000000 ; AND ESI,80
24 | 21d8 ; and eax,ebx
25 | 03F6 ; ADD ESI,ESI
26 | 03F6 ; ADD ESI,ESI
27 | 0BF0 ; OR ESI,EAX
28 | 0FB64424 99 ; MOVZX EAX,BYTE PTR SS:[ESP-67]
29 | 03F6 ; ADD ESI,ESI
30 | 21d9 ; and ecx,ebx
31 | 0BF1 ; OR ESI,ECX
32 | 0fb64c24 47 ; MOVZX ECX,BYTE PTR SS:[ESP+47]
33 | 0BC1 ; OR EAX,ECX
34 | 0FB64C24 9D ; MOVZX ECX,BYTE PTR SS:[ESP-63]
35 | 21d8 ; and eax,ebx
36 | 03F6 ; ADD ESI,ESI
37 | 21da ; and edx,ebx
38 | 0BF2 ; OR ESI,EDX
39 | 0FB65424 9F ; MOVZX EDX,BYTE PTR SS:[ESP-61]
40 | 03F6 ; ADD ESI,ESI
41 | 0BF0 ; OR ESI,EAX
42 | 0FB64424 90 ; MOVZX EAX,BYTE PTR SS:[ESP-70]
43 | 21d8 ; and eax,ebx
44 | 03F6 ; ADD ESI,ESI
45 | 21da ; and edx,ebx
46 | 0BF2 ; OR ESI,EDX
47 | 0FB65424 81 ; MOVZX EDX,BYTE PTR SS:[ESP-7F]
48 | 21d9 ; and ecx,ebx
49 | 03F6 ; ADD ESI,ESI
50 | 0BF0 ; OR ESI,EAX
51 | 0FB64424 AD ; MOVZX EAX,BYTE PTR SS:[ESP-53]
52 | 21d8 ; and eax,ebx
53 | C1E6 07 ; SHL ESI,7
54 | 0BF1 ; OR ESI,ECX
55 | 0FB64C24 AC ; MOVZX ECX,BYTE PTR SS:[ESP-54]
56 | D1E9 ; SHR ECX,1
57 | 0BC1 ; OR EAX,ECX
58 | 0FB64C24 C8 ; MOVZX ECX,BYTE PTR SS:[ESP-38]
59 | 21da ; and edx,ebx
60 | C1E8 02 ; SHR EAX,2
61 | 03F6 ; ADD ESI,ESI
62 | 0BF2 ; OR ESI,EDX
63 | 0FB65424 AA ; MOVZX EDX,BYTE PTR SS:[ESP-56]
64 | 21da ; and edx,ebx
65 | 0BC2 ; OR EAX,EDX
66 | 0fb65424 48 ; MOVZX EDX,BYTE PTR SS:[ESP+48]
67 | 0BCA ; OR ECX,EDX
68 | 0FB65424 D0 ; MOVZX EDX,BYTE PTR SS:[ESP-30]
69 | D1E8 ; SHR EAX,1
70 | 21d9 ; and ecx,ebx
71 | 0BC1 ; OR EAX,ECX
72 | 0fb64c24 50 ; MOVZX ECX,BYTE PTR SS:[ESP+50]
73 | 0BCA ; OR ECX,EDX
74 | 0fb65424 4B ; MOVZX EDX,BYTE PTR SS:[ESP+4B]
75 | D1E8 ; SHR EAX,1
76 | 21d9 ; and ecx,ebx
77 | 0BC1 ; OR EAX,ECX
78 | 0FB64C24 CB ; MOVZX ECX,BYTE PTR SS:[ESP-35]
79 | D1E8 ; SHR EAX,1
80 | 0BCA ; OR ECX,EDX
81 | 0FB65424 C9 ; MOVZX EDX,BYTE PTR SS:[ESP-37]
82 | 21d9 ; and ecx,ebx
83 | 0BC1 ; OR EAX,ECX
84 | 0fb64c24 4D ; MOVZX ECX,BYTE PTR SS:[ESP+4D]
85 | D1E8 ; SHR EAX,1
86 | 03F6 ; ADD ESI,ESI
87 | 0BF0 ; OR ESI,EAX
88 | 0FB64424 CD ; MOVZX EAX,BYTE PTR SS:[ESP-33]
89 | 0BC1 ; OR EAX,ECX
90 | 8A4C24 CF ; MOV CL,BYTE PTR SS:[ESP-31]
91 | 21d8 ; and eax,ebx
92 | 0BF0 ; OR ESI,EAX
93 | 80E2 80 ; AND DL,80
94 | 0FB6C2 ; MOVZX EAX,DL
95 | F7D8 ; NEG EAX
96 | 1BC0 ; SBB EAX,EAX
97 | 25 90000000 ; AND EAX,90
98 | 0BF0 ; OR ESI,EAX
99 | 80E1 80 ; AND CL,80
100 | 8A4424 C7 ; MOV AL,BYTE PTR SS:[ESP-39]
101 | 0FB6D1 ; MOVZX EDX,CL
102 | F7DA ; NEG EDX
103 | 1BD2 ; SBB EDX,EDX
104 | 24 80 ; AND AL,80
105 | 83E2 60 ; AND EDX,60
106 | 0FB6C8 ; MOVZX ECX,AL
107 | 0BF2 ; OR ESI,EDX
108 | 0FB65424 D1 ; MOVZX EDX,BYTE PTR SS:[ESP-2F]
109 |
110 | 81EC 88000000 ; sub esp, 88 ; 恢复ESP
111 | 5B ; pop ebx
112 | )
113 | this._setPatchData( 0x457883, 0x4579d1, 0x400c00, 0x80, pd )
114 | this.addrPattern := "i)(?:\b0fb6|\b8a4)[0-9a-f]+\s([0-9a-z]{2})\s"
115 | }
116 |
117 | doCustomPatch( pExeData ) {
118 | ; 要让上面的补丁有效,
119 | ; 需要打个补丁以修正总是无法正常初始化 DirectInput 的 BUG 。
120 |
121 | ; original data
122 | od =
123 | (LTrim Comment
124 | E8 F11A0100 ; call
125 | E8 BC2A0100 ; call
126 | 8125 10384C00 FFF3FFFF ; and dword ptr ds:[4C3810],FFFFF3FF
127 | B8 80324C00 ; mov eax,th11.4C3280
128 | E8 E8230000 ; call
129 | A1 10384C00 ; mov eax,dword ptr ds:[4C3810]
130 | 33D2 ; xor edx,edx
131 | 391D A0324C00 ; cmp dword ptr ds:[4C32A0],ebx
132 | BE E4584A00 ; mov esi,th11.4A58E4
133 | 0F95C2 ; setne dl
134 | 33C9 ; xor ecx,ecx
135 | C1E2 0A ; shl edx,A
136 | 33D0 ; xor edx,eax
137 | 81E2 00040000 ; and edx,400
138 | 33C2 ; xor eax,edx
139 | 391D A4324C00 ; cmp dword ptr ds:[4C32A4],ebx
140 | 0F95C1 ; setne cl
141 | C1E1 0B ; shl ecx,B
142 | 33C8 ; xor ecx,eax
143 | 81E1 00080000 ; and ecx,800
144 | 33C1 ; xor eax,ecx
145 | A3 10384C00 ; mov dword ptr ds:[4C3810],eax
146 | E8 243D0100 ; call
147 | 6A 20 ; push 20
148 | E8 A3A20100 ; call
149 | A3 84324C00 ; mov dword ptr ds:[4C3284],eax
150 | 3BC3 ; cmp eax,ebx
151 | 75 17 ; jne th11.445733
152 | 68 5C684900 ; push th11.49685C
153 | BF 40594A00 ; mov edi,th11.4A5940
154 | E8 C5330100 ; call
155 | 83C4 04 ; add esp,4
156 | E9 66040000 ; jmp th11.445B99
157 | 8B5C24 10 ; mov ebx,dword ptr ss:[esp+10]
158 | E8 A4130000 ; call
159 | 85C0 ; test eax,eax
160 | 0F85 53040000 ; jne th11.445B97
161 | )
162 |
163 | ; patch data
164 | pd =
165 | (LTrim Comment
166 | 8B5C24 10 ; mov ebx,dword ptr ss:[esp+10]
167 | E8 2D140000 ; call
168 | 85C0 ; test eax,eax
169 | 0F85 DC040000 ; jne th11.445B97
170 | E8 E01A0100 ; call
171 | E8 AB2A0100 ; call
172 | 8125 10384C00 FFF3FFFF ; and dword ptr ds:[4C3810],FFFFF3FF
173 | B8 80324C00 ; mov eax,th11.4C3280
174 | E8 D7230000 ; call
175 | A1 10384C00 ; mov eax,dword ptr ds:[4C3810]
176 | 33D2 ; xor edx,edx
177 | 3915 A0324C00 ; cmp dword ptr ds:[4C32A0],edx
178 | BE E4584A00 ; mov esi,th11.4A58E4
179 | 0F95C2 ; setne dl
180 | 33C9 ; xor ecx,ecx
181 | C1E2 0A ; shl edx,A
182 | 33D0 ; xor edx,eax
183 | 81E2 00040000 ; and edx,400
184 | 33C2 ; xor eax,edx
185 | 390D A4324C00 ; cmp dword ptr ds:[4C32A4],ecx
186 | 0F95C1 ; setne cl
187 | C1E1 0B ; shl ecx,B
188 | 33C8 ; xor ecx,eax
189 | 81E1 00080000 ; and ecx,800
190 | 33C1 ; xor eax,ecx
191 | A3 10384C00 ; mov dword ptr ds:[4C3810],eax
192 | E8 133D0100 ; call
193 | 6A 20 ; push 20
194 | E8 92A20100 ; call
195 | A3 84324C00 ; mov dword ptr ds:[4C3284],eax
196 | 3BC7 ; cmp eax,edi
197 | 75 17 ; jne th11.445744
198 | 68 5C684900 ; push th11.49685C
199 | BF 40594A00 ; mov edi,th11.4A5940
200 | E8 B4330100 ; call
201 | 83C4 04 ; add esp,4
202 | E9 55040000 ; jmp th11.445B99
203 | )
204 |
205 | addr := 0x44AAA
206 |
207 | AddLog("【提示】开始打补丁以修正地灵殿特有的无法正确初始化 DirectInput8 的 BUG 。")
208 | if ( compareHexToBinary( od, pExeData, addr ) = 0 ) {
209 | AddLog("【提示】用于修正BUG的补丁应用成功!")
210 | writeHexToBinary( pd, pExeData, addr )
211 | }
212 | else if ( compareHexToBinary( pd, pExeData, addr) = 0 ) {
213 | AddLog("【提示】无需打补丁。跳过。")
214 | }
215 | else {
216 | AddLog("【警告】无法打补丁。因为需要打补丁的数据已被第三方程序修改过。自定义键位可能无效。")
217 | }
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/gamedata/gamedata12.ahk:
--------------------------------------------------------------------------------
1 | ; 本作很坑爹的按 [ESP+XX] 来访问局部变量...
2 | ; 继承自 TH11
3 |
4 | class THKMC_GameData12 extends THKMC_GameData11 {
5 | __New( ) {
6 | base.__New()
7 | this._setEXEInfo("th12", "东方星莲船 1.00b", 0x4a95ffdc, 737280)
8 | ; 直接继承 th11 的 patchdata
9 | pd := this.patchdata
10 | this._setPatchData( 0x463093, 0x4631e1, 0x400c00, 0x80, pd )
11 | }
12 |
13 | ; 屏蔽 TH11 的 custom patch
14 | doCustomPatch( pExeData ) {
15 | }
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/gamedata/gamedata125.ahk:
--------------------------------------------------------------------------------
1 | ; 本作很坑爹的按 [ESP+XX] 来访问局部变量...
2 |
3 | class THKMC_GameData125 extends THKMC_GameData12 {
4 | __New( ) {
5 | base.__New()
6 | this._setEXEInfo("th125", "东方文花帖DS 1.00a", 0x4b916e39, 743424)
7 | pd =
8 | (LTrim Comment
9 |
10 | 57 ; PUSH EDI
11 | BF 80000000 ; MOV EDI,80
12 |
13 | 81C4 88000000 ; add esp, 88 ; 后面的地址总共 -80-4=-84
14 |
15 | 0FB67424 81 ; MOVZX ESI,BYTE PTR SS:[ESP-7F]
16 | 0FB64424 AE ; MOVZX EAX,BYTE PTR SS:[ESP-52]
17 | 0FB64C24 A6 ; MOVZX ECX,BYTE PTR SS:[ESP-5A]
18 | 0FB65424 C4 ; MOVZX EDX,BYTE PTR SS:[ESP-3C]
19 | 21fe ; and esi,edi
20 | 03F6 ; ADD ESI,ESI
21 | 21f9 ; and ecx,edi
22 | 21f8 ; and eax,edi
23 | 0BF0 ; OR ESI,EAX
24 | 0FB64424 93 ; MOVZX EAX,BYTE PTR SS:[ESP-6D]
25 | 03F6 ; ADD ESI,ESI
26 | 0BF1 ; OR ESI,ECX
27 | 0FB64C24 A0 ; MOVZX ECX,BYTE PTR SS:[ESP-60]
28 | 21fa ; and edx,edi
29 | 03F6 ; ADD ESI,ESI
30 | 03F6 ; ADD ESI,ESI
31 | 0BF2 ; OR ESI,EDX
32 | 0FB65424 9C ; MOVZX EDX,BYTE PTR SS:[ESP-64]
33 | 03F6 ; ADD ESI,ESI
34 | 03F6 ; ADD ESI,ESI
35 | 21f9 ; and ecx,edi
36 | 21f8 ; and eax,edi
37 | 0BF0 ; OR ESI,EAX
38 | 0FB64424 99 ; MOVZX EAX,BYTE PTR SS:[ESP-67]
39 | 21fa ; and edx,edi
40 | 03F6 ; ADD ESI,ESI
41 | 0BF1 ; OR ESI,ECX
42 | 0fb64c24 47 ; MOVZX ECX,BYTE PTR SS:[ESP+47]
43 | 0BC1 ; OR EAX,ECX
44 | 0FB64C24 AD ; MOVZX ECX,BYTE PTR SS:[ESP-53]
45 | 03F6 ; ADD ESI,ESI
46 | 0BF2 ; OR ESI,EDX
47 | 0FB65424 9F ; MOVZX EDX,BYTE PTR SS:[ESP-61]
48 | 21fa ; and edx,edi
49 | 21f8 ; and eax,edi
50 | 03F6 ; ADD ESI,ESI
51 | 0BF0 ; OR ESI,EAX
52 | 0FB64424 90 ; MOVZX EAX,BYTE PTR SS:[ESP-70]
53 | 21f9 ; and ecx,edi
54 | 03F6 ; ADD ESI,ESI
55 | 0BF2 ; OR ESI,EDX
56 | 0FB65424 AC ; MOVZX EDX,BYTE PTR SS:[ESP-54]
57 | D1EA ; SHR EDX,1
58 | 0BCA ; OR ECX,EDX
59 | 0FB65424 C8 ; MOVZX EDX,BYTE PTR SS:[ESP-38]
60 | 21f8 ; and eax,edi
61 | D1E9 ; SHR ECX,1
62 | 03F6 ; ADD ESI,ESI
63 | 0BF0 ; OR ESI,EAX
64 | 0FB64424 AA ; MOVZX EAX,BYTE PTR SS:[ESP-56]
65 | 21f8 ; and eax,edi
66 | 0BC8 ; OR ECX,EAX
67 | 0fb64424 48 ; MOVZX EAX,BYTE PTR SS:[ESP+48]
68 | 0BD0 ; OR EDX,EAX
69 | 0FB64424 D0 ; MOVZX EAX,BYTE PTR SS:[ESP-30]
70 | 21fa ; and edx,edi
71 | D1E9 ; SHR ECX,1
72 | 0BCA ; OR ECX,EDX
73 | 0fb65424 50 ; MOVZX EDX,BYTE PTR SS:[ESP+50]
74 | 0BD0 ; OR EDX,EAX
75 | 0fb64424 4B ; MOVZX EAX,BYTE PTR SS:[ESP+4B]
76 | 21fa ; and edx,edi
77 | D1E9 ; SHR ECX,1
78 | 0BCA ; OR ECX,EDX
79 | 0FB65424 CB ; MOVZX EDX,BYTE PTR SS:[ESP-35]
80 | 0BD0 ; OR EDX,EAX
81 | 0fb64424 4D ; MOVZX EAX,BYTE PTR SS:[ESP+4D]
82 | D1E9 ; SHR ECX,1
83 | 21fa ; and edx,edi
84 | 0BCA ; OR ECX,EDX
85 | 0FB65424 CD ; MOVZX EDX,BYTE PTR SS:[ESP-33]
86 | 0BD0 ; OR EDX,EAX
87 | D1E9 ; SHR ECX,1
88 | 21fa ; and edx,edi
89 | 0BCA ; OR ECX,EDX
90 | D1E9 ; SHR ECX,1
91 | C1E6 09 ; SHL ESI,9
92 | 0BF1 ; OR ESI,ECX
93 | 0FB64C24 C9 ; MOVZX ECX,BYTE PTR SS:[ESP-37]
94 | 80E1 80 ; AND CL,80
95 | 0FB6D1 ; MOVZX EDX,CL
96 | 8A4424 CF ; MOV AL,BYTE PTR SS:[ESP-31]
97 | F7DA ; NEG EDX
98 | 1BD2 ; SBB EDX,EDX
99 | 24 80 ; AND AL,80
100 | 83E2 48 ; AND EDX,48
101 | 0BF2 ; OR ESI,EDX
102 | 8A5424 C7 ; MOV DL,BYTE PTR SS:[ESP-39]
103 | 0FB6C8 ; MOVZX ECX,AL
104 | F7D9 ; NEG ECX
105 | 1BC9 ; SBB ECX,ECX
106 | 80E2 80 ; AND DL,80
107 | 83E1 30 ; AND ECX,30
108 | 0BF1 ; OR ESI,ECX
109 | 0FB64C24 D1 ; MOVZX ECX,BYTE PTR SS:[ESP-2F]
110 | 0FB6C2 ; MOVZX EAX,DL
111 | F7D8 ; NEG EAX
112 | 1BC0 ; SBB EAX,EAX
113 | 80E1 80 ; AND CL,80
114 | 83E0 28 ; AND EAX,28
115 | 0BF0 ; OR ESI,EAX
116 | 0FB64424 9D ; MOVZX EAX,BYTE PTR SS:[ESP-63]
117 |
118 |
119 | 81EC 88000000 ; sub esp, 88 ; 恢复ESP
120 | 5F ; pop edi
121 | )
122 | this._setPatchData( 0x46245b, 0x4625ca, 0x400c00, 0x80, pd )
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/gamedata/gamedata128.ahk:
--------------------------------------------------------------------------------
1 | class THKMC_GameData128 extends THKMC_GameDataBase {
2 | __New( ) {
3 | base.__New("th128", "妖精大战争 ~ 东方三月精 1.00a", 0x4C57A196, 752640)
4 | pd=
5 | (LTrim Comment
6 |
7 | 57 ; PUSH EDI
8 | BF 80000000 ; MOV EDI,80
9 |
10 | 0FB6B5 40FFFFFF ; MOVZX ESI,BYTE PTR SS:[EBP-C0]
11 | 0FB685 0FFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-F1]
12 | 0FB68D 1CFFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-E4]
13 | 0FB695 18FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-E8]
14 | 21fe ; and esi,edi
15 | 03F6 ; ADD ESI,ESI
16 | 21f9 ; and ecx,edi
17 | 03F6 ; ADD ESI,ESI
18 | 21f8 ; and eax,edi
19 | 0BF0 ; OR ESI,EAX
20 | 0FB685 15FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-EB]
21 | 03F6 ; ADD ESI,ESI
22 | 0BF1 ; OR ESI,ECX
23 | 0fb68d C3ffffff ; MOVZX ECX,BYTE PTR SS:[EBP-3D]
24 | 0BC1 ; OR EAX,ECX
25 | 0FB68D 2AFFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-D6]
26 | 21fa ; and edx,edi
27 | 03F6 ; ADD ESI,ESI
28 | 0BF2 ; OR ESI,EDX
29 | 0FB695 1BFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-E5]
30 | 03F6 ; ADD ESI,ESI
31 | 21f8 ; and eax,edi
32 | 0BF0 ; OR ESI,EAX
33 | 0FB685 0CFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-F4]
34 | 21fa ; and edx,edi
35 | 03F6 ; ADD ESI,ESI
36 | 0BF2 ; OR ESI,EDX
37 | 0FB695 19FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-E7]
38 | 0BCA ; OR ECX,EDX
39 | 0FB695 28FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-D8]
40 | 21f9 ; and ecx,edi
41 | 21f8 ; and eax,edi
42 | 03F6 ; ADD ESI,ESI
43 | 0BF0 ; OR ESI,EAX
44 | 0FB685 FDFEFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-103]
45 | C1E6 07 ; SHL ESI,7
46 | 0BF1 ; OR ESI,ECX
47 | 0FB68D 29FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-D7]
48 | 21f9 ; and ecx,edi
49 | 21f8 ; and eax,edi
50 | D1EA ; SHR EDX,1
51 | 0BCA ; OR ECX,EDX
52 | 0FB695 44FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-BC]
53 | C1E9 02 ; SHR ECX,2
54 | 03F6 ; ADD ESI,ESI
55 | 0BF0 ; OR ESI,EAX
56 | 0FB685 26FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-DA]
57 | 21f8 ; and eax,edi
58 | 0BC8 ; OR ECX,EAX
59 | 0fb685 C4ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-3C]
60 | 0BD0 ; OR EDX,EAX
61 | 0FB685 4CFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B4]
62 | D1E9 ; SHR ECX,1
63 | 21fa ; and edx,edi
64 | 0BCA ; OR ECX,EDX
65 | 0fb695 CCffffff ; MOVZX EDX,BYTE PTR SS:[EBP-34]
66 | D1E9 ; SHR ECX,1
67 | 0BD0 ; OR EDX,EAX
68 | 0fb685 C7ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-39]
69 | 21fa ; and edx,edi
70 | 0BCA ; OR ECX,EDX
71 | 0FB695 47FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-B9]
72 | D1E9 ; SHR ECX,1
73 | 0BD0 ; OR EDX,EAX
74 | 0FB685 45FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-BB]
75 | 21fa ; and edx,edi
76 | 0BCA ; OR ECX,EDX
77 | 0fb695 C9ffffff ; MOVZX EDX,BYTE PTR SS:[EBP-37]
78 | D1E9 ; SHR ECX,1
79 | 03F6 ; ADD ESI,ESI
80 | 0BF1 ; OR ESI,ECX
81 | 0FB68D 49FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B7]
82 | 0BCA ; OR ECX,EDX
83 | 21f9 ; and ecx,edi
84 | 0BF1 ; OR ESI,ECX
85 | 24 80 ; AND AL,80
86 | 0FB6C8 ; MOVZX ECX,AL
87 | F7D9 ; NEG ECX
88 | 1BC9 ; SBB ECX,ECX
89 | 81E1 90000000 ; AND ECX,90
90 | 0BF1 ; OR ESI,ECX
91 | 8A95 4BFFFFFF ; MOV DL,BYTE PTR SS:[EBP-B5]
92 | 8A8D 43FFFFFF ; MOV CL,BYTE PTR SS:[EBP-BD]
93 | 80E2 80 ; AND DL,80
94 | 0FB6C2 ; MOVZX EAX,DL
95 | F7D8 ; NEG EAX
96 | 1BC0 ; SBB EAX,EAX
97 | 80E1 80 ; AND CL,80
98 | 83E0 60 ; AND EAX,60
99 | 0FB6D1 ; MOVZX EDX,CL
100 | 0BF0 ; OR ESI,EAX
101 | 0FB685 4DFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B3]
102 |
103 | 5F ; pop edi
104 | )
105 |
106 | this._setPatchData( 0x469032, 0x46919e, 0x400c00, 0x104, pd )
107 | }
108 | }
109 |
110 |
--------------------------------------------------------------------------------
/gamedata/gamedata13.ahk:
--------------------------------------------------------------------------------
1 | class THKMC_GameData13 extends THKMC_GameDataBase {
2 | __New( ) {
3 | base.__New("th13", "东方神灵庙 1.00c", 0x4e4bc8a5, 790528)
4 | pd =
5 | (LTrim Comment
6 | 0FB6B5 40FFFFFF ; MOVZX ESI,BYTE PTR SS:[EBP-C0]
7 | 0FB68D 0FFFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-F1]
8 | 0FB695 1CFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-E4]
9 | 57 ; PUSH EDI
10 | BF 80000000 ; MOV EDI,80
11 | 21FE ; AND ESI,EDI
12 | 03F6 ; ADD ESI,ESI
13 | 03F6 ; ADD ESI,ESI
14 | 21f9 ; and ecx,edi
15 | 0BF1 ; OR ESI,ECX
16 | 0FB68D 18FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-E8]
17 | 03F6 ; ADD ESI,ESI
18 | 21fa ; and edx,edi
19 | 0BF2 ; OR ESI,EDX
20 | 0FB695 15FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-EB]
21 | 21f9 ; and ecx,edi
22 | 03F6 ; ADD ESI,ESI
23 | 0BF1 ; OR ESI,ECX
24 | 0fb68d C3ffffff ; MOVZX ECX,BYTE PTR SS:[EBP-3D]
25 | 0BD1 ; OR EDX,ECX
26 | 0FB68D 0CFFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-F4]
27 | 0FB685 2AFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-D6]
28 | 03F6 ; ADD ESI,ESI
29 | 21fa ; and edx,edi
30 | 0BF2 ; OR ESI,EDX
31 | 0FB695 1BFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-E5]
32 | 03F6 ; ADD ESI,ESI
33 | 21fa ; and edx,edi
34 | 0BF2 ; OR ESI,EDX
35 | 21f9 ; and ecx,edi
36 | 8BD0 ; MOV EDX,EAX
37 | 03F6 ; ADD ESI,ESI
38 | 0BF1 ; OR ESI,ECX
39 | 0FB68D 19FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-E7]
40 | C1E6 05 ; SHL ESI,5
41 | 21fa ; and edx,edi
42 | 0BF2 ; OR ESI,EDX
43 | 0FB695 FDFEFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-103]
44 | 21f8 ; and eax,edi
45 | 21f9 ; and ecx,edi
46 | 03F6 ; ADD ESI,ESI
47 | 03F6 ; ADD ESI,ESI
48 | 0BF1 ; OR ESI,ECX
49 | 0FB68D 28FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-D8]
50 | 0BF0 ; OR ESI,EAX
51 | 0FB685 29FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-D7]
52 | 21f8 ; and eax,edi
53 | D1E9 ; SHR ECX,1
54 | 0BC1 ; OR EAX,ECX
55 | 0FB68D 44FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-BC]
56 | 21fa ; and edx,edi
57 | C1E8 02 ; SHR EAX,2
58 | 03F6 ; ADD ESI,ESI
59 | 0BF2 ; OR ESI,EDX
60 | 0FB695 26FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-DA]
61 | 21fa ; and edx,edi
62 | 0BC2 ; OR EAX,EDX
63 | 0fb695 C4ffffff ; MOVZX EDX,BYTE PTR SS:[EBP-3C]
64 | 0BCA ; OR ECX,EDX
65 | 0FB695 4CFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-B4]
66 | D1E8 ; SHR EAX,1
67 | 21f9 ; and ecx,edi
68 | 0BC1 ; OR EAX,ECX
69 | 0fb68d CCffffff ; MOVZX ECX,BYTE PTR SS:[EBP-34]
70 | 0BCA ; OR ECX,EDX
71 | 0fb695 C7ffffff ; MOVZX EDX,BYTE PTR SS:[EBP-39]
72 | D1E8 ; SHR EAX,1
73 | 21f9 ; and ecx,edi
74 | 0BC1 ; OR EAX,ECX
75 | 0FB68D 47FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B9]
76 | D1E8 ; SHR EAX,1
77 | 0BCA ; OR ECX,EDX
78 | 0FB695 45FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-BB]
79 | 21f9 ; and ecx,edi
80 | 0BC1 ; OR EAX,ECX
81 | 0fb68d C9ffffff ; MOVZX ECX,BYTE PTR SS:[EBP-37]
82 | D1E8 ; SHR EAX,1
83 | 03F6 ; ADD ESI,ESI
84 | 0BF0 ; OR ESI,EAX
85 | 0FB685 49FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B7]
86 | 0BC1 ; OR EAX,ECX
87 | 21f8 ; and eax,edi
88 | 0BF0 ; OR ESI,EAX
89 | 8A8D 4BFFFFFF ; MOV CL,BYTE PTR SS:[EBP-B5]
90 | 80E2 80 ; AND DL,80
91 | 0FB6C2 ; MOVZX EAX,DL
92 | F7D8 ; NEG EAX
93 | 1BC0 ; SBB EAX,EAX
94 | 80E1 80 ; AND CL,80
95 | 25 90000000 ; AND EAX,90
96 | 0BF0 ; OR ESI,EAX
97 | 8A85 43FFFFFF ; MOV AL,BYTE PTR SS:[EBP-BD]
98 | 0FB6D1 ; MOVZX EDX,CL
99 | F7DA ; NEG EDX
100 | 1BD2 ; SBB EDX,EDX
101 | 24 80 ; AND AL,80
102 | 83E2 60 ; AND EDX,60
103 | 0FB6C8 ; MOVZX ECX,AL
104 | 0BF2 ; OR ESI,EDX
105 | 0FB695 4DFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-B3]
106 | 5F ; pop edi
107 | )
108 | this._setPatchData( 0x471845, 0x4719c6, 0x400c00, 0x104, pd )
109 | }
110 | }
111 |
112 |
--------------------------------------------------------------------------------
/gamedata/gamedata14.ahk:
--------------------------------------------------------------------------------
1 | class THKMC_GameData14 extends THKMC_GameDataBase {
2 | __New( ) {
3 | base.__New("th14", "东方辉针城 1.00b", 0x520dc559, 897536)
4 | pd =
5 | (LTrim Comment
6 |
7 | 0FB6B5 40FFFFFF ; MOVZX ESI,BYTE PTR SS:[EBP-C0]
8 | 0FB685 0FFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-F1]
9 |
10 | 57 ; PUSH EDI
11 | BF 80000000 ; MOV EDI,80
12 | 21f8 ; and eax,edi
13 | 21FE ; AND ESI,EDI
14 | C1E6 02 ; SHL ESI,2
15 | 0BF0 ; OR ESI,EAX
16 | 0FB685 1CFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E4]
17 | 21f8 ; and eax,edi
18 | 0FB68D 15FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-EB]
19 | 03F6 ; ADD ESI,ESI
20 | 0BF0 ; OR ESI,EAX
21 | 0FB685 18FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E8]
22 | 21f8 ; and eax,edi
23 | 03F6 ; ADD ESI,ESI
24 | 0BF0 ; OR ESI,EAX
25 | 0fb685 C3ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-3D]
26 | 0BC8 ; OR ECX,EAX
27 | 0FB685 1BFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E5]
28 | 0FB695 2AFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-D6]
29 | 21f8 ; and eax,edi
30 | 03F6 ; ADD ESI,ESI
31 | 21f9 ; and ecx,edi
32 | 0BF1 ; OR ESI,ECX
33 | 03F6 ; ADD ESI,ESI
34 | 0BF0 ; OR ESI,EAX
35 | 0FB685 0CFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-F4]
36 | 21f8 ; and eax,edi
37 | 03F6 ; ADD ESI,ESI
38 | 0BF0 ; OR ESI,EAX
39 | 8BC2 ; MOV EAX,EDX
40 | 21f8 ; and eax,edi
41 | C1E6 05 ; SHL ESI,5
42 | 0BF0 ; OR ESI,EAX
43 | 0FB685 19FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E7]
44 | 0BC2 ; OR EAX,EDX
45 | 0FB695 29FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-D7]
46 | 21f8 ; and eax,edi
47 | 0FB68D 44FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-BC]
48 | C1E6 02 ; SHL ESI,2
49 | 0BF0 ; OR ESI,EAX
50 | 0FB685 FDFEFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-103]
51 | 21f8 ; and eax,edi
52 | 03F6 ; ADD ESI,ESI
53 | 0BF0 ; OR ESI,EAX
54 | 0FB685 28FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-D8]
55 | 21fa ; and edx,edi
56 | D1E8 ; SHR EAX,1
57 | 0BD0 ; OR EDX,EAX
58 | 0FB685 26FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-DA]
59 | C1EA 02 ; SHR EDX,2
60 | 21f8 ; and eax,edi
61 | 0BD0 ; OR EDX,EAX
62 | 0fb685 C4ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-3C]
63 | 0BC8 ; OR ECX,EAX
64 | 0FB685 4CFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B4]
65 | 21f9 ; and ecx,edi
66 | D1EA ; SHR EDX,1
67 | 0BD1 ; OR EDX,ECX
68 | 0fb68d CCffffff ; MOVZX ECX,BYTE PTR SS:[EBP-34]
69 | 0BC8 ; OR ECX,EAX
70 | 0fb685 C7ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-39]
71 | 21f9 ; and ecx,edi
72 | D1EA ; SHR EDX,1
73 | 0BD1 ; OR EDX,ECX
74 | 0FB68D 47FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B9]
75 | 0BC8 ; OR ECX,EAX
76 | 0fb685 C9ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-37]
77 | 21f9 ; and ecx,edi
78 | D1EA ; SHR EDX,1
79 | 0BD1 ; OR EDX,ECX
80 | 0FB68D 49FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B7]
81 | 0BC8 ; OR ECX,EAX
82 | 0FB685 45FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-BB]
83 | 03F6 ; ADD ESI,ESI
84 | 24 80 ; AND AL,80
85 | D1EA ; SHR EDX,1
86 | 0BF2 ; OR ESI,EDX
87 | 21f9 ; and ecx,edi
88 | 0FB6C0 ; MOVZX EAX,AL
89 | 0BF1 ; OR ESI,ECX
90 | F7D8 ; NEG EAX
91 | 1BC0 ; SBB EAX,EAX
92 | 25 90000000 ; AND EAX,90
93 | 0BF0 ; OR ESI,EAX
94 | 0FB685 4BFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B5]
95 | 24 80 ; AND AL,80
96 | 0FB6C0 ; MOVZX EAX,AL
97 | F7D8 ; NEG EAX
98 | 1BC0 ; SBB EAX,EAX
99 | 83E0 60 ; AND EAX,60
100 | 0BF0 ; OR ESI,EAX
101 | 0FB685 43FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-BD]
102 | 24 80 ; AND AL,80
103 | 0FB6C0 ; MOVZX EAX,AL
104 | F7D8 ; NEG EAX
105 | 1BC0 ; SBB EAX,EAX
106 | 83E0 50 ; AND EAX,50
107 | 0BF0 ; OR ESI,EAX
108 | 0FB685 4DFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B3]
109 |
110 | 5F ; pop edi
111 | )
112 | this._setPatchData( 0x401ee7, 0x402063, 0x400c00, 0x104, pd )
113 | }
114 | }
115 |
116 |
--------------------------------------------------------------------------------
/gamedata/gamedata143.ahk:
--------------------------------------------------------------------------------
1 | ; 继承自 TH15
2 |
3 | class THKMC_GameData143 extends THKMC_GameData15 {
4 | __New( ) {
5 | base.__New()
6 | base._setEXEInfo("th143", "弹幕天邪鬼 1.00a", 0x53546435, 939008)
7 | ; 直接继承 th15 的 patchdata
8 | pd := this.patchdata
9 | this._setPatchData( 0x4021b7, 0x402339, 0x400c00, 0x104, pd )
10 | }
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/gamedata/gamedata15.ahk:
--------------------------------------------------------------------------------
1 | class THKMC_GameData15 extends THKMC_GameDataBase {
2 | __New( ) {
3 | ; base.__New("th15", "东方绀珠传 1.00a", 0x55BEB248, 951808) ; 去掉注释可直接支持 1.00a,但目前不可两者同时支持
4 | base.__New("th15", "东方绀珠传 1.00b", 0x56121EA7, 951808)
5 | pd =
6 | (LTrim Comment
7 | 0FB6B5 40FFFFFF ; MOVZX ESI,BYTE PTR SS:[EBP-C0]
8 | 0FB685 0FFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-F1]
9 | 57 ; PUSH EDI
10 | BF 80000000 ; MOV EDI,80
11 | 21FE ; AND ESI,EDI
12 | 21F8 ; AND EAX,EDI
13 | C1E6 02 ; SHL ESI,2
14 | 0BF0 ; OR ESI,EAX
15 | 0FB68D 15FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-EB]
16 | 0FB685 1CFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E4]
17 | 03F6 ; ADD ESI,ESI
18 | 21F8 ; AND EAX,EDI
19 | 0FB695 2AFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-D6]
20 | 0BF0 ; OR ESI,EAX
21 | 0FB685 18FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E8]
22 | 21F8 ; AND EAX,EDI
23 | 03F6 ; ADD ESI,ESI
24 | 0BF0 ; OR ESI,EAX
25 | 0FB685 C3FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-3D]
26 | 0BC8 ; OR ECX,EAX
27 | 03F6 ; ADD ESI,ESI
28 | 0FB685 1BFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E5]
29 | 21F9 ; AND ECX,EDI
30 | 0BF1 ; OR ESI,ECX
31 | 21F8 ; AND EAX,EDI
32 | 03F6 ; ADD ESI,ESI
33 | 0FB68D 44FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-BC]
34 | 0BF0 ; OR ESI,EAX
35 | 0FB685 0CFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-F4]
36 | 21F8 ; AND EAX,EDI
37 | 03F6 ; ADD ESI,ESI
38 | 0BF0 ; OR ESI,EAX
39 | 8BC2 ; MOV EAX,EDX
40 | 21F8 ; AND EAX,EDI
41 | C1E6 05 ; SHL ESI,5
42 | 0BF0 ; OR ESI,EAX
43 | 21FA ; AND EDX,EDI
44 | 0FB685 19FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E7]
45 | 21F8 ; AND EAX,EDI
46 | C1E6 02 ; SHL ESI,2
47 | 0BF0 ; OR ESI,EAX
48 | 0FB685 FDFEFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-103]
49 | 0BF2 ; OR ESI,EDX
50 | 21F8 ; AND EAX,EDI
51 | 0FB695 29FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-D7]
52 | 03F6 ; ADD ESI,ESI
53 | 0BF0 ; OR ESI,EAX
54 | 21FA ; AND EDX,EDI
55 | 0FB685 28FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-D8]
56 | 03F6 ; ADD ESI,ESI
57 | D1E8 ; SHR EAX,1
58 | 0BD0 ; OR EDX,EAX
59 | 0FB685 26FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-DA]
60 | C1EA 02 ; SHR EDX,2
61 | 21F8 ; AND EAX,EDI
62 | 0BD0 ; OR EDX,EAX
63 | 0FB685 C4FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-3C]
64 | 0BC8 ; OR ECX,EAX
65 | D1EA ; SHR EDX,1
66 | 0FB685 4CFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B4]
67 | 21F9 ; AND ECX,EDI
68 | 0BD1 ; OR EDX,ECX
69 | 0FB68D CCFFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-34]
70 | 0BC8 ; OR ECX,EAX
71 | D1EA ; SHR EDX,1
72 | 0FB685 C7FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-39]
73 | 21F9 ; AND ECX,EDI
74 | 0BD1 ; OR EDX,ECX
75 | 0FB68D 47FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B9]
76 | 0BC8 ; OR ECX,EAX
77 | D1EA ; SHR EDX,1
78 | 0FB685 C9FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-37]
79 | 21F9 ; AND ECX,EDI
80 | 0BD1 ; OR EDX,ECX
81 | 0FB68D 49FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B7]
82 | 0BC8 ; OR ECX,EAX
83 | D1EA ; SHR EDX,1
84 | 0FB685 45FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-BB]
85 | 0BF2 ; OR ESI,EDX
86 | 21F9 ; AND ECX,EDI
87 | 0BF1 ; OR ESI,ECX
88 | 24 80 ; AND AL,80
89 | 0FB6C0 ; MOVZX EAX,AL
90 | F7D8 ; NEG EAX
91 | 1BC0 ; SBB EAX,EAX
92 | 25 90000000 ; AND EAX,90
93 | 0BF0 ; OR ESI,EAX
94 | 0FB685 4BFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B5]
95 | 24 80 ; AND AL,80
96 | 0FB6C0 ; MOVZX EAX,AL
97 | F7D8 ; NEG EAX
98 | 1BC0 ; SBB EAX,EAX
99 | 83E0 60 ; AND EAX,60
100 | 0BF0 ; OR ESI,EAX
101 | 0FB685 43FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-BD]
102 | 24 80 ; AND AL,80
103 | 0FB6C0 ; MOVZX EAX,AL
104 | F7D8 ; NEG EAX
105 | 1BC0 ; SBB EAX,EAX
106 | 83E0 50 ; AND EAX,50
107 | 0BF0 ; OR ESI,EAX
108 | 0FB685 4DFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B3]
109 | 5F ; pop edi
110 | )
111 | this._setPatchData( 0x402167, 0x4022e9, 0x400c00, 0x104, pd )
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/gamedata/gamedata16.ahk:
--------------------------------------------------------------------------------
1 | ; 继承自 TH15
2 |
3 | class THKMC_GameData16 extends THKMC_GameData15 {
4 | __New( ) {
5 | base.__New()
6 | base._setEXEInfo("th16", "东方天空璋 1.00a", 0x597F974D, 683520)
7 | ; 直接继承 th15 的 patchdata
8 | pd := this.patchdata
9 | this._setPatchData( 0x401f67, 0x4020e9, 0x400c00, 0x104, pd )
10 | }
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/gamedata/gamedata165.ahk:
--------------------------------------------------------------------------------
1 | ; 继承自 TH15
2 |
3 | class THKMC_GameData165 extends THKMC_GameData15 {
4 | __New( ) {
5 | base.__New()
6 | base._setEXEInfo("th165", "秘封噩梦日记 1.00a", 0x5B5FB2EF, 740352)
7 | ; 直接继承 th15 的 patchdata
8 | pd := this.patchdata
9 | this._setPatchData( 0x401bd7, 0x401d59, 0x400c00, 0x104, pd )
10 | }
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/gamedata/gamedata17.ahk:
--------------------------------------------------------------------------------
1 | class THKMC_GameData17 extends THKMC_GameDataBase {
2 | __New( ) {
3 | base.__New("th17", "东方鬼形兽 1.00b", 0x5D4E902C, 747520)
4 | pd =
5 | (LTrim Comment
6 | 57 ; PUSH EDI
7 | 87E5 ; xchg ebp,esp
8 | 81c5 10010000 ; add ebp, 110
9 | 0FB6B5 40FFFFFF ; MOVZX ESI,BYTE PTR SS:[EBP-C0]
10 | 0FB685 0FFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-F1]
11 | BF 80000000 ; MOV EDI,80
12 | 21fe ; and esi,edi
13 | 21f8 ; and eax,edi
14 | C1E6 02 ; SHL ESI,2
15 | 0BF0 ; OR ESI,EAX
16 | 0FB68D 15FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-EB]
17 | 0FB685 1CFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E4]
18 | 03F6 ; ADD ESI,ESI
19 | 21f8 ; and eax,edi
20 | 0FB695 29FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-D7]
21 | 0BF0 ; OR ESI,EAX
22 | 21fa ; and edx,edi
23 | 0FB685 18FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E8]
24 | 03F6 ; ADD ESI,ESI
25 | 21f8 ; and eax,edi
26 | 0BF0 ; OR ESI,EAX
27 | 0fb685 C3ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-3D]
28 | 0BC8 ; OR ECX,EAX
29 | 03F6 ; ADD ESI,ESI
30 | 0FB685 1BFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E5]
31 | 21f9 ; and ecx,edi
32 | 0BF1 ; OR ESI,ECX
33 | 21f8 ; and eax,edi
34 | 0FB68D 19FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-E7]
35 | 03F6 ; ADD ESI,ESI
36 | 0BF0 ; OR ESI,EAX
37 | 0FB685 0CFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-F4]
38 | 21f8 ; and eax,edi
39 | 03F6 ; ADD ESI,ESI
40 | 0BF0 ; OR ESI,EAX
41 | 0FB685 2AFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-D6]
42 | 0BC8 ; OR ECX,EAX
43 | C1E6 07 ; SHL ESI,7
44 | 0FB685 FDFEFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-103]
45 | 21f9 ; and ecx,edi
46 | 0BF1 ; OR ESI,ECX
47 | 21f8 ; and eax,edi
48 | 0FB68D 44FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-BC]
49 | 03F6 ; ADD ESI,ESI
50 | 0BF0 ; OR ESI,EAX
51 | 0FB685 28FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-D8]
52 | D1E8 ; SHR EAX,1
53 | 03F6 ; ADD ESI,ESI
54 | 0BD0 ; OR EDX,EAX
55 | 0FB685 26FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-DA]
56 | 21f8 ; and eax,edi
57 | C1EA 02 ; SHR EDX,2
58 | 0BD0 ; OR EDX,EAX
59 | 0fb685 C4ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-3C]
60 | 0BC8 ; OR ECX,EAX
61 | D1EA ; SHR EDX,1
62 | 0FB685 4CFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B4]
63 | 21f9 ; and ecx,edi
64 | 0BD1 ; OR EDX,ECX
65 | 0fb68d CCffffff ; MOVZX ECX,BYTE PTR SS:[EBP-34]
66 | 0BC8 ; OR ECX,EAX
67 | D1EA ; SHR EDX,1
68 | 0fb685 C7ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-39]
69 | 21f9 ; and ecx,edi
70 | 0BD1 ; OR EDX,ECX
71 | 0FB68D 47FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B9]
72 | 0BC8 ; OR ECX,EAX
73 | D1EA ; SHR EDX,1
74 | 0fb685 C9ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-37]
75 | 21f9 ; and ecx,edi
76 | 0BD1 ; OR EDX,ECX
77 | 0FB68D 49FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B7]
78 | 0BC8 ; OR ECX,EAX
79 | D1EA ; SHR EDX,1
80 | 0FB685 45FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-BB]
81 | 0BF2 ; OR ESI,EDX
82 | 24 80 ; AND AL,80
83 | 21f9 ; and ecx,edi
84 | ; 0FB6C0 ; MOVZX EAX,AL
85 | 0BF1 ; OR ESI,ECX
86 | F7D8 ; NEG EAX
87 | 1BC0 ; SBB EAX,EAX
88 | 25 90000000 ; AND EAX,90
89 | 0BF0 ; OR ESI,EAX
90 | 0FB685 4BFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B5]
91 | 24 80 ; AND AL,80
92 | ; 0FB6C0 ; MOVZX EAX,AL
93 | F7D8 ; NEG EAX
94 | 1BC0 ; SBB EAX,EAX
95 | 83E0 60 ; AND EAX,60
96 | 0BF0 ; OR ESI,EAX
97 | 0FB685 43FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-BD]
98 | 24 80 ; AND AL,80
99 | ; 0FB6C0 ; MOVZX EAX,AL
100 | F7D8 ; NEG EAX
101 | 1BC0 ; SBB EAX,EAX
102 | 83E0 50 ; AND EAX,50
103 | 0BF0 ; OR ESI,EAX
104 | 0FB685 4DFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B3]
105 | 81ed 10010000 ; sub ebp, 110
106 | 87E5 ; xchg ebp,esp
107 | 5F ; POP EDI
108 | )
109 | this._setPatchData( 0x401c8f, 0x401dea, 0x400c00, 0x104, pd )
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/gamedata/gamedata17tr.ahk:
--------------------------------------------------------------------------------
1 | class THKMC_GameData17tr extends THKMC_GameDataBase {
2 | __New( ) {
3 | base.__New("th17tr", "东方鬼形兽 体验版 0.01a", 0x5CCCE6FC, 729600)
4 | pd =
5 | (LTrim Comment
6 | 0FB6B5 40FFFFFF ; MOVZX ESI,BYTE PTR SS:[EBP-C0]
7 | 0FB685 0FFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-F1]
8 | 57 ; PUSH EDI
9 | BF 80000000 ; MOV EDI,80
10 | 21fe ; and esi,edi
11 | 21f8 ; and eax,edi
12 | C1E6 02 ; SHL ESI,2
13 | 0BF0 ; OR ESI,EAX
14 | 0FB68D 15FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-EB]
15 | 0FB685 1CFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E4]
16 | 03F6 ; ADD ESI,ESI
17 | 21f8 ; and eax,edi
18 | 0FB695 29FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-D7]
19 | 0BF0 ; OR ESI,EAX
20 | 21fa ; and edx,edi
21 | 0FB685 18FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E8]
22 | 03F6 ; ADD ESI,ESI
23 | 21f8 ; and eax,edi
24 | 0BF0 ; OR ESI,EAX
25 | 0fb685 C3ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-3D]
26 | 0BC8 ; OR ECX,EAX
27 | 03F6 ; ADD ESI,ESI
28 | 0FB685 1BFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E5]
29 | 21f9 ; and ecx,edi
30 | 0BF1 ; OR ESI,ECX
31 | 21f8 ; and eax,edi
32 | 0FB68D 19FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-E7]
33 | 03F6 ; ADD ESI,ESI
34 | 0BF0 ; OR ESI,EAX
35 | 0FB685 0CFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-F4]
36 | 21f8 ; and eax,edi
37 | 03F6 ; ADD ESI,ESI
38 | 0BF0 ; OR ESI,EAX
39 | 0FB685 2AFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-D6]
40 | 0BC8 ; OR ECX,EAX
41 | C1E6 07 ; SHL ESI,7
42 | 0FB685 FDFEFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-103]
43 | 21f9 ; and ecx,edi
44 | 0BF1 ; OR ESI,ECX
45 | 21f8 ; and eax,edi
46 | 0FB68D 44FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-BC]
47 | 03F6 ; ADD ESI,ESI
48 | 0BF0 ; OR ESI,EAX
49 | 0FB685 28FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-D8]
50 | D1E8 ; SHR EAX,1
51 | 03F6 ; ADD ESI,ESI
52 | 0BD0 ; OR EDX,EAX
53 | 0FB685 26FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-DA]
54 | 21f8 ; and eax,edi
55 | C1EA 02 ; SHR EDX,2
56 | 0BD0 ; OR EDX,EAX
57 | 0fb685 C4ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-3C]
58 | 0BC8 ; OR ECX,EAX
59 | D1EA ; SHR EDX,1
60 | 0FB685 4CFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B4]
61 | 21f9 ; and ecx,edi
62 | 0BD1 ; OR EDX,ECX
63 | 0fb68d CCffffff ; MOVZX ECX,BYTE PTR SS:[EBP-34]
64 | 0BC8 ; OR ECX,EAX
65 | D1EA ; SHR EDX,1
66 | 0fb685 C7ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-39]
67 | 21f9 ; and ecx,edi
68 | 0BD1 ; OR EDX,ECX
69 | 0FB68D 47FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B9]
70 | 0BC8 ; OR ECX,EAX
71 | D1EA ; SHR EDX,1
72 | 0fb685 C9ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-37]
73 | 21f9 ; and ecx,edi
74 | 0BD1 ; OR EDX,ECX
75 | 0FB68D 49FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B7]
76 | 0BC8 ; OR ECX,EAX
77 | D1EA ; SHR EDX,1
78 | 0FB685 45FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-BB]
79 | 0BF2 ; OR ESI,EDX
80 | 24 80 ; AND AL,80
81 | 21f9 ; and ecx,edi
82 | 0FB6C0 ; MOVZX EAX,AL
83 | 0BF1 ; OR ESI,ECX
84 | F7D8 ; NEG EAX
85 | 1BC0 ; SBB EAX,EAX
86 | 25 90000000 ; AND EAX,90
87 | 0BF0 ; OR ESI,EAX
88 | 0FB685 4BFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B5]
89 | 24 80 ; AND AL,80
90 | 0FB6C0 ; MOVZX EAX,AL
91 | F7D8 ; NEG EAX
92 | 1BC0 ; SBB EAX,EAX
93 | 83E0 60 ; AND EAX,60
94 | 0BF0 ; OR ESI,EAX
95 | 0FB685 43FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-BD]
96 | 24 80 ; AND AL,80
97 | 0FB6C0 ; MOVZX EAX,AL
98 | F7D8 ; NEG EAX
99 | 1BC0 ; SBB EAX,EAX
100 | 83E0 50 ; AND EAX,50
101 | 0BF0 ; OR ESI,EAX
102 | 0FB685 4DFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B3]
103 | 5F ; POP EDI
104 | )
105 | this._setPatchData( 0x401bd6, 0x401d47, 0x400c00, 0x104, pd )
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/gamedata/gamedata6.ahk:
--------------------------------------------------------------------------------
1 | class THKMC_GameData6 extends THKMC_GameDataBase {
2 | __New( ) {
3 | base.__New("th6", "东方红魔乡 1.02h", 0x3DE9A0FB, 512000)
4 | pd =
5 | (LTrim Comment
6 | 8B85 C0FFFFFF ; MOV EAX,DWORD PTR SS:[EBP-40]
7 | 56 ; push esi
8 | 57 ; push edi
9 | BE FF000000 ; mov esi, 0ff
10 | BF 80000000 ; mov edi, 80
11 | 21f0 ; and eax,esi
12 | 21f8 ; and eax,edi
13 | F7D8 ; NEG EAX
14 | 1BC0 ; SBB EAX,EAX
15 | 83E0 10 ; AND EAX,10
16 | 8B8D F4FEFFFF ; MOV ECX,DWORD PTR SS:[EBP-10C]
17 | 81E1 FFFF0000 ; AND ECX,0FFFF
18 | 0BC8 ; OR ECX,EAX
19 | 66:898D F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],CX
20 | 8B95 C8FFFFFF ; MOV EDX,DWORD PTR SS:[EBP-38]
21 | 21f2 ; and edx,esi
22 | 21fa ; and edx,edi
23 | F7DA ; NEG EDX
24 | 1BD2 ; SBB EDX,EDX
25 | 83E2 20 ; AND EDX,20
26 | 8B85 F4FEFFFF ; MOV EAX,DWORD PTR SS:[EBP-10C]
27 | 25 FFFF0000 ; AND EAX,0FFFF
28 | 0BC2 ; OR EAX,EDX
29 | 66:8985 F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],AX
30 | 8B8D C3FFFFFF ; MOV ECX,DWORD PTR SS:[EBP-3D]
31 | 21f1 ; and ecx,esi
32 | 21f9 ; and ecx,edi
33 | F7D9 ; NEG ECX
34 | 1BC9 ; SBB ECX,ECX
35 | 83E1 40 ; AND ECX,40
36 | 8B95 F4FEFFFF ; MOV EDX,DWORD PTR SS:[EBP-10C]
37 | 81E2 FFFF0000 ; AND EDX,0FFFF
38 | 0BD1 ; OR EDX,ECX
39 | 66:8995 F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],DX
40 | 8B85 C5FFFFFF ; MOV EAX,DWORD PTR SS:[EBP-3B]
41 | 21f0 ; and eax,esi
42 | 21f8 ; and eax,edi
43 | F7D8 ; NEG EAX
44 | 1BC0 ; SBB EAX,EAX
45 | 21f8 ; and eax,edi
46 | 8B8D F4FEFFFF ; MOV ECX,DWORD PTR SS:[EBP-10C]
47 | 81E1 FFFF0000 ; AND ECX,0FFFF
48 | 0BC8 ; OR ECX,EAX
49 | 66:898D F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],CX
50 | 8B95 40FFFFFF ; MOV EDX,DWORD PTR SS:[EBP-C0]
51 | 21f2 ; and edx,esi
52 | 21fa ; and edx,edi
53 | F7DA ; NEG EDX
54 | 1BD2 ; SBB EDX,EDX
55 | 83E2 10 ; AND EDX,10
56 | 8B85 F4FEFFFF ; MOV EAX,DWORD PTR SS:[EBP-10C]
57 | 25 FFFF0000 ; AND EAX,0FFFF
58 | 0BC2 ; OR EAX,EDX
59 | 66:8985 F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],AX
60 | 8B8D 48FFFFFF ; MOV ECX,DWORD PTR SS:[EBP-B8]
61 | 21f1 ; and ecx,esi
62 | 21f9 ; and ecx,edi
63 | F7D9 ; NEG ECX
64 | 1BC9 ; SBB ECX,ECX
65 | 83E1 20 ; AND ECX,20
66 | 8B95 F4FEFFFF ; MOV EDX,DWORD PTR SS:[EBP-10C]
67 | 81E2 FFFF0000 ; AND EDX,0FFFF
68 | 0BD1 ; OR EDX,ECX
69 | 66:8995 F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],DX
70 | 8B85 43FFFFFF ; MOV EAX,DWORD PTR SS:[EBP-BD]
71 | 21f0 ; and eax,esi
72 | 21f8 ; and eax,edi
73 | F7D8 ; NEG EAX
74 | 1BC0 ; SBB EAX,EAX
75 | 83E0 40 ; AND EAX,40
76 | 8B8D F4FEFFFF ; MOV ECX,DWORD PTR SS:[EBP-10C]
77 | 81E1 FFFF0000 ; AND ECX,0FFFF
78 | 0BC8 ; OR ECX,EAX
79 | 66:898D F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],CX
80 | 8B95 45FFFFFF ; MOV EDX,DWORD PTR SS:[EBP-BB]
81 | 21f2 ; and edx,esi
82 | 21fa ; and edx,edi
83 | F7DA ; NEG EDX
84 | 1BD2 ; SBB EDX,EDX
85 | 21fa ; and edx,edi
86 | 8B85 F4FEFFFF ; MOV EAX,DWORD PTR SS:[EBP-10C]
87 | 25 FFFF0000 ; AND EAX,0FFFF
88 | 0BC2 ; OR EAX,EDX
89 | 66:8985 F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],AX
90 | 8B8D 3FFFFFFF ; MOV ECX,DWORD PTR SS:[EBP-C1]
91 | 21f1 ; and ecx,esi
92 | 21f9 ; and ecx,edi
93 | F7D9 ; NEG ECX
94 | 1BC9 ; SBB ECX,ECX
95 | 83E1 50 ; AND ECX,50
96 | 8B95 F4FEFFFF ; MOV EDX,DWORD PTR SS:[EBP-10C]
97 | 81E2 FFFF0000 ; AND EDX,0FFFF
98 | 0BD1 ; OR EDX,ECX
99 | 66:8995 F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],DX
100 | 8B85 41FFFFFF ; MOV EAX,DWORD PTR SS:[EBP-BF]
101 | 21f0 ; and eax,esi
102 | 21f8 ; and eax,edi
103 | F7D8 ; NEG EAX
104 | 1BC0 ; SBB EAX,EAX
105 | 25 90000000 ; AND EAX,90
106 | 8B8D F4FEFFFF ; MOV ECX,DWORD PTR SS:[EBP-10C]
107 | 81E1 FFFF0000 ; AND ECX,0FFFF
108 | 0BC8 ; OR ECX,EAX
109 | 66:898D F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],CX
110 | 8B95 47FFFFFF ; MOV EDX,DWORD PTR SS:[EBP-B9]
111 | 21f2 ; and edx,esi
112 | 21fa ; and edx,edi
113 | F7DA ; NEG EDX
114 | 1BD2 ; SBB EDX,EDX
115 | 83E2 60 ; AND EDX,60
116 | 8B85 F4FEFFFF ; MOV EAX,DWORD PTR SS:[EBP-10C]
117 | 25 FFFF0000 ; AND EAX,0FFFF
118 | 0BC2 ; OR EAX,EDX
119 | 66:8985 F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],AX
120 | 8B8D 49FFFFFF ; MOV ECX,DWORD PTR SS:[EBP-B7]
121 | 21f1 ; and ecx,esi
122 | 21f9 ; and ecx,edi
123 | F7D9 ; NEG ECX
124 | 1BC9 ; SBB ECX,ECX
125 | 81E1 A0000000 ; AND ECX,0A0
126 | 8B95 F4FEFFFF ; MOV EDX,DWORD PTR SS:[EBP-10C]
127 | 81E2 FFFF0000 ; AND EDX,0FFFF
128 | 0BD1 ; OR EDX,ECX
129 | 66:8995 F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],DX
130 | 8B85 BFFFFFFF ; MOV EAX,DWORD PTR SS:[EBP-41]
131 | 21f0 ; and eax,esi
132 | 21f8 ; and eax,edi
133 | F7D8 ; NEG EAX
134 | 1BC0 ; SBB EAX,EAX
135 | 25 00080000 ; AND EAX,800
136 | 8B8D F4FEFFFF ; MOV ECX,DWORD PTR SS:[EBP-10C]
137 | 81E1 FFFF0000 ; AND ECX,0FFFF
138 | 0BC8 ; OR ECX,EAX
139 | 66:898D F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],CX
140 | 8B95 24FFFFFF ; MOV EDX,DWORD PTR SS:[EBP-DC]
141 | 21f2 ; and edx,esi
142 | 21fa ; and edx,edi
143 | F7DA ; NEG EDX
144 | 1BD2 ; SBB EDX,EDX
145 | F7DA ; NEG EDX
146 | 8B85 F4FEFFFF ; MOV EAX,DWORD PTR SS:[EBP-10C]
147 | 25 FFFF0000 ; AND EAX,0FFFF
148 | 0BC2 ; OR EAX,EDX
149 | 66:8985 F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],AX
150 | 8B8D 25FFFFFF ; MOV ECX,DWORD PTR SS:[EBP-DB]
151 | 21f1 ; and ecx,esi
152 | 21f9 ; and ecx,edi
153 | F7D9 ; NEG ECX
154 | 1BC9 ; SBB ECX,ECX
155 | 83E1 02 ; AND ECX,2
156 | 8B95 F4FEFFFF ; MOV EDX,DWORD PTR SS:[EBP-10C]
157 | 81E2 FFFF0000 ; AND EDX,0FFFF
158 | 0BD1 ; OR EDX,ECX
159 | 66:8995 F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],DX
160 | 8B85 22FFFFFF ; MOV EAX,DWORD PTR SS:[EBP-DE]
161 | 21f0 ; and eax,esi
162 | 21f8 ; and eax,edi
163 | F7D8 ; NEG EAX
164 | 1BC0 ; SBB EAX,EAX
165 | 83E0 04 ; AND EAX,4
166 | 8B8D F4FEFFFF ; MOV ECX,DWORD PTR SS:[EBP-10C]
167 | 81E1 FFFF0000 ; AND ECX,0FFFF
168 | 0BC8 ; OR ECX,EAX
169 | 66:898D F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],CX
170 | 8B95 2EFFFFFF ; MOV EDX,DWORD PTR SS:[EBP-D2]
171 | 21f2 ; and edx,esi
172 | 21fa ; and edx,edi
173 | F7DA ; NEG EDX
174 | 1BD2 ; SBB EDX,EDX
175 | 83E2 04 ; AND EDX,4
176 | 8B85 F4FEFFFF ; MOV EAX,DWORD PTR SS:[EBP-10C]
177 | 25 FFFF0000 ; AND EAX,0FFFF
178 | 0BC2 ; OR EAX,EDX
179 | 66:8985 F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],AX
180 | 8B8D F9FEFFFF ; MOV ECX,DWORD PTR SS:[EBP-107]
181 | 21f1 ; and ecx,esi
182 | 21f9 ; and ecx,edi
183 | F7D9 ; NEG ECX
184 | 1BC9 ; SBB ECX,ECX
185 | 83E1 08 ; AND ECX,8
186 | 8B95 F4FEFFFF ; MOV EDX,DWORD PTR SS:[EBP-10C]
187 | 81E2 FFFF0000 ; AND EDX,0FFFF
188 | 0BD1 ; OR EDX,ECX
189 | 66:8995 F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],DX
190 | 8B85 15FFFFFF ; MOV EAX,DWORD PTR SS:[EBP-EB]
191 | 21f0 ; and eax,esi
192 | 21f8 ; and eax,edi
193 | F7D8 ; NEG EAX
194 | 1BC0 ; SBB EAX,EAX
195 | 25 00010000 ; AND EAX,100
196 | 8B8D F4FEFFFF ; MOV ECX,DWORD PTR SS:[EBP-10C]
197 | 81E1 FFFF0000 ; AND ECX,0FFFF
198 | 0BC8 ; OR ECX,EAX
199 | 66:898D F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],CX
200 | 8B95 95FFFFFF ; MOV EDX,DWORD PTR SS:[EBP-6B]
201 | 21f2 ; and edx,esi
202 | 21fa ; and edx,edi
203 | F7DA ; NEG EDX
204 | 1BD2 ; SBB EDX,EDX
205 | 81E2 00010000 ; AND EDX,100
206 | 8B85 F4FEFFFF ; MOV EAX,DWORD PTR SS:[EBP-10C]
207 | 25 FFFF0000 ; AND EAX,0FFFF
208 | 0BC2 ; OR EAX,EDX
209 | 66:8985 F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],AX
210 | 8B8D 08FFFFFF ; MOV ECX,DWORD PTR SS:[EBP-F8]
211 | 21f1 ; and ecx,esi
212 | 21f9 ; and ecx,edi
213 | F7D9 ; NEG ECX
214 | 1BC9 ; SBB ECX,ECX
215 | 81E1 00020000 ; AND ECX,200
216 | 8B95 F4FEFFFF ; MOV EDX,DWORD PTR SS:[EBP-10C]
217 | 81E2 FFFF0000 ; AND EDX,0FFFF
218 | 0BD1 ; OR EDX,ECX
219 | 66:8995 F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],DX
220 | 8B85 17FFFFFF ; MOV EAX,DWORD PTR SS:[EBP-E9]
221 | 21f0 ; and eax,esi
222 | 21f8 ; and eax,edi
223 | F7D8 ; NEG EAX
224 | 1BC0 ; SBB EAX,EAX
225 | 25 00040000 ; AND EAX,400
226 | 8B8D F4FEFFFF ; MOV ECX,DWORD PTR SS:[EBP-10C]
227 | 81E1 FFFF0000 ; AND ECX,0FFFF
228 | 0BC8 ; OR ECX,EAX
229 | 66:898D F4FEFFFF ; MOV WORD PTR SS:[EBP-10C],CX
230 | 8B95 14FFFFFF ; MOV EDX,DWORD PTR SS:[EBP-EC]
231 | 21f2 ; and edx,esi
232 | 21fa ; and edx,edi
233 | F7DA ; NEG EDX
234 | 1BD2 ; SBB EDX,EDX
235 | 81E2 00100000 ; AND EDX,1000
236 | 8B85 F4FEFFFF ; MOV EAX,DWORD PTR SS:[EBP-10C]
237 | 25 FFFF0000 ; AND EAX,0FFFF
238 | 5F ; pop edi
239 | 5E ; pop esi
240 | )
241 | this._setPatchData( 0x41dc85, 0x41e08c, 0x400000, 0x108, pd )
242 | this.addrPattern := "i)\b8b[0-9a-f]+\s([0-9a-z]{2}f[ef]ffff)\s"
243 | }
244 | }
245 |
--------------------------------------------------------------------------------
/gamedata/gamedata6cn.ahk:
--------------------------------------------------------------------------------
1 | class THKMC_GameData6cn extends THKMC_GameData6 {
2 | __New( ) {
3 | base.__New()
4 | base._setEXEInfo("th6", "东方红魔乡 渔场汉化版", 0x3D6F56A4, 506880)
5 | ; 直接继承 th6 的 patchdata
6 | pd := this.patchdata
7 | this._setPatchData( 0x41d825, 0x41dc2f, 0x400c00, 0x108, pd )
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/gamedata/gamedata7.ahk:
--------------------------------------------------------------------------------
1 | class THKMC_GameData7 extends THKMC_GameDataBase {
2 | __New( ) {
3 | base.__New("th7", "东方妖妖梦 1.00b", 0x3F983F81, 650752)
4 | pd =
5 | (LTrim Comment
6 | 0fb685 C8ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-38]
7 | 57 ; push edi
8 | BF 80000000 ; mov edi, 80
9 | 21f8 ; and eax,edi
10 | F7D8 ; NEG EAX
11 | 1BC0 ; SBB EAX,EAX
12 | 83E0 10 ; AND EAX,10
13 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
14 | 0BC8 ; OR ECX,EAX
15 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
16 | 0fb695 D0ffffff ; MOVZX EDX,BYTE PTR SS:[EBP-30]
17 | 21fa ; and edx,edi
18 | F7DA ; NEG EDX
19 | 1BD2 ; SBB EDX,EDX
20 | 83E2 20 ; AND EDX,20
21 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
22 | 0BC2 ; OR EAX,EDX
23 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
24 | 0fb68d CBffffff ; MOVZX ECX,BYTE PTR SS:[EBP-35]
25 | 21f9 ; and ecx,edi
26 | F7D9 ; NEG ECX
27 | 1BC9 ; SBB ECX,ECX
28 | 83E1 40 ; AND ECX,40
29 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
30 | 0BD1 ; OR EDX,ECX
31 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
32 | 0fb685 CDffffff ; MOVZX EAX,BYTE PTR SS:[EBP-33]
33 | 21f8 ; and eax,edi
34 | F7D8 ; NEG EAX
35 | 1BC0 ; SBB EAX,EAX
36 | 21f8 ; and eax,edi
37 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
38 | 0BC8 ; OR ECX,EAX
39 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
40 | 0FB695 48FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-B8]
41 | 21fa ; and edx,edi
42 | F7DA ; NEG EDX
43 | 1BD2 ; SBB EDX,EDX
44 | 83E2 10 ; AND EDX,10
45 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
46 | 0BC2 ; OR EAX,EDX
47 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
48 | 0FB68D 50FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B0]
49 | 21f9 ; and ecx,edi
50 | F7D9 ; NEG ECX
51 | 1BC9 ; SBB ECX,ECX
52 | 83E1 20 ; AND ECX,20
53 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
54 | 0BD1 ; OR EDX,ECX
55 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
56 | 0FB685 4BFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B5]
57 | 21f8 ; and eax,edi
58 | F7D8 ; NEG EAX
59 | 1BC0 ; SBB EAX,EAX
60 | 83E0 40 ; AND EAX,40
61 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
62 | 0BC8 ; OR ECX,EAX
63 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
64 | 0FB695 4DFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-B3]
65 | 21fa ; and edx,edi
66 | F7DA ; NEG EDX
67 | 1BD2 ; SBB EDX,EDX
68 | 21fa ; and edx,edi
69 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
70 | 0BC2 ; OR EAX,EDX
71 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
72 | 0FB68D 47FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B9]
73 | 21f9 ; and ecx,edi
74 | F7D9 ; NEG ECX
75 | 1BC9 ; SBB ECX,ECX
76 | 83E1 50 ; AND ECX,50
77 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
78 | 0BD1 ; OR EDX,ECX
79 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
80 | 0FB685 49FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B7]
81 | 21f8 ; and eax,edi
82 | F7D8 ; NEG EAX
83 | 1BC0 ; SBB EAX,EAX
84 | 25 90000000 ; AND EAX,90
85 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
86 | 0BC8 ; OR ECX,EAX
87 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
88 | 0FB695 4FFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-B1]
89 | 21fa ; and edx,edi
90 | F7DA ; NEG EDX
91 | 1BD2 ; SBB EDX,EDX
92 | 83E2 60 ; AND EDX,60
93 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
94 | 0BC2 ; OR EAX,EDX
95 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
96 | 0FB68D 51FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-AF]
97 | 21f9 ; and ecx,edi
98 | F7D9 ; NEG ECX
99 | 1BC9 ; SBB ECX,ECX
100 | 81E1 A0000000 ; AND ECX,0A0
101 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
102 | 0BD1 ; OR EDX,ECX
103 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
104 | 0fb685 C7ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-39]
105 | 21f8 ; and eax,edi
106 | F7D8 ; NEG EAX
107 | 1BC0 ; SBB EAX,EAX
108 | 25 00080000 ; AND EAX,800
109 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
110 | 0BC8 ; OR ECX,EAX
111 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
112 | 0FB695 20FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-E0]
113 | 21fa ; and edx,edi
114 | F7DA ; NEG EDX
115 | 1BD2 ; SBB EDX,EDX
116 | 81E2 00200000 ; AND EDX,2000
117 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
118 | 0BC2 ; OR EAX,EDX
119 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
120 | 0FB68D 2CFFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-D4]
121 | 21f9 ; and ecx,edi
122 | F7D9 ; NEG ECX
123 | 1BC9 ; SBB ECX,ECX
124 | F7D9 ; NEG ECX
125 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
126 | 0BD1 ; OR EDX,ECX
127 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
128 | 0FB685 2DFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-D3]
129 | 21f8 ; and eax,edi
130 | F7D8 ; NEG EAX
131 | 1BC0 ; SBB EAX,EAX
132 | 83E0 02 ; AND EAX,2
133 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
134 | 0BC8 ; OR ECX,EAX
135 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
136 | 0FB695 2AFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-D6]
137 | 21fa ; and edx,edi
138 | F7DA ; NEG EDX
139 | 1BD2 ; SBB EDX,EDX
140 | 83E2 04 ; AND EDX,4
141 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
142 | 0BC2 ; OR EAX,EDX
143 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
144 | 0FB68D 36FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-CA]
145 | 21f9 ; and ecx,edi
146 | F7D9 ; NEG ECX
147 | 1BC9 ; SBB ECX,ECX
148 | 83E1 04 ; AND ECX,4
149 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
150 | 0BD1 ; OR EDX,ECX
151 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
152 | 0FB685 01FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-FF]
153 | 21f8 ; and eax,edi
154 | F7D8 ; NEG EAX
155 | 1BC0 ; SBB EAX,EAX
156 | 83E0 08 ; AND EAX,8
157 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
158 | 0BC8 ; OR ECX,EAX
159 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
160 | 0FB695 1DFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-E3]
161 | 21fa ; and edx,edi
162 | F7DA ; NEG EDX
163 | 1BD2 ; SBB EDX,EDX
164 | 81E2 00010000 ; AND EDX,100
165 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
166 | 0BC2 ; OR EAX,EDX
167 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
168 | 0fb68d 9Dffffff ; MOVZX ECX,BYTE PTR SS:[EBP-63]
169 | 21f9 ; and ecx,edi
170 | F7D9 ; NEG ECX
171 | 1BC9 ; SBB ECX,ECX
172 | 81E1 00010000 ; AND ECX,100
173 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
174 | 0BD1 ; OR EDX,ECX
175 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
176 | 0FB685 10FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-F0]
177 | 21f8 ; and eax,edi
178 | F7D8 ; NEG EAX
179 | 1BC0 ; SBB EAX,EAX
180 | 25 00020000 ; AND EAX,200
181 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
182 | 0BC8 ; OR ECX,EAX
183 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
184 | 0FB695 1FFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-E1]
185 | 21fa ; and edx,edi
186 | F7DA ; NEG EDX
187 | 1BD2 ; SBB EDX,EDX
188 | 81E2 00040000 ; AND EDX,400
189 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
190 | 0BC2 ; OR EAX,EDX
191 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
192 | 0FB68D 1CFFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-E4]
193 | 21f9 ; and ecx,edi
194 | F7D9 ; NEG ECX
195 | 1BC9 ; SBB ECX,ECX
196 | 81E1 00100000 ; AND ECX,1000
197 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
198 | 0BD1 ; OR EDX,ECX
199 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
200 | 0FB685 13FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-ED]
201 | 21f8 ; and eax,edi
202 | 5F ; pop edi
203 | )
204 | this._setPatchData( 0x430f2a, 0x431298, 0x400C00, 0x100, pd )
205 | }
206 |
207 | doCustomPatch( pExeData ) {
208 | ; 检查是否中文版
209 | result := compareHexToBinary( "EB56909090", pExeData, 0x37A97 )
210 | if ( result = 0 ) {
211 | AddLog("【提示】这是渔场汉化版")
212 | }
213 | else {
214 | ; 若不是中文版,则去掉自校验
215 | writeHexToBinary( "C705145C570000EE0900C705105C57005C44C5AEC3", pExeData, 0x352c0 )
216 | }
217 | }
218 | }
219 |
--------------------------------------------------------------------------------
/gamedata/gamedata8.ahk:
--------------------------------------------------------------------------------
1 | class THKMC_GameData8 extends THKMC_GameDataBase {
2 | __New( ) {
3 | base.__New("th8", "东方永夜抄 1.00d", 0x414daf4c, 840704)
4 | pd =
5 | (LTrim Comment
6 | 53 ; PUSH EBX
7 | BB 80000000 ; MOV EBX,80
8 |
9 | 0fb695 C8ffffff ; MOVZX EDX,BYTE PTR SS:[EBP-38]
10 | 21da ; and edx,ebx
11 | F7DA ; NEG EDX
12 | 1BD2 ; SBB EDX,EDX
13 | 83E2 10 ; AND EDX,10
14 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
15 | 0BC2 ; OR EAX,EDX
16 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
17 | 0fb68d D0ffffff ; MOVZX ECX,BYTE PTR SS:[EBP-30]
18 | 21d9 ; and ecx,ebx
19 | F7D9 ; NEG ECX
20 | 1BC9 ; SBB ECX,ECX
21 | 83E1 20 ; AND ECX,20
22 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
23 | 0BD1 ; OR EDX,ECX
24 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
25 | 0fb685 CBffffff ; MOVZX EAX,BYTE PTR SS:[EBP-35]
26 | 21d8 ; and eax,ebx
27 | F7D8 ; NEG EAX
28 | 1BC0 ; SBB EAX,EAX
29 | 83E0 40 ; AND EAX,40
30 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
31 | 0BC8 ; OR ECX,EAX
32 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
33 | 0fb695 CDffffff ; MOVZX EDX,BYTE PTR SS:[EBP-33]
34 | 21da ; and edx,ebx
35 | F7DA ; NEG EDX
36 | 1BD2 ; SBB EDX,EDX
37 | 21da ; and edx,ebx
38 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
39 | 0BC2 ; OR EAX,EDX
40 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
41 | 0FB68D 48FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B8]
42 | 21d9 ; and ecx,ebx
43 | F7D9 ; NEG ECX
44 | 1BC9 ; SBB ECX,ECX
45 | 83E1 10 ; AND ECX,10
46 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
47 | 0BD1 ; OR EDX,ECX
48 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
49 | 0FB685 50FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B0]
50 | 21d8 ; and eax,ebx
51 | F7D8 ; NEG EAX
52 | 1BC0 ; SBB EAX,EAX
53 | 83E0 20 ; AND EAX,20
54 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
55 | 0BC8 ; OR ECX,EAX
56 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
57 | 0FB695 4BFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-B5]
58 | 21da ; and edx,ebx
59 | F7DA ; NEG EDX
60 | 1BD2 ; SBB EDX,EDX
61 | 83E2 40 ; AND EDX,40
62 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
63 | 0BC2 ; OR EAX,EDX
64 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
65 | 0FB68D 4DFFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B3]
66 | 21d9 ; and ecx,ebx
67 | F7D9 ; NEG ECX
68 | 1BC9 ; SBB ECX,ECX
69 | 21d9 ; and ecx,ebx
70 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
71 | 0BD1 ; OR EDX,ECX
72 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
73 | 0FB685 47FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B9]
74 | 21d8 ; and eax,ebx
75 | F7D8 ; NEG EAX
76 | 1BC0 ; SBB EAX,EAX
77 | 83E0 50 ; AND EAX,50
78 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
79 | 0BC8 ; OR ECX,EAX
80 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
81 | 0FB695 49FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-B7]
82 | 21da ; and edx,ebx
83 | F7DA ; NEG EDX
84 | 1BD2 ; SBB EDX,EDX
85 | 81E2 90000000 ; AND EDX,90
86 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
87 | 0BC2 ; OR EAX,EDX
88 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
89 | 0FB68D 4FFFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B1]
90 | 21d9 ; and ecx,ebx
91 | F7D9 ; NEG ECX
92 | 1BC9 ; SBB ECX,ECX
93 | 83E1 60 ; AND ECX,60
94 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
95 | 0BD1 ; OR EDX,ECX
96 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
97 | 0FB685 51FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-AF]
98 | 21d8 ; and eax,ebx
99 | F7D8 ; NEG EAX
100 | 1BC0 ; SBB EAX,EAX
101 | 25 A0000000 ; AND EAX,0A0
102 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
103 | 0BC8 ; OR ECX,EAX
104 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
105 | 0fb695 C7ffffff ; MOVZX EDX,BYTE PTR SS:[EBP-39]
106 | 21da ; and edx,ebx
107 | F7DA ; NEG EDX
108 | 1BD2 ; SBB EDX,EDX
109 | 81E2 00080000 ; AND EDX,800
110 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
111 | 0BC2 ; OR EAX,EDX
112 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
113 | 0FB68D 19FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-E7]
114 | 21d9 ; and ecx,ebx
115 | F7D9 ; NEG ECX
116 | 1BC9 ; SBB ECX,ECX
117 | 81E1 00080000 ; AND ECX,800
118 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
119 | 0BD1 ; OR EDX,ECX
120 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
121 | 0FB685 20FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E0]
122 | 21d8 ; and eax,ebx
123 | F7D8 ; NEG EAX
124 | 1BC0 ; SBB EAX,EAX
125 | 25 00200000 ; AND EAX,2000
126 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
127 | 0BC8 ; OR ECX,EAX
128 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
129 | 0FB695 2CFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-D4]
130 | 21da ; and edx,ebx
131 | F7DA ; NEG EDX
132 | 1BD2 ; SBB EDX,EDX
133 | F7DA ; NEG EDX
134 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
135 | 0BC2 ; OR EAX,EDX
136 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
137 | 0FB68D 2DFFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-D3]
138 | 21d9 ; and ecx,ebx
139 | F7D9 ; NEG ECX
140 | 1BC9 ; SBB ECX,ECX
141 | 83E1 02 ; AND ECX,2
142 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
143 | 0BD1 ; OR EDX,ECX
144 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
145 | 0FB685 2AFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-D6]
146 | 21d8 ; and eax,ebx
147 | F7D8 ; NEG EAX
148 | 1BC0 ; SBB EAX,EAX
149 | 83E0 04 ; AND EAX,4
150 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
151 | 0BC8 ; OR ECX,EAX
152 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
153 | 0FB695 36FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-CA]
154 | 21da ; and edx,ebx
155 | F7DA ; NEG EDX
156 | 1BD2 ; SBB EDX,EDX
157 | 83E2 04 ; AND EDX,4
158 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
159 | 0BC2 ; OR EAX,EDX
160 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
161 | 0FB68D 01FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-FF]
162 | 21d9 ; and ecx,ebx
163 | F7D9 ; NEG ECX
164 | 1BC9 ; SBB ECX,ECX
165 | 83E1 08 ; AND ECX,8
166 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
167 | 0BD1 ; OR EDX,ECX
168 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
169 | 0FB685 1DFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E3]
170 | 21d8 ; and eax,ebx
171 | F7D8 ; NEG EAX
172 | 1BC0 ; SBB EAX,EAX
173 | 25 00010000 ; AND EAX,100
174 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
175 | 0BC8 ; OR ECX,EAX
176 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
177 | 0fb695 9Dffffff ; MOVZX EDX,BYTE PTR SS:[EBP-63]
178 | 21da ; and edx,ebx
179 | F7DA ; NEG EDX
180 | 1BD2 ; SBB EDX,EDX
181 | 81E2 00010000 ; AND EDX,100
182 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
183 | 0BC2 ; OR EAX,EDX
184 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
185 | 0FB68D 10FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-F0]
186 | 21d9 ; and ecx,ebx
187 | F7D9 ; NEG ECX
188 | 1BC9 ; SBB ECX,ECX
189 | 81E1 00020000 ; AND ECX,200
190 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
191 | 0BD1 ; OR EDX,ECX
192 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
193 | 0FB685 1FFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E1]
194 | 21d8 ; and eax,ebx
195 | F7D8 ; NEG EAX
196 | 1BC0 ; SBB EAX,EAX
197 | 25 00040000 ; AND EAX,400
198 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
199 | 0BC8 ; OR ECX,EAX
200 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
201 | 0FB695 1CFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-E4]
202 | 21da ; and edx,ebx
203 | F7DA ; NEG EDX
204 | 1BD2 ; SBB EDX,EDX
205 | 81E2 00100000 ; AND EDX,1000
206 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
207 | 0BC2 ; OR EAX,EDX
208 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
209 | 0FB68D 13FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-ED]
210 |
211 | 5B ; pop ebx
212 | )
213 | this._setPatchData( 0x43dd9e, 0x43e12e, 0x400200, 0x100, pd )
214 | }
215 |
216 | doCustomPatch( pExeData ) {
217 | ; 检查是否中文版
218 | result := compareHexToBinary( "EB5A909090", pExeData, 0x45fd2 )
219 | if ( result = 0 ) {
220 | AddLog("【提示】这是渔场汉化版")
221 | }
222 | else {
223 | ; 若不是中文版,则去掉自校验
224 | writeHexToBinary( "C785E8FEFFFF B96168A2 C785F0FEFFFF00D40C00", pExeData, 0x435ef )
225 | }
226 | }
227 | }
228 |
--------------------------------------------------------------------------------
/gamedata/gamedata95.ahk:
--------------------------------------------------------------------------------
1 | class THKMC_GameData95 extends THKMC_GameDataBase {
2 | __New( ) {
3 | base.__New("th95", "东方文花帖 1.02a", 0x43c68d3f, 696832)
4 |
5 |
6 | pd =
7 | (LTrim Comment
8 |
9 | 53 ; PUSH EBX
10 | BB 80000000 ; MOV EBX,80
11 |
12 | 0fb68d C8ffffff ; MOVZX ECX,BYTE PTR SS:[EBP-38]
13 | 21d9 ; and ecx,ebx
14 | F7D9 ; NEG ECX
15 | 1BC9 ; SBB ECX,ECX
16 | 83E1 10 ; AND ECX,10
17 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
18 | 0BD1 ; OR EDX,ECX
19 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
20 | 0fb685 D0ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-30]
21 | 21d8 ; and eax,ebx
22 | F7D8 ; NEG EAX
23 | 1BC0 ; SBB EAX,EAX
24 | 83E0 20 ; AND EAX,20
25 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
26 | 0BC8 ; OR ECX,EAX
27 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
28 | 0fb695 CBffffff ; MOVZX EDX,BYTE PTR SS:[EBP-35]
29 | 21da ; and edx,ebx
30 | F7DA ; NEG EDX
31 | 1BD2 ; SBB EDX,EDX
32 | 83E2 40 ; AND EDX,40
33 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
34 | 0BC2 ; OR EAX,EDX
35 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
36 | 0fb68d CDffffff ; MOVZX ECX,BYTE PTR SS:[EBP-33]
37 | 21d9 ; and ecx,ebx
38 | F7D9 ; NEG ECX
39 | 1BC9 ; SBB ECX,ECX
40 | 21d9 ; and ecx,ebx
41 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
42 | 0BD1 ; OR EDX,ECX
43 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
44 | 0FB685 2CFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-D4]
45 | 21d8 ; and eax,ebx
46 | F7D8 ; NEG EAX
47 | 1BC0 ; SBB EAX,EAX
48 | 83E0 02 ; AND EAX,2
49 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
50 | 0BC8 ; OR ECX,EAX
51 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
52 | 0FB695 2DFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-D3]
53 | 21da ; and edx,ebx
54 | F7DA ; NEG EDX
55 | 1BD2 ; SBB EDX,EDX
56 | F7DA ; NEG EDX
57 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
58 | 0BC2 ; OR EAX,EDX
59 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
60 | 0FB68D 2AFFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-D6]
61 | 21d9 ; and ecx,ebx
62 | F7D9 ; NEG ECX
63 | 1BC9 ; SBB ECX,ECX
64 | 83E1 05 ; AND ECX,5
65 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
66 | 0BD1 ; OR EDX,ECX
67 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
68 | 0FB685 48FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B8]
69 | 21d8 ; and eax,ebx
70 | F7D8 ; NEG EAX
71 | 1BC0 ; SBB EAX,EAX
72 | 83E0 10 ; AND EAX,10
73 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
74 | 0BC8 ; OR ECX,EAX
75 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
76 | 0FB695 50FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-B0]
77 | 21da ; and edx,ebx
78 | F7DA ; NEG EDX
79 | 1BD2 ; SBB EDX,EDX
80 | 83E2 20 ; AND EDX,20
81 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
82 | 0BC2 ; OR EAX,EDX
83 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
84 | 0FB68D 4BFFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B5]
85 | 21d9 ; and ecx,ebx
86 | F7D9 ; NEG ECX
87 | 1BC9 ; SBB ECX,ECX
88 | 83E1 40 ; AND ECX,40
89 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
90 | 0BD1 ; OR EDX,ECX
91 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
92 | 0FB685 4DFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B3]
93 | 21d8 ; and eax,ebx
94 | F7D8 ; NEG EAX
95 | 1BC0 ; SBB EAX,EAX
96 | 21d8 ; and eax,ebx
97 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
98 | 0BC8 ; OR ECX,EAX
99 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
100 | 0FB695 47FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-B9]
101 | 21da ; and edx,ebx
102 | F7DA ; NEG EDX
103 | 1BD2 ; SBB EDX,EDX
104 | 83E2 50 ; AND EDX,50
105 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
106 | 0BC2 ; OR EAX,EDX
107 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
108 | 0FB68D 49FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-B7]
109 | 21d9 ; and ecx,ebx
110 | F7D9 ; NEG ECX
111 | 1BC9 ; SBB ECX,ECX
112 | 81E1 90000000 ; AND ECX,90
113 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
114 | 0BD1 ; OR EDX,ECX
115 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
116 | 0FB685 4FFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-B1]
117 | 21d8 ; and eax,ebx
118 | F7D8 ; NEG EAX
119 | 1BC0 ; SBB EAX,EAX
120 | 83E0 60 ; AND EAX,60
121 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
122 | 0BC8 ; OR ECX,EAX
123 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
124 | 0FB695 51FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-AF]
125 | 21da ; and edx,ebx
126 | F7DA ; NEG EDX
127 | 1BD2 ; SBB EDX,EDX
128 | 81E2 A0000000 ; AND EDX,0A0
129 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
130 | 0BC2 ; OR EAX,EDX
131 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
132 | 0FB685 1DFFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-E3]
133 | 21d8 ; and eax,ebx
134 | F7D8 ; NEG EAX
135 | 1BC0 ; SBB EAX,EAX
136 | 25 00010000 ; AND EAX,100
137 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
138 | 0BC8 ; OR ECX,EAX
139 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
140 | 0FB695 01FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-FF]
141 | 21da ; and edx,ebx
142 | F7DA ; NEG EDX
143 | 1BD2 ; SBB EDX,EDX
144 | 83E2 08 ; AND EDX,8
145 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
146 | 0BC2 ; OR EAX,EDX
147 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
148 | 0FB68D 1CFFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-E4]
149 | 21d9 ; and ecx,ebx
150 | F7D9 ; NEG ECX
151 | 1BC9 ; SBB ECX,ECX
152 | 81E1 00100000 ; AND ECX,1000
153 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
154 | 0BD1 ; OR EDX,ECX
155 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
156 | 0fb685 C7ffffff ; MOVZX EAX,BYTE PTR SS:[EBP-39]
157 | 21d8 ; and eax,ebx
158 | F7D8 ; NEG EAX
159 | 1BC0 ; SBB EAX,EAX
160 | 25 00080000 ; AND EAX,800
161 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
162 | 0BC8 ; OR ECX,EAX
163 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
164 | 0FB695 19FFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-E7]
165 | 21da ; and edx,ebx
166 | F7DA ; NEG EDX
167 | 1BD2 ; SBB EDX,EDX
168 | 81E2 00080000 ; AND EDX,800
169 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
170 | 0BC2 ; OR EAX,EDX
171 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
172 | 0FB68D 20FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-E0]
173 | 21d9 ; and ecx,ebx
174 | F7D9 ; NEG ECX
175 | 1BC9 ; SBB ECX,ECX
176 | 81E1 00200000 ; AND ECX,2000
177 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
178 | 0BD1 ; OR EDX,ECX
179 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
180 | 0FB685 10FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-F0]
181 | 21d8 ; and eax,ebx
182 | F7D8 ; NEG EAX
183 | 1BC0 ; SBB EAX,EAX
184 | 25 00020000 ; AND EAX,200
185 | 0FB78D FCFEFFFF ; MOVZX ECX,WORD PTR SS:[EBP-104]
186 | 0BC8 ; OR ECX,EAX
187 | 66:898D FCFEFFFF ; MOV WORD PTR SS:[EBP-104],CX
188 | 0FB695 1FFFFFFF ; MOVZX EDX,BYTE PTR SS:[EBP-E1]
189 | 21da ; and edx,ebx
190 | F7DA ; NEG EDX
191 | 1BD2 ; SBB EDX,EDX
192 | 81E2 00040000 ; AND EDX,400
193 | 0FB785 FCFEFFFF ; MOVZX EAX,WORD PTR SS:[EBP-104]
194 | 0BC2 ; OR EAX,EDX
195 | 66:8985 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],AX
196 | 0FB68D 13FFFFFF ; MOVZX ECX,BYTE PTR SS:[EBP-ED]
197 | 21d9 ; and ecx,ebx
198 | F7D9 ; NEG ECX
199 | 1BC9 ; SBB ECX,ECX
200 | 81E1 00400000 ; AND ECX,4000
201 | 0FB795 FCFEFFFF ; MOVZX EDX,WORD PTR SS:[EBP-104]
202 | 0BD1 ; OR EDX,ECX
203 | 66:8995 FCFEFFFF ; MOV WORD PTR SS:[EBP-104],DX
204 | 0FB685 26FFFFFF ; MOVZX EAX,BYTE PTR SS:[EBP-DA]
205 |
206 | 5B ; pop ebx
207 | )
208 | this._setPatchData( 0x419f4e, 0x41a2bd, 0x400C00, 0x100, pd )
209 | }
210 | }
211 |
--------------------------------------------------------------------------------
/gamedata/gamedataalcostg.ahk:
--------------------------------------------------------------------------------
1 | ; 本作很坑爹的按 [ESP+XX] 来访问局部变量...
2 | ; 而且会修改 EBX/BL
3 |
4 | class THKMC_GameDataAlcostg extends THKMC_GameData10 {
5 | __New( ) {
6 | base.__New()
7 | base._setEXEInfo("alcostg", "黄昏酒场 1.00a", 0x47755c66, 472064)
8 | pd =
9 | (LTrim Comment
10 |
11 | 57 ; PUSH EDI
12 | BF 80000000 ; MOV EDI,80
13 |
14 | 81C4 94000000 ; add esp, 94 ; 后面的地址总共 -0x90。使用 KADD 和 KADDForComment 命令
15 |
16 | 33C9 ; XOR ECX,ECX
17 | 8A4C24 A0 ; MOV CL,BYTE PTR SS:[ESP-60]
18 | 33D2 ; XOR EDX,EDX
19 | 8A5424 9C ; MOV DL,BYTE PTR SS:[ESP-64]
20 | 33C0 ; XOR EAX,EAX
21 | 8A4424 93 ; MOV AL,BYTE PTR SS:[ESP-6D]
22 | 33DB ; XOR EBX,EBX
23 | 8A5C24 48 ; MOV BL,BYTE PTR SS:[ESP+48]
24 | 21f9 ; and ecx,edi
25 | 21fa ; and edx,edi
26 | 21f8 ; and eax,edi
27 | D1E0 ; SHL EAX,1
28 | 0BC1 ; OR EAX,ECX
29 | 33C9 ; XOR ECX,ECX
30 | 8A4C24 99 ; MOV CL,BYTE PTR SS:[ESP-67]
31 | D1E0 ; SHL EAX,1
32 | 0BC2 ; OR EAX,EDX
33 | 33D2 ; XOR EDX,EDX
34 | 8a5424 47 ; MOV DL,BYTE PTR SS:[ESP+47]
35 | D1E0 ; SHL EAX,1
36 | 0BCA ; OR ECX,EDX
37 | 21f9 ; and ecx,edi
38 | 0BC1 ; OR EAX,ECX
39 | 33D2 ; XOR EDX,EDX
40 | 8A5424 90 ; MOV DL,BYTE PTR SS:[ESP-70]
41 | 33C9 ; XOR ECX,ECX
42 | 8A4C24 9F ; MOV CL,BYTE PTR SS:[ESP-61]
43 | D1E0 ; SHL EAX,1
44 | 21fa ; and edx,edi
45 | 21f9 ; and ecx,edi
46 | 0BC1 ; OR EAX,ECX
47 | 33C9 ; XOR ECX,ECX
48 | 8A4C24 9D ; MOV CL,BYTE PTR SS:[ESP-63]
49 | D1E0 ; SHL EAX,1
50 | 0BC2 ; OR EAX,EDX
51 | 33D2 ; XOR EDX,EDX
52 | 8A5424 81 ; MOV DL,BYTE PTR SS:[ESP-7F]
53 | C1E0 07 ; SHL EAX,7
54 | 21f9 ; and ecx,edi
55 | 0BC1 ; OR EAX,ECX
56 | 33C9 ; XOR ECX,ECX
57 | 8A4C24 AD ; MOV CL,BYTE PTR SS:[ESP-53]
58 | 21fa ; and edx,edi
59 | D1E0 ; SHL EAX,1
60 | 0BC2 ; OR EAX,EDX
61 | 0FB65424 AC ; MOVZX EDX,BYTE PTR SS:[ESP-54]
62 | D1EA ; SHR EDX,1
63 | 21f9 ; and ecx,edi
64 | 0BCA ; OR ECX,EDX
65 | 33D2 ; XOR EDX,EDX
66 | 8A5424 AE ; MOV DL,BYTE PTR SS:[ESP-52]
67 | D1E9 ; SHR ECX,1
68 | D1E0 ; SHL EAX,1
69 | 21fa ; and edx,edi
70 | 0BCA ; OR ECX,EDX
71 | 33D2 ; XOR EDX,EDX
72 | 8A5424 AA ; MOV DL,BYTE PTR SS:[ESP-56]
73 | D1E9 ; SHR ECX,1
74 | 21fa ; and edx,edi
75 | 0BCA ; OR ECX,EDX
76 | 33D2 ; XOR EDX,EDX
77 | 8A5424 C8 ; MOV DL,BYTE PTR SS:[ESP-38]
78 | D1E9 ; SHR ECX,1
79 | 0BD3 ; OR EDX,EBX
80 | 21fa ; and edx,edi
81 | 0BCA ; OR ECX,EDX
82 | 33D2 ; XOR EDX,EDX
83 | 8a5424 50 ; MOV DL,BYTE PTR SS:[ESP+50]
84 | 33DB ; XOR EBX,EBX
85 | 8A5C24 D0 ; MOV BL,BYTE PTR SS:[ESP-30]
86 | D1E9 ; SHR ECX,1
87 | 0BD3 ; OR EDX,EBX
88 | 21fa ; and edx,edi
89 | 0BCA ; OR ECX,EDX
90 | 33D2 ; XOR EDX,EDX
91 | 8A5424 CB ; MOV DL,BYTE PTR SS:[ESP-35]
92 | 33DB ; XOR EBX,EBX
93 | 8a5c24 4B ; MOV BL,BYTE PTR SS:[ESP+4B]
94 | D1E9 ; SHR ECX,1
95 | 0BD3 ; OR EDX,EBX
96 | 21fa ; and edx,edi
97 | 0BCA ; OR ECX,EDX
98 | D1E9 ; SHR ECX,1
99 | 0BC1 ; OR EAX,ECX
100 | 33C9 ; XOR ECX,ECX
101 | 8A4C24 CD ; MOV CL,BYTE PTR SS:[ESP-33]
102 | 33D2 ; XOR EDX,EDX
103 | 8a5424 4D ; MOV DL,BYTE PTR SS:[ESP+4D]
104 | 0BCA ; OR ECX,EDX
105 | 8A5424 CF ; MOV DL,BYTE PTR SS:[ESP-31]
106 | 21f9 ; and ecx,edi
107 | 0BC1 ; OR EAX,ECX
108 | 8A4C24 C9 ; MOV CL,BYTE PTR SS:[ESP-37]
109 | 80E1 80 ; AND CL,80
110 | F6D9 ; NEG CL
111 | 1BC9 ; SBB ECX,ECX
112 | 81E1 90000000 ; AND ECX,90
113 | 80E2 80 ; AND DL,80
114 | 0BC1 ; OR EAX,ECX
115 | 8A4C24 C7 ; MOV CL,BYTE PTR SS:[ESP-39]
116 | F6DA ; NEG DL
117 | 1BD2 ; SBB EDX,EDX
118 | 83E2 60 ; AND EDX,60
119 | 0BC2 ; OR EAX,EDX
120 | 8A5424 D1 ; MOV DL,BYTE PTR SS:[ESP-2F]
121 |
122 |
123 | 81EC 94000000 ; sub esp, 94 ; 恢复ESP
124 | 5F ; pop edi
125 | )
126 | this._setPatchData( 0x446a37, 0x446b8e, 0x400c00, 0x80, pd )
127 | }
128 | }
129 |
130 |
131 |
--------------------------------------------------------------------------------
/readme.mak:
--------------------------------------------------------------------------------
1 | # Make readme.html using mingw32-make
2 |
3 |
4 | SHELL=cmd.exe
5 |
6 | TARGETS=README.html
7 |
8 | RM=del
9 |
10 | all: $(TARGETS)
11 |
12 | README.html: README.md
13 | pandoc -f markdown+multiline_tables+table_captions-implicit_figures -s --toc --toc-depth=4 --email-obfuscation=references -V lang=zh --css=docs/style.css --metadata pagetitle="THKMC Readme" -o $@ $<
14 |
15 |
16 | clean:
17 | -$(RM) $(TARGETS)
18 |
19 |
20 | .SUFFIXES:
21 |
22 | .PHONY: clean
23 |
--------------------------------------------------------------------------------
/thkmc.ahk:
--------------------------------------------------------------------------------
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 | ;;; Touhou Keyboard Mapping Changer
3 | ;;; Written by wz520
4 | ;;; Tested AutoHotkey Version: 1.1.30.01
5 | ;;; Download on Github: https://github.com/wz520/thkmc
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7 |
8 |
9 | #NoEnv
10 | #SingleInstance, force
11 | #Persistent
12 |
13 | #include gamedata.ahk
14 | #include KeyNamesDX.ahk
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 |
24 | title = THKMC
25 | helpfilecmd = https://wz520.github.io/thkmc/help.html
26 | g_bakfilesuffix = .thkmcbackup ; 备份文件后缀
27 | g_inifilepath = thkmc.ini ; 键位配置文件
28 | g_configfilepath = config.ini ; 程序配置文件
29 |
30 | SetWorkingDir, %A_ScriptDir%
31 |
32 | ShowLog := True
33 |
34 | ; #NoTrayIcon ;; 由于要用 TrayTip 显示一些提示,所以不能禁掉 TrayIcon
35 | ; 不过要把TrayTip菜单给删掉(仅编译版)
36 | if ( A_IsCompiled ) {
37 | Menu, Tray, NoStandard
38 | }
39 |
40 |
41 |
42 | doBackup(inifilepath, exefilepath) {
43 | global ddlBackup
44 | global g_bakfilesuffix
45 | Gui, Submit, NoHide
46 | if ( ddlBackup = 1 || ddlBackup = 2 ) {
47 | backupfilepath=%exefilepath%%g_bakfilesuffix%
48 | if ( ddlBackup = 1 ) {
49 | ; 1 = 如果备份文件已存在,则不进行备份
50 | IfExist, %backupfilepath%
51 | {
52 | AddLog("【备份】备份文件已存在,跳过")
53 | backupfilepath=
54 | }
55 | }
56 |
57 | if ( backupfilepath != "" ) {
58 | FileCopy, %exefilepath%, %backupfilepath%, 1
59 | AddLog("【备份】成功!")
60 | }
61 | }
62 | }
63 |
64 | doProcess(patch_processor, filename, bTestMode) {
65 | if ( patch_processor.isEXEThisGame() ) {
66 | if ( bTestMode ) {
67 | AddLog("【提示】“测试模式”已开启。EXE文件不会被修改,备份文件也不会被创建。")
68 | }
69 | AddLog("【目标文件】" . filename)
70 | AddLog("【所属游戏】" . patch_processor._d.gamenameCN)
71 |
72 | patch_processor.doPatch()
73 | patch_processor.updateEXECache()
74 |
75 | if ( bTestMode ) {
76 | return True ; 如果勾选“测试模式”,则在此直接返回
77 | }
78 | else {
79 | doBackup(patch_processor._d.inifilepath, filename)
80 | fileobj := FileOpen(filename, "w")
81 | if ( isObject(fileobj) ) {
82 | ; 打开成功
83 | filesize := patch_processor._exesize
84 | if ( fileobj.RawWrite(patch_processor._pEXEData, filesize) = filesize ) {
85 | fileobj.Close()
86 | return True
87 | }
88 | else
89 | throw Exception("写入文件失败", filename)
90 | }
91 | else
92 | throw Exception("以写入方式打开文件失败", filename)
93 | }
94 |
95 | }
96 |
97 | return False
98 | }
99 |
100 |
101 |
102 | ; throw exception on error
103 | ; outvar: exedata and filesize.
104 | ; if file not found, filesize will be set to -1, and exedata will be
105 | ; set to an empty string
106 | readEXEData(filename, ByRef exedata, ByRef filesize) {
107 | filesize := -1
108 | exedata =
109 | ; NOTE:
110 | ; When inside a try-block, FileOpen() will throw an exception on error.
111 | ; To throw our customized error when the file cannot be opened, we need
112 | ; to add one more try-block here to prevent the exeuction flow from
113 | ; jumping to the outer catch-block.
114 | fileobj =
115 | try {
116 | fileobj := FileOpen(filename, "r")
117 | }
118 | catch {
119 | ; nothing
120 | }
121 | if ( !isObject(fileobj) ) {
122 | ; NOTE:
123 | ; If we don't put a try-block above, and this function is being
124 | ; executed inside a try-block, this line would be NEVER executed.
125 | throw Exception("以读取方式打开文件失败或者文件不存在", filename)
126 | }
127 |
128 | filesize := fileobj.Length
129 |
130 | ;; 目前支持的游戏中还没有这么大的EXE
131 | if ( filesize > 1048576 ) {
132 | throw Exception("这文件太大我不敢看…… > _ <", filename)
133 | }
134 |
135 | ;; FileOpen() 碰到带 BOM 的 UTF-8 或 UTF-16 的文本文件会自动跳过 BOM,
136 | ;; 这会导致下面抛出“读取文件失败”异常
137 | ;; 所以要先手动定位到文件起始处
138 | fileobj.Seek(0)
139 |
140 | ; 分配内存用于存储 EXE 的二进制数据
141 | VarSetCapacity(exedata, filesize, 0)
142 |
143 | ; 读取
144 | if ( fileobj.RawRead( exedata, filesize ) != filesize ) {
145 | throw Exception("读取文件失败", filename)
146 | }
147 |
148 | fileobj.Close()
149 | }
150 |
151 |
152 | askInputFilename() {
153 | Gui, +OwnDialogs
154 | FileSelectFile, files, M3, %A_ScriptDir%, 请选择一个东方 STG 的主程序文件, 应用程序文件 (*.exe)
155 | if ( errorlevel != 0 || files = "" ) {
156 | ; throw Exception("由于你没有选择文件,于是我不知道该修改啥……", "*")
157 | Exit
158 | }
159 |
160 | dir=
161 | filepaths := []
162 | Loop, parse, files, `n
163 | {
164 | if (A_Index = 1)
165 | dir := A_LoopField
166 | else
167 | filepaths.Push(dir . "\" . A_LoopField)
168 | }
169 |
170 | return filepaths
171 | }
172 |
173 | ; filename 不得为空,否则扔异常
174 | ; 本函数无返回值。若有任何错误,则扔异常
175 | ; NOTE: It's not recommended to call this function directly. Use tryDoWork() instead.
176 | _doWork(filename) {
177 | if ( filename="" ) {
178 | throw Exception("内部错误ERR233:没有文件名")
179 | }
180 | readEXEData( filename, exedata, filesize )
181 |
182 | succeeded := False
183 | global THKMC_GameIDList, chkTestMode
184 | Gui, 1:Default
185 | Gui, Submit, NoHide
186 | for k, id in THKMC_GameIDList {
187 | gamedata := new THKMC_GameData%id%()
188 | patch_processor := new THKMC_PatchProcessor(&exedata, filesize, gamedata)
189 | if ( doProcess(patch_processor, filename, chkTestMode) ) {
190 | AddLog("`r`n修改成功!`r`n")
191 | succeeded := True
192 | break
193 | }
194 | }
195 |
196 | if ( !succeeded ) {
197 | wocao := []
198 | wocao.Push("此乃何物?吾不识也。")
199 | wocao.Push("无法识别的文件。")
200 | wocao.Push("啊哈哈,琪露诺看不懂。")
201 | wocao.Push("对不起,我的智商刚刚下线,这是啥我看不懂……")
202 | throw Exception(array_choose(wocao), filename)
203 | }
204 | }
205 |
206 | ; e is an Exception object
207 | addErrorObjectToLog(e, bShow:=False) {
208 | msg := "【错误】" e.message
209 | if ( e.what ) {
210 | msg .= "`r`n【相关文件】" e.what
211 | }
212 | AddLog(msg, True)
213 |
214 | if ( bShow ) {
215 | DoShowLog()
216 | ClearLog()
217 | }
218 | }
219 |
220 | ; filenames 可以接受多个文件(使用数组)
221 | tryDoWork(filenames="") {
222 | global HasError
223 | global chkAlwaysAddToList
224 |
225 | filepaths := !IsObject(filenames)
226 | ? [filenames]
227 | : filenames.Count() = 0
228 | ? [""]
229 | : filenames
230 |
231 | if ( filepaths[1] = "" ) {
232 | filepaths := askInputFilename()
233 | }
234 |
235 | Gui, 1:Default
236 | Gui, Submit, NoHide
237 | for k, f in filepaths {
238 | succeeded := False
239 | if ( k > 1 ) {
240 | AddLog("`r`n`r`n####################### 分割线 #######################`r`n`r`n")
241 | }
242 |
243 | try {
244 | _doWork(f)
245 | succeeded := True
246 | }
247 | catch e {
248 | addErrorObjectToLog(e)
249 | }
250 |
251 | if ( chkAlwaysAddToList || succeeded ) {
252 | addFileToList(f, True)
253 | }
254 | }
255 | DoShowLog()
256 | refreshFileList()
257 |
258 | ; DEBUG
259 | if ( 0 ) {
260 | ExitApp, HasError ? 1 : 0
261 | }
262 | else {
263 | ; 清除log
264 | return ClearLog()
265 | }
266 | }
267 |
268 |
269 |
270 |
271 | ;; ------------
272 | ;; GUI 相关
273 | ;; ------------
274 |
275 | assertLVHasSelection() {
276 | Gui, +OwnDialogs
277 | for c, r in LVRow {
278 | }
279 | if ( c <= 0 ) {
280 | global title
281 | MsgBox, 0x40, %title%, 没有高亮的项目 poi
282 | Exit
283 | }
284 | }
285 |
286 |
287 | ; atTop: 添加到最上面
288 | ; return a value returned by LV_Add() or LV_InsertIfNotExist()
289 | addFileToList(filename, atTop:=False) {
290 | global g_ImageListID, g_bakfilesuffix
291 | backupfilepath=%filename%%g_bakfilesuffix%
292 | backupfileexists := FileExist(backupfilepath) ? "√" : "×"
293 |
294 | ; 获取文件属于哪个游戏
295 | gamenameCN := "未知"
296 |
297 | e = ; clear error object
298 | try {
299 | readEXEData(filename, exedata, filesize)
300 | global THKMC_GameIDList
301 | for k, id in THKMC_GameIDList {
302 | gamedata := new THKMC_GameData%id%()
303 | patch_processor := new THKMC_PatchProcessor(&exedata, filesize, gamedata)
304 | if ( patch_processor.isEXEThisGame() ) {
305 | gamenameCN := gamedata.gamenameCN
306 | break
307 | }
308 | }
309 | }
310 | catch e {
311 | gamenameCN := Format("【{:s}】", e.Message)
312 | }
313 |
314 | ; 图标
315 | if ( isObject(e) ) { ; there was an error
316 | iconID := 9999
317 | }
318 | else {
319 | iconID := IL_Add(g_ImageListID, filename, 1)
320 | }
321 |
322 | ; 其他文件属性
323 | try {
324 | FileGetTime, filetime, %filename%
325 | FormatTime, filetimestring, %filetime% R T0
326 | }
327 | catch e {
328 | filetimestring = 无可奉告
329 | }
330 | try {
331 | FileGetAttrib, fileattrib, %filename%
332 | }
333 | catch e {
334 | fileattrib = 布吉岛
335 | }
336 | filesize := DecimalMark(filesize, 0)
337 |
338 | result := atTop
339 | ? LV_InsertIfNotExist(filename, 1, 1, "Icon" . iconID, filename, gamenameCN, filesize, filetimestring, fileattrib, backupfileexists)
340 | : LV_Add("Icon" . iconID, filename, gamenameCN, filesize, filetimestring, fileattrib, backupfileexists)
341 | return result
342 | }
343 |
344 | loadFileList() {
345 | ; 当文件列表很长时可能需要一点时间。所以显示一个提示框
346 |
347 | splash := new WZSplashWindow("Praying" , "正在载入文件列表", "少女祈祷中...")
348 |
349 | splash.Show()
350 | try {
351 | loop, Read, recentfiles.txt
352 | {
353 | l := A_LoopReadLine
354 | ; 忽略空行和包含 *、? 的行
355 | if ( l = "" || RegExMatch(l, "[*?]") ) {
356 | continue
357 | }
358 |
359 | addFileToList(l)
360 | }
361 | }
362 | finally {
363 | LAutoSizeColumn()
364 | splash.Destroy()
365 | }
366 | }
367 |
368 | saveFileList() {
369 | fp := FileOpen("recentfiles.txt", "w`n", "UTF-16")
370 | if ( IsObject(fp) ) {
371 | loop, % LV_GetCount()
372 | {
373 | result := LV_GetText(l, A_Index)
374 | if (result)
375 | fp.WriteLine(l)
376 | }
377 | fp.Close()
378 | }
379 | }
380 |
381 | refreshFileList() {
382 | saveFileList()
383 | LV_Delete()
384 | loadFileList()
385 | }
386 |
387 |
388 |
389 | createINIFile(inifilepath) {
390 | filecontent=
391 | (LTrim
392 | ; 关于本设置文件的完整说明,请参看 thkmc_sample.ini
393 |
394 | [Default]
395 | UP=W
396 | DOWN=S
397 | LEFT=A
398 | RIGHT=D
399 |
400 | Z=j
401 | X=k
402 | C=l
403 | LSHIFT=i
404 | )
405 |
406 | fileobj := FileOpen(inifilepath, "w`n", "UTF-16")
407 | if ( isObject(fileobj) ) {
408 | if (fileobj.Write(filecontent)) {
409 | fileobj.Close()
410 | }
411 | else
412 | throw Exception("写入文件失败", inifilepath)
413 | }
414 | else
415 | throw Exception("以写入方式打开文件失败", inifilepath)
416 | }
417 |
418 | ensureINIExists() {
419 | global title, g_inifilepath
420 | IfNotExist, %g_inifilepath%
421 | {
422 | createINIFile(g_inifilepath)
423 | Gui, +OwnDialogs
424 | msg=【%g_inifilepath%】文件不存在。`r`n`r`n已自动生成。
425 | MsgBox, 64, %title%, %msg%
426 | }
427 | }
428 |
429 |
430 | confirmApply(filepaths) {
431 | global vCA_OK
432 | IsOK := False
433 |
434 | txtFiles := array_join(filepaths, "`r`n")
435 |
436 | Gui, WndConfirm:New, +LabelCA_ +Owner1 -SysMenu -Resize +LastFound, 确认 - THKMC
437 |
438 | Gui, Color, Fuchsia
439 |
440 | Gui, Add, Edit, w500 r25, 你选择的文件是:`r`n%txtFiles%`r`n`r`n真的要将 INI 文件中的键位映射设置应用到这些程序上吗?
441 | Gui, Add, Button, gCA_OK Default w150 vvCA_OK, 是(&Y)
442 | Gui, Add, Button, gCA_Close x+20 w150 , 否(&H)
443 | GuiControl, Focus, vCA_OK
444 | Gui, Show, Center AutoSize
445 | Gui, 1:+Disabled
446 |
447 | WinWaitClose
448 |
449 | return IsOK
450 |
451 | CA_OK:
452 | IsOK := True
453 | ; no return
454 | CA_Close:
455 | CA_Cancel:
456 | Gui, 1:-Disabled
457 | Gui, WndConfirm:Destroy
458 | return
459 | }
460 |
461 |
462 | LOpenINI() {
463 | global g_inifilepath
464 | ensureINIExists()
465 | Run, %g_inifilepath%
466 | }
467 |
468 | LOpenAndApply() {
469 | assertLVHasSelection()
470 |
471 | filepaths := []
472 | for c, row in LVRow {
473 | LV_GetText(filename, row)
474 | filepaths.Push(filename)
475 | }
476 |
477 | if (confirmApply(filepaths)) {
478 | tryDoWork(filepaths)
479 | }
480 | }
481 |
482 |
483 | ; ListView 按键处理
484 | LFileLV() {
485 | if ( A_GuiEvent = "DoubleClick" ) {
486 | LRunEXE()
487 | }
488 | else if ( A_GuiEvent = "K" ) {
489 | key := GetKeyName(Format("vk{:x}", A_EventInfo))
490 | ShortcutkeyToFuncMap := {}
491 | if ( GetKeyState("Ctrl") && !GetKeyState("Alt") ) {
492 | ShortcutkeyToFuncMap["G"] := Func("LOpenAndApply")
493 | ShortcutkeyToFuncMap["D"] := Func("LOpenFolder")
494 | ShortcutkeyToFuncMap["B"] := Func("LRestoreFromBackup")
495 | ShortcutkeyToFuncMap["V"] := Func("LRunVPatch")
496 | ShortcutkeyToFuncMap["C"] := Func("LRunCustom")
497 | ShortcutkeyToFuncMap["Z"] := Func("LRunNyasama")
498 | ShortcutkeyToFuncMap["A"] := Func("LSelectAll")
499 | ShortcutkeyToFuncMap["S"] := Func("LOpenShanghaiAlice")
500 | }
501 | else if ( GetKeyState("Alt") && !GetKeyState("Ctrl") ) {
502 | ShortcutkeyToFuncMap["Enter"] := Func("LOpenFileProperties")
503 | }
504 | else {
505 | ShortcutkeyToFuncMap["NumpadDel"] := Func("LRemove")
506 | ShortcutkeyToFuncMap["F5"] := Func("refreshFileList")
507 | }
508 | if ( ShortcutkeyToFuncMap.HasKey(key) ) {
509 | ShortcutkeyToFuncMap[key].Call()
510 | }
511 | }
512 | }
513 |
514 | LOpenEXE() {
515 | tryDoWork()
516 | }
517 |
518 | LRunEXE() {
519 | assertLVHasSelection()
520 | for c, row in LVRow {
521 | LV_GetText(filename, row)
522 | CriticalRun(filename, "CMDDIR")
523 | }
524 | }
525 |
526 | RunOtherFileInEXEDir(newfilename) {
527 | assertLVHasSelection()
528 | for c, row in LVRow {
529 | LV_GetText(filename, row)
530 | SplitPath, filename, , dir
531 | filename=%dir%\%newfilename%
532 | CriticalRun(filename, "CMDDIR")
533 | }
534 | }
535 |
536 | LRunVPatch() {
537 | RunOtherFileInEXEDir("vpatch.exe")
538 | }
539 | LRunCustom() {
540 | RunOtherFileInEXEDir("custom.exe")
541 | }
542 |
543 | LRunNyasama() {
544 | assertLVHasSelection()
545 | for c, row in LVRow {
546 | LV_GetText(filename, row)
547 | SplitPath, filename, , dir, ext, namenoext
548 | filename=%dir%\%namenoext%c.%ext%
549 | CriticalRun(filename, "CMDDIR")
550 | }
551 | }
552 |
553 | LSelectAll() {
554 | LV_Modify(0, "Select")
555 | }
556 |
557 | ; 返回错误信息,若有错误则扔异常
558 | doRestoreFromBackup( filename, bKeep )
559 | {
560 | global g_bakfilesuffix
561 | bakfilename = %filename%%g_bakfilesuffix%
562 | if ( !FileExist(bakfilename) ) {
563 | throw Exception("备份文件不存在", filename)
564 | }
565 | if ( bKeep ) {
566 | FileCopy, %bakfilename%, %filename%, 1
567 | }
568 | else {
569 | FileMove, %bakfilename%, %filename%, 1
570 | }
571 | }
572 |
573 | LRestoreFromBackup() {
574 | assertLVHasSelection()
575 |
576 | global title, g_bakfilesuffix
577 | MsgBox, 0x33, %title%,
578 | (LTrim
579 | 恢复后是否要保留备份文件(*%g_bakfilesuffix%)?
580 |
581 | 【是】 :恢复并保留备份文件
582 | 【否】 :恢复并删除备份文件
583 | 【取消】:不做任何事情
584 | )
585 |
586 | bKeep := True
587 | IfMsgBox, Cancel
588 | {
589 | return
590 | }
591 | else IfMsgBox, No
592 | {
593 | bKeep := False
594 | }
595 |
596 | success_count := 0
597 | for c, row in LVRow {
598 | LV_GetText(filename, row)
599 | try {
600 | doRestoreFromBackup(filename, bKeep)
601 | success_count++
602 | }
603 | catch e {
604 | e.what := filename
605 | addErrorObjectToLog(e, True)
606 | }
607 | }
608 |
609 | refreshFileList()
610 | TrayTip, %title%, 成功恢复了 %success_count% 个文件。
611 | }
612 |
613 | LDeleteBackup() {
614 | assertLVHasSelection()
615 |
616 | global title, g_bakfilesuffix
617 | MsgBox, 0x134, %title%, 真的要【从磁盘上】删除所有选中项目的备份文件(*%g_bakfilesuffix%)吗?
618 |
619 | IfMsgBox, No
620 | {
621 | return
622 | }
623 |
624 | success_count := 0
625 | for c, row in LVRow {
626 | LV_GetText(filename, row)
627 | try {
628 | bakfile =%filename%%g_bakfilesuffix%
629 | IfExist, %bakfile%
630 | {
631 | FileDelete, %bakfile%
632 | success_count++
633 | }
634 | }
635 | catch e {
636 | ; ignore errors
637 | }
638 | }
639 |
640 | refreshFileList()
641 | TrayTip, %title%, 成功删除了 %success_count% 个备份文件。
642 | }
643 |
644 | ; return a list
645 | LVGetAllSelection() {
646 | files := []
647 | for c, row in LVRow {
648 | LV_GetText(filename, row)
649 | files.Push(filename)
650 | }
651 | return files
652 | }
653 |
654 |
655 | LCopyFullPath() {
656 | assertLVHasSelection()
657 | files := LVGetAllSelection()
658 | c := files.MaxIndex()
659 | if ( c ) {
660 | global title
661 | Clipboard := array_join(files)
662 | TrayTip, %title%, 复制%c%个文件的路径到剪贴板成功!
663 | }
664 | }
665 |
666 | LCopyOrCutFile(itemname) {
667 | assertLVHasSelection()
668 | bCopy := InStr(itemname, "复制") ? True : False
669 | files := LVGetAllSelection()
670 | c := files.MaxIndex()
671 | if ( c ) {
672 | global title
673 | verb := bCopy ? "复制" : "剪切"
674 | CopyFilesToClipboard(files, bCopy)
675 | TrayTip, %title%, %verb%%c%个文件到剪贴板成功!
676 | }
677 | }
678 |
679 | LOpenFolder() {
680 | assertLVHasSelection()
681 | for c, row in LVRow {
682 | LV_GetText(filename, row)
683 |
684 | ; NOTE: Run 貌似没用,换成 DllCall()
685 | ; Run, *open explorer.exe /select,%filename%
686 | ; DllCall("shell32.dll\ShellExecute", "ptr", 0, "str", "open", "str", "Explorer.exe", "str", " /select," . filename, "ptr", 0, "int", 10, "int")
687 |
688 | ; NOTE: 不不不,其实 Run 还是有用的,只是我参数没写对。>_<
689 | Run, *open explorer.exe /select`,%filename%, , UseErrorLevel
690 | }
691 | }
692 |
693 | LOpenShanghaiAlice() {
694 | cmd = *open %A_AppData%\ShanghaiAlice
695 | CriticalRun(cmd)
696 | }
697 |
698 | LOpenFileProperties() {
699 | assertLVHasSelection()
700 | for c, row in LVRow {
701 | LV_GetText(filename, row)
702 |
703 | Run, properties %filename%, , UseErrorLevel
704 | if ( ErrorLevel = "ERROR" ) {
705 | global title
706 | TrayTip, %title% - 打开文件属性失败, 文件:%filename%, ,3
707 | }
708 | }
709 | }
710 |
711 |
712 | ;; Load/Save Config
713 |
714 | loadConfig(key, default) {
715 | global g_configfilepath, g_inifilepath
716 | IniRead, chkstate, %g_configfilepath%, thkmc, %key%
717 |
718 | if ( chkstate = "ERROR" ) {
719 | IniRead, chkstate, %g_inifilepath%, thkmc, %key%, %default%
720 | }
721 |
722 | return chkstate
723 | }
724 | saveConfig() {
725 | global ddlBackup, chkTestMode, chkAlwaysAddToList, g_configfilepath
726 | Gui, Submit, NoHide
727 |
728 | IniWrite, %ddlBackup%, %g_configfilepath%, thkmc, DoBackup
729 | IniWrite, %chkTestMode%, %g_configfilepath%, thkmc, TestMode
730 | IniWrite, %chkAlwaysAddToList%, %g_configfilepath%, thkmc, AlwaysAddToList
731 | }
732 |
733 |
734 |
735 | ; return the count of the deleted items
736 | LRemove() {
737 | assertLVHasSelection()
738 | global title
739 | delcount := 0
740 | MsgBox, 0x34, %title%, 真的要清除列表中所有已选中的项目吗?
741 | IfMsgBox, Yes
742 | {
743 | rownum := 0
744 | Loop {
745 | rownum := LV_GetNext(rownum)
746 | if ( rownum ) {
747 | LV_Delete(rownum--)
748 | delcount++
749 | } else
750 | break
751 | }
752 | }
753 | return delcount
754 | }
755 |
756 | LRemoveAll() {
757 | global title
758 | Gui, +OwnDialogs
759 | MsgBox, 0x34, %title%, 真的要清除列表中的所有项目吗?
760 | IfMsgBox, Yes
761 | {
762 | LV_Delete()
763 | }
764 | }
765 |
766 | GuiSize(GuiHwnd, EventInfo, Width, Height) {
767 | if ( EventInfo != 1 ) {
768 | neww := Width - 20
769 | newh := Height - 120
770 | GuiControl, Move, vFileLV, w%neww% h%newh%
771 | }
772 | }
773 |
774 | ; 拖拽处理
775 | GuiDropFiles(GuiHwnd, FileArray, CtrlHwnd, X, Y) {
776 | _files := []
777 |
778 | splash=
779 | for k, f in FileArray {
780 | attr := FileExist(f)
781 | if ( InStr(attr, "D") ) {
782 | if ( !IsObject(splash) ) {
783 | splash := new WZSplashWindow("SearchingEXE" , "正在搜索 .exe 文件", "少女祈祷中...")
784 | splash.Show()
785 | }
786 |
787 | loop, Files, %f%\*.exe, R
788 | {
789 | _files.Push(A_LoopFileFullPath)
790 | }
791 | }
792 | else {
793 | _files.Push(f)
794 | }
795 | }
796 | if ( IsObject(splash) ) {
797 | splash.Destroy()
798 | }
799 |
800 | if (confirmApply(_files)) {
801 | tryDoWork(_files)
802 | }
803 | }
804 |
805 | GuiContextMenu(GuiHwnd, CtrlHwnd, EventInfo, IsRightClick, X, Y) {
806 | if (A_GuiControl = "vFileLV") {
807 | Menu, mnuLV, Show, %A_GuiX%, %A_GuiY%
808 | }
809 | }
810 |
811 |
812 |
813 | ; ------------------------
814 | ; -- ENTRY
815 | ; ------------------------
816 |
817 | ; 创建 GUI
818 | Gui, +Hwndg_hWnd
819 | Gui, Add, Button, gLOpenINI, 编辑 thkmc.ini(&E)
820 | Gui, Add, Button, gLOpenEXE x+10, 打开程序并应用补丁(&O)
821 | Gui, Add, Button, gLOpenAndApply x+10 hwndhBtnApply, 应用补丁(&A)
822 | Gui, Add, Button, gLRunEXE x+10 hwndhBtnRun +Default, 运行(&R)
823 | Gui, Add, Button, grefreshFileList x+10 y5 hwndhBtnRefresh, 刷新(&E)
824 | Gui, Add, Button, gRunHelpAndExit hwndhBtnHelp x+10 y5, 帮助(&H)
825 | Gui, Add, Custom, ClassSysLink hwndhSysLinkAbout gLSysLinkEvent x+5 w50 r1 y10, 关于...
826 |
827 | Gui, Add, Text, xm+0, 备份到 *%g_bakfilesuffix% ?
828 | cfgvalue := loadConfig("DoBackup", 1)
829 | Gui, Add, DropDownList, AltSubmit vddlBackup x+10 yp-3 w210 Choose%cfgvalue%, 只在备份文件不存在时备份(推荐)|总是备份(若备份已存在则覆盖)|不备份(不推荐)
830 | cfgvalue := loadConfig("TestMode", 0)
831 | Gui, Add, Checkbox, x+10 yp-3 h30 vchkTestMode Checked%cfgvalue%, 测试模式(&T)
832 | cfgvalue := loadConfig("AlwaysAddToList", 0)
833 | Gui, Add, Checkbox, x+10 h30 vchkAlwaysAddToList Checked%cfgvalue%, 总是添加至列表(&P)
834 |
835 | Gui, Add, Text, x10, 查看更新:
836 | Gui, Add, Custom, ClassSysLink hwndhSysLink gLSysLinkEvent x+5 w40 r1, 喵玉殿
837 | Gui, Add, Custom, ClassSysLink hwndhSysLinkGitHub gLSysLinkEvent x+5 w40 r1, GitHub
838 | g_updatelink = http://bbs.nyasama.com/forum.php?mod=viewthread&tid=78904
839 | g_githublink = https://github.com/wz520/thkmc
840 |
841 | Gui, Add, Text, xm CBlue, ※最近打开的文件(双击可运行程序,右击有菜单):
842 | Gui, Add, ListView, vvFileLV xm w740 h400 gLFileLV AltSubmit LV0x4000, 文件|游戏版本|大小|最后修改时间|属性|存在备份 ; LVS_EX_LABELTIP:=0x4000
843 | LV_ModifyCol(3, "Integer") ; For sorting purposes, indicate that column 2 is an integer.
844 | g_ImageListID := IL_Create(10)
845 | LV_SetImageList(g_ImageListID)
846 | Gui, +Resize +OwnDialogs
847 |
848 | ; GUI ToolTip
849 | GuiControlGet, hCtrl, Hwnd, chkTestMode
850 | AttachTipToControl(hCtrl, "模拟打补丁的过程:会显示修改结果,但不会创建/修改EXE文件和备份文件。`r`n【提示】若打补丁成功,仍会将文件路径添加至文件列表。")
851 | GuiControlGet, hCtrl, Hwnd, chkAlwaysAddToList
852 | AttachTipToControl(hCtrl, "即使打补丁失败也会将文件路径添加至文件列表。`r`n若不勾选此项, THKMC 只会在打补丁成功后才将文件路径添加至文件列表。")
853 | AttachTipToControl(hBtnApply, "将 .INI 中的映射配置重新应用到选中的程序上")
854 | AttachTipToControl(hBtnRun, "运行选中的游戏程序")
855 | AttachTipToControl(hBtnRefresh, "刷新“最近打开的文件”列表")
856 | AttachTipToControl(hBtnHelp, helpfilecmd)
857 | AttachTipToControl(hSysLink, g_updatelink)
858 | AttachTipToControl(hSysLinkGitHub, g_githublink)
859 |
860 | Gui, Show, Center, %title%
861 | GuiControl, Focus, vFileLV
862 |
863 | ; 快捷菜单
864 | Menu, mnuLV, Add, 应用改键补丁`tCtrl+G, LOpenAndApply
865 | Menu, mnuLV, Add
866 | Menu, mnuLV, Add, 运行该程序`tEnter, LRunEXE
867 | Menu, mnuLV, Default, 运行该程序`tEnter
868 | Menu, mnuLV, Add, 运行所在目录下的 vpatch.exe`tCtrl+V, LRunVPatch
869 | Menu, mnuLV, Add, 运行所在目录下的 custom.exe`tCtrl+C, LRunCustom
870 | Menu, mnuLV, Add, 运行所在目录下的汉化版游戏程序(th???c.exe)`tCtrl+Z, LRunNyasama
871 | Menu, mnuLV, Add, 打开所在目录`tCtrl+D, LOpenFolder
872 | Menu, mnuLV, Add, 打开 ShanghaiAlice 目录`tCtrl+S, LOpenShanghaiAlice
873 | Menu, mnuLV, Add
874 | Menu, mnuLV, Add, 属性...`tAlt+Enter, LOpenFileProperties
875 | Menu, mnuLV, Add
876 | Menu, mnuLV, Add, 从备份文件恢复`tCtrl+B, LRestoreFromBackup
877 | Menu, mnuLV, Add, 删除备份文件, LDeleteBackup
878 | Menu, mnuLV, Add
879 | Menu, mnuLV, Add, 复制完整路径, LCopyFullPath
880 | Menu, mnuLV, Add, 剪切, LCopyOrCutFile
881 | Menu, mnuLV, Add, 复制, LCopyOrCutFile
882 | Menu, mnuLV, Add, 全选`tCtrl+A, LSelectAll
883 | Menu, mnuLV, Add
884 | Menu, mnuLV, Add, 移除高亮的项目`tDelete, LRemove
885 | Menu, mnuLV, Add, 移除所有项目, LRemoveAll
886 | Menu, mnuLV, Add
887 | Menu, mnuLV, Add, 自动调整表格宽度, LAutoSizeColumn
888 | Menu, mnuLV, Add, 刷新`tF5, refreshFileList
889 | Menu, mnuLV, Add
890 | Menu, mnuLV, Add, 关于..., LAbout
891 |
892 | OnExit("LOnExit")
893 |
894 | loadFileList()
895 |
896 | return
897 |
898 | LOnExit(ExitReason, ExitCode) {
899 | saveFileList()
900 | saveConfig()
901 | }
902 |
903 | GuiClose:
904 | GuiEscape:
905 | ExitApp
906 |
907 | lSysLinkEvent:
908 | if ( A_GuiEvent = "N" ) {
909 | code := NumGet(A_EventInfo, A_PtrSize+4, "Int") ; NMHDR->hwndFrom
910 | if ( code = -2 || code = -4 ) { ; NM_CLICK = -2, NM_RETURN = -4
911 | hwndFrom := NumGet(A_EventInfo, 0, "UPtr") ; NMHDR->hwndFrom
912 | if ( hwndFrom = hSysLink ) {
913 | Run, %g_updatelink%
914 | }
915 | else if (hwndFrom = hSysLinkGitHub) {
916 | Run, %g_githublink%
917 | }
918 | else if (hwndFrom = hSysLinkAbout) {
919 | LAbout()
920 | }
921 | }
922 | }
923 | return
924 |
925 | GetAHKVersionString() {
926 | strIsUnicode := A_IsUnicode ? "Unicode" : "ANSI"
927 | strIs64bit := A_PtrSize = 8 ? "64位" : "32位"
928 | result=%A_AhkVersion% %strIsUnicode% %strIs64bit%
929 | return result
930 | }
931 |
932 | LAbout() {
933 | global title
934 | Gui, +OwnDialogs
935 |
936 | gamelist := THKMC_GetGameNameList()
937 | ahkver := GetAHKVersionString()
938 |
939 | MsgBox, 64, %title%,
940 | (LTrim
941 | THKMC - 东方STG专用键盘键位映射修改工具 1.40
942 |
943 | AutoHotkey 版本:%ahkver%
944 |
945 | Written by wz520
946 | 百度贴吧ID:天使的枷锁
947 |
948 | 支持的游戏:
949 | %gamelist%
950 | )
951 | }
952 |
953 | LAutoSizeColumn() {
954 | LVAutoSizeHeader("vFileLV")
955 | }
956 |
957 |
--------------------------------------------------------------------------------
/thkmc.ahk.ini:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wz520/thkmc/caf7020d652babf3293273c7d40119a8fd79ac74/thkmc.ahk.ini
--------------------------------------------------------------------------------
/thkmc.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wz520/thkmc/caf7020d652babf3293273c7d40119a8fd79ac74/thkmc.ico
--------------------------------------------------------------------------------
/thkmc_sample.ini:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wz520/thkmc/caf7020d652babf3293273c7d40119a8fd79ac74/thkmc_sample.ini
--------------------------------------------------------------------------------