GB/GBC汉化经验分享之十五--《圣剑传说》的原文本输出程序分析 心得研究

六级用户 RangerMarsh 11天前 348

十五、《圣剑传说》的原文本输出程序分析


接下来我们就好好分析一下游戏原来的文本输出程序,看可以如何去做修改。

之前已经记下了游戏在运行到0:378A时会读出文本,就在这里设置断点,先看一下游戏在读出文本后做了哪些操作。

15-01.png

这里可以开两个窗口,平行地看游戏对清音和浊音的输出有什么区别,这样们可以知道在哪里去做修改。这里我们先以读出D:46FB4E(“ど”)为例。

读出文本的代码后,按F7一步一步向下走。这里是判断读取得到值是否是控制符(00-1F)或者短语(20-3F)。

15-02.png

cp a,40

jp c,3837

cp是比较,将当前a的值与40作比较,相当于做减法,根据结果的不同执行不同的操作。有两套判断标准,一个是cnc,如果结果小于0,就标记为c,大于等于0就是nc。另一个是znz,结果是0就是z,不是0就是nz。可以在寄存器窗口最右侧看到标记情况。这里4E-40=E,是大于0的,标记为nc

jp是跳转的指令,可以加判断也可以不加。这里表示,如果标记是c就跳转到3837,现在标记是nc,所以不会跳转,程序要继续向下运行。

这一段是比较D84A的值,如果这个值是下面做比较的这些值中的一个,就跳到37AF去运行,不是就继续运行。

15-03.png

push af表示把当前寄存器af的值推送到栈,与之对应的是pop af,从当前栈中取回值到寄存器af。类似的其他几个寄存器也有同样的命令。一般来说是后面的操作会用到当前这个寄存器,但现在寄存器的值待会还要用,就可以用这个命令暂时保存一下。这个命令使用时要注意推送后记得取回,如果同时推送多个寄存器的话要注意取回顺序。

jr也是跳转,但只能跳转比较近的距离(前后256个字节?),但这个命令本身只有2字节,相比jp3字节)可以节省一些空间。

这里D84A的值是06,所以继续运行。将b的值减1,给a赋值7F,然后调用程序0:389D,再给d的值加1

15-04.png

这里call是调用程序,表示跳到后面这个地址去运行,运行完一般会有一个ret返回的命令,再返回到下一行继续运行。

这里0:389D这个程序非常重要,它完整的运行顺序是这样的。

15-05.png

它的作用是根据de的值计算出一个MAP上的地址,然后把a的值对应的Tile写到上述MAP地址,从而实现文本的显示。具体的程序就不解读了,大家可以自己去分析一下。这里因为调用程序之前给a赋值7F,对应的是空白Tile,同时给d的值减了1,所以最终的效果是将当前要写字的位置上方清空。

接下来,将寄存器a的值取回来,也就是之前读出的文本的代码,然后将这个值先与67比较,再与70比较。

15-06.png

看一下码表,40-66是浊音,67-6F是半浊音,而前面我们已经判断过一次,a里的值要大于40,综合起来我们可以判断出这里的两个cp指令正是来判断浊音和半浊音的,也就是我们预期可以用来跳转到中文输出程序的位置。

简单看一下0:37FA0:381E这两个程序,他们分别给a赋值7071,然后调用程序0:3897

15-07.png

而程序0:3897是不是很眼熟,和刚才0:37A8几乎一样,将d1后调用程序0:389D,再给d1。区别是没有给a赋值,这里a就对应将要写到MAP上的Tile的编号。

15-08.png

看一下VRAM70对应的Tile是“゛”,71对应的Tile是“゜”,也就是浊音和半浊音的上标。通过0:389D程序,把对应的上标写到当前字符的上方,实现浊音、半浊音的输出。后面的程序就是再换算出对应的清音的码表编码。这里4E被计算为9D保存在a中返回。查看码表,9D对应的正是“と”。接下来将a的值减去80,对应到VRAM中的Tile编号,调用程序0:389D程序,把这个字符写到MAP上。

15-09.png

因为这里没有给d值减1,所以“と”是写在正常文本这一行。而如果之前a的值大于等于70,就会直接来到这里,输出单个的字符。

到这里,程序就完成了一个编码对应的文本输出。所以我们就可以把0:37B0这里修改为判断a的值后跳到我们的中文输出程序,输出中文后再跳到0:37BF

后面的程序暂时还看不太明白,最终会来到一步ret退出程序,之前这些都是属于程序0:3786。我们先放一放,再往前面去看一看。

我们从读取文本的断点往前追踪,很快就看到,确实是调用了程序0:3786

15-10.png

程序0:3786先调用程序0:375C,先判断D84A的值是否06,然后从D8B8-D8BB读出debc的值,接下来就到了我们刚才分析的文本读取输出。

15-11.png

文本的地址hl在进入程序之前就已经存在了,debc是程序后重新读出来的。并且之前已经发现de的值和文本在MAP上什么地方写Tile有关系,我们就再看一下它们是如何变化的。

点击游戏屏幕,观察游戏在每一次运行到0:378A时,寄存器中数值的变化。可以看到hl的地址每次增加1,这个可以理解,要按照顺序把文本一个一个读出来。另外一个变化时每读写一个字,b的值会减1e的值会加1。这应该是程序0:3786中下面这两句运行的结果。

15-12.png

按照这个规律,如果输出4Tile的大字,因为编码变成了2字节,同时字符多占了一个字的位置,可能要给be额外的加11。这个后面写程序的时候要注意。


上一篇:GB/GBC汉化经验分享之十四--文本指针
下一篇:GB/GBC汉化经验分享之十六--Rom的扩容
最新回复 (1)
  • 四级用户 橘霓暴 9天前
    0 2
    我觉得我会了
    • 老男人游戏网配套论坛
      3
        立即登录 立即注册
发新帖
本论坛禁止发布SWITCH和PS4相关资源,若有其他侵权内容,请致邮3360342659#qq.com(#替换成@)删除。