找回密码
 注册
搜索
查看: 3417|回复: 3

[转帖] 解密FC重装机兵中文版的无敌军号

[复制链接]
发表于 2013-7-3 23:50 | 显示全部楼层 |阅读模式
本帖最后由 Toyger 于 2013-7-3 23:52 编辑

http://bbs.saraba1st.com/2b/read-htm-tid-315085.html

作者:doubledr

军号在mm1中文版中几乎是无敌的,使用之后基本不会费血了,我本以为游戏是这样设置的,但最近看到帖子说,日文版mm中的军号并无此BT功效,于是我打开模拟器试了一试,发现果然如此。

原来无敌的军号是中文版的“特色”啊,于是我猜想是中文版中做了什么改动,也可能是汉化不小心产生的错误。到底是如何产生这么厉害的军号呢。

首先分析一下中文版中军号可能的效果,很容易想到的是提高人物的防御力,而且是极大的提高,因为使用军号后敌人基本打不动主角了,攻击力提升倒是不明显,所以我打算从主角防御力入手。

先找到存储主角防御力的地址,这个不难,你可以直接去ec里面看代码,那里有好多别人找好的地址,最后我找到防御力地址在:6472.


你可以直接改这个地址的数据,然后查看强度,会发现防御力跟着变化,表示地址找的没错。

现在防御力地址找到了,我们来测试一下防御力对伤害值的影响。由于我只关心防御力,所以我这里选择龟式战车这个敌人,因为龟式战车喜欢用冲撞,而且冲撞的伤害只与双方防御力有关。就是谁防御力大谁胜。

好了,先让龟式战车冲撞我,这次我损了702,主角这次的防御力是58,龟式战车的防御力是760。760-58正好等于702。真好,意外的发现了冲撞的计算公式:敌防-我防=伤害(如果我防大于敌防则反过来)。

多次冲撞,发现伤害值一直都是702,1滴不多也不少,确定这个计算公式是正确的,并且没有随机偏移。


接下来我直接修改6472处的值就是主角防御数值,然后让龟式战车冲撞,我想应该是伤害将要减小才对,但结果是伤害仍然是702,并没有减少,问题出在哪里呢。

我再一想,是不是游戏程序在战斗时将主角防御力存在了另一个位置,然后在战斗中的伤害计算都是在另一个位置,如果是这样的话,直接修改6472处不能改变伤害就能解释得通了,并且战斗时将主角的属性存储在另外一个地方再使用,也是一种很常见的做法,这样可以保证主角的属性属性数据相对独立。越想越觉得对,继续。

为了找到主角的防御力最终存到哪个地方,我将断点设置在6472处。然后遇敌,很幸运的,游戏马上中断下来,如图:


图示主角的防御力被存储在了706d处,继续寻找6472处的访问,发现没有再次中断了,可以确定只有706d这一个位置了。我也极相信这个位置就是在战斗时使用的防御值。

好了,接下来查看706d附近的数值,由于我研究mm1较多,不多时基本都给我看出来是什么数据了,从706a开始的3个字节分别存储的是3位主角的速度,虽然现在还只有1个主角,但是游戏就是这么存的。接着706d开始每2个字节存储3位主角的防御,再后面就是连续3位主角的等级(战斗等级,驾驶等级,修理等级)共9个字节:

如下图是使用军号前706d附近的数值 蓝色框起来的是主角防御,2个字节存储:


现在使用军号(在中文版),结果如下图:
引用
现在分析使用军号前后数据的变化。
结果是:使用军号后从706a地址处开始的连续16个字节,每个字节都加上了0x10(16进制),就是都加上了16.

反应在属性数值变化上就是:主角三人的速度全都增加了16,防御值增加了0x1010=4112,全部等级都增加16.

军号的威力就在此了,主要的bt之处在于防御力增加了4112,为什么增加这么多,可以发现游戏这种加法的bug,因为防御是2个字节存储,低位增加0x10是16,高位增加0x10是4096,bug在于给高位也增加了0x10.


好了,中文版军号的秘密已经知道了,但是中文版和日本版之间的差别还不知道。但是有前面的研究,相信很快就可以搞清楚了,继续往下看、

现在换日本版的来,同样是观察706d附近的数值。找到使用军号前后的变化。

使用前的状态跟上面中文版的一样,使用后的状态如下(由于读档时已经使用了一次军号,下面的截图实际使用了2次军号,结果全都是加上0x20,就是32,意外的也发现了军号可以多次使用都有效果):


引用
日文版吹军号之后的效果是:
结果是:使用军号后从706a地址处开始的连续3个字节,每个字节都加上了0x10(16进制),就是都加上了16.

反应在属性数值变化上就是:主角三人的速度全都增加了16。
仅仅只是把3人的速度提高了,防御力,等级根本就没有变化,所以日文版的军号并没有特效,虽然我现在不敢确认是否别的数值有变化,但是可以确认的起码防御和等级都没有变化。


接下来就要从代码里找到,这两种差别的原因,看看到底是人为还是汉化错误。

把断点设置到706a(存储的是主角的速度,因为无论在中文版还是日文版这个值在使用军号后都将变化),这里是吹军号后的必经之地。

日文版军号效果代码:
        LDX #$02  //只存储连续3个字节(中文版照理说就应该是ldx  #$10,看我猜的对不对)
e8002:
        CLC
        LDA #$10  //增加的数值0x10(32)

        ADC $706A,X  
        BCC e800C  //超过1个字节的最大值的话保证不出错,从这里可以看出原本游戏只是给单字节的属性增加16的

        LDA #$FF
e800C:
        STA $706A,X  //保存增加16后的值,此处是速度

        DEX
        BPL e8002
……
中文版军号效果代码:
        ORA (z02,X)  e8002:
        CLC
        LDA #$10  
        ADC $706A,X  
        BCC e800C  
        LDA #$FF
e800C:
        STA $706A,X  
        DEX
        BPL e8002
……
可以看出中文版和日文版只有第一句不同,中文版是ORA (z02,X)  ,并不是我所希望的ldx #$10

假若是我所希望的ldx #$10,那么毫无疑问,这是当年汉化人员人为加上去的,但问题是现在是这么一句毫无意义的代码,在这么一个位置读取$02的值,然后间接寻址又进行或运算,简直毫无道理,并且由于下面有一行代码:
LDA #$10  
就使得ORA (z02,X)  这句变得没有任何作用了,我开始怀疑代码是不是另有地方,但是找了一会儿没有头绪。
现在的问题是中文版中存储连续x10个字节的这个ox10从哪里来的,因为ORA (z02,X)  不可能使X变成10。

突然临机一动,从这段代码往上找,进过几次跳转,终于给我找到这个所谓的0x10了,
   LDX #$10
        JMP $D414  这里是将第0x10块代码转移到某个地址,然后程序就会跳转到上面我帖出来的代码,

这里确实有个0x10,但是这个0x10的意义是第0x10块代码,就是这样奇怪,现在终于想清楚了,0x10就是从这个地方延续下去的,因为下面都没有改变x值的代码。而ORA (z02,X) 的确是一句毫无用处的代码,在日文版中,这里是给x赋值2,而在中文版中,这句没有任何作用,x值就延续了前面的代码块号0x10.这样误打误撞结果造就了中文版中的无敌军号。

:D :D :D :D
依我来看,这极可能是汉化时发生的错误而非人为所致,首先这个0x10来的极为蹊跷,如果我是当年改程序的,绝对是将
ldx #$2 改成 ldx#$10 而不是现在的ORA (z02,X) ,这么个毫无意义的代码,至少也是改成nop。

再者为什么是0x10也是很奇怪的,因为从速度到等级一共是0x11个字节,如果是人为把所有属性增加0x10,就应该是
ldx #$11 ,现在的中文版却是只改变0x10个字节,这样第3个角色的驾驶等级其实是没有增加的。

所以,基本可以确定这是汉化中不小心发生的错误。

现在都研究清楚了,就可以把这个汉化错误给改回来。

把文件 0x20010 处的 01,改成 A2,这样中文版中的军号就跟日文版一样了。
发表于 2013-7-3 23:52 | 显示全部楼层
没玩过
 楼主| 发表于 2013-7-3 23:53 | 显示全部楼层
SK玩过
发表于 2013-7-6 22:10 | 显示全部楼层
有内容。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|虎纹猫家园

GMT+8, 2024-5-9 06:45 , Processed in 0.052509 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表