- UID
- 2290
- 阅读权限
- 40
- 精华
- 魅力
-
- 信用
-
- 注册时间
- 2009-2-8
- 在线时间
- 小时
- 最后登录
- 1970-1-1
|
本文由 痕 原创
出处:http://langrisser.xyz/mdl2-summons-magic
先来个结论:这是个BUG
MDL2的召唤兽魔法与DER的是一样的,都是从召唤兽的职业数据读取,而不是随机变动的。
看这个,出现BUG的程序段:
简单解释一下,
1、0xa62c是保存当前使用魔法的单位的内存地址的地方,把使用魔法的单位的内存地址读取到A1寄存器
2-3、判断这个单位的序号是否为零,如果为零,说明这个单位是指挥官,从这个单位的战场内存数据中读取可使用的魔法,直接跳过以下的程序;而如果不为零,说明这个单位是佣兵或召唤兽,就从这个单位的职业数据处读取可使用的魔法,这个在接下来的程序中实现。
4、把地址0x5eddc置入寄存器A0,0x5eddc是职业数据
5-6、读取这个单位的职业
7、职业的编码乘以0x1c,每个职业的职业数据长度是0x1c
8、把A1和D0相加,结果置入A1。这里就开始错了,A0错写成A1了,A0才是职业数据
9、A1的值加上0x16。同上,错了
10、清空D7寄存器,准备用来保存可使用的魔法。
11、把常数3置入寄存器D6,职业数据中,每个职业最多可用4种魔法
12-13、读取职业数据中可使用魔法的字节,置入D1,然后A1的值增加1。错了,A0才是职业数据
14-15、判断这个字节是否为0xff,如果是0xff,表示这个字节没有可用魔法,跳到第18步,否则继续执行
16、D1的数值加上1,因为魔法的代码是从2开始计数
17、根据D1的数值,把D7相应的bit设置为1
18、如果D6不等于-1,则循环第11-17步,同时D6的值自减1
到这里为止就是读取可用魔法的程序了,其中第8、第9和第13错了,导致召唤兽的魔法读取错误。
可以自己验证一下:
比如艾尔文召唤出来的水元素,艾尔文的召唤兽内存地址0x6090,水元素职业代码0x8D,乘以0x1C,与内存地址相加,再加上0x16,得到0x7012,从0x7012开始的4个字节在BUG的情况下决定艾尔文召唤出来的水元素的魔法。
BUG修复:
汇编修改:
- 21226:adda.w D0,A1 -> 21226:adda.w D0,A0
- 21228:adda.w #$16,A1 -> 21228:adda.w #$16,A0
- 21234:move.b (A1)+,D1 -> 21234:move.b (A0)+,D1
复制代码 十六进制修改:
21226:D2 -> D0
21228:D2 -> D0
21235:19 -> 18 |
|