汉化日记(1)—-《超·占事略决2》的源代码级跟踪 by funlove

暗黑兔 发表于 2009-10-10 16:34 | 来源: | 阅读

汉化日记(1) B1z7r0Rm,
—-《超·占事略决2》的源代码级跟踪 “Q; Vy t
>,c’Z<TM
by funlove (funslove@163.com) ;rt\
2004.01.31  K,H�xe;-
@�[j%V ynf
要研究的GBA Rom为0551号,Shaman King Card Game - Chou Senjiryyakketsu 2 (J).gba j&�`D{z-c~
用 tlp很容易找到字库位置,而文本也是很简单的Shift-JIS码.由于我家中的电脑一运行Magicwin就死机,加上也是第一次认真地研究一个 Rom,经验太少,一直没能找到文本位置.今天用no$GBA做了跟踪调试,找到了文本,下面把记录的跟踪过程与大家共享,希望能对大家理解GBA游戏的 运行方式有一定的帮助. =T#?:J#a
cp4~`X
目标:找到字符和编码的对应关系(其实就是Shift-JIS码). E4xybVo@
VaTA|=[;
打 开游戏进入对话场面,按F5切出,再按一次F5,在"BG 3"这个标签上可以看到文本.将鼠标移到字上,记下右边出现的Tile Address(如06002980).于是想到可以在这里设断点,当被改写时中断.按Ctrl+B,输入[06002980]!表示向地址 06002980写数据时中断.点击游戏画面继续运行,会在下面的语句后面中断: g\@zQ^O?
08001976 str r0,[r2,8h] ;将r0的内容储存到内存地址r2+8处 E=qfI>2U&
其中寄存器r2=040000D4,r0=80000020,这句话为什么会对06002980产生影响呢?这需要对GBA的内存做一点了解.在GBA系统参考中可以看到,从04000000h开始是寄存器的镜像区域.进一步查寄存器表: K#dG’/M|Pb
寄存器地址 内容 (YHK,aC>u
040000D4 DMA3源地址 aa\?k\h’7X
040000D8 DMA3目标地址 {N@tJ,Fh{
040000DC 字计数 6tup^Rlo;$
其中,从040000DC开始的数高端第二位,也就是80000020的最高字节0100中的”1″,是系统的执行位(这个是我的猜测).于是我们在数据窗口中找到地址040000D4处,对应的数据为: k<%y+v
040000D4 03007D48 4J$dG l#f
040000D8 06002980 ^P owL :
在这里了!设置执行位以后,系统自动把从03007D48h开始的20h个字节移动到06002980h,做为一个Tile. x24&mWgU
b&.3u�ls6
下 一步就看03007D48这个地址了.猜想它指向字模,那么随着文本变化,这个地址的应该变动指向不同的字模.但继续进行游戏,几次中断以后发现 03007D48这个地址一直没变,看来这是一个Tile的临时存放区.于是再次按Ctrl+B,输入[03007D48]!,观察它指向的Tile内容 的变化. &H?Vlx Ix
(+;%zh-
在此中断: kTo{W]9]
08006DF0 strb r0,[r2] ;将r0的一个低字节内容储存到内存地址r2处 iLf* m~Q
其中r0=00,r2=03007D48. tdnd~�WSR
看来这次是直接写内存了.按几下F7就发现正处在一个循环中,其作用是将从03007D48h开始的3Fh个字节赋值.代码如下: ‘BNZUuUl

复制代码

  1. 08006DE8 mov r2,r13
  2. add r2,r2,r3
  3. add r2,4h
  4. ldrb r1,[r4]
  5. ldrb r0,[r5]
  6. and r0,r1
  7. strb r0,[r2]
  8. add r4,1h
  9. add r3,1h
  10. cmp r3,3Fh
  11. ble 08006DE8h

)Z63 cr/
这段代码很简单,可以看出,r4指向的就是字模地址. ivPX_#QI
’ y_2″
r4中的地址又是怎么来的呢?向前看,有: Ve t<,;Te
08006D9C push r4-r7,lr D~@lpcI
开始进栈了,说明这很可能是一个函数的开始.在这个语句上点击设上断点.从这里开始,有: 9a{9|p>L
08006DA4 lsl r0,r0,10h ;左移16位 fx/If
08006DA6 lsr r0,r0,0Ah ;右移10位.这两句的作用就是将r0左移6位,即乘以64(一个8*16Tile的大小).之所以又左移又右移的,是要利用左移将两个高字节清零 IdciGS6 t
08006DA8 ldr r1,=8275888h ;给r1赋值 p *GAs C
08006DAA add r4,r0,r1 ;r4的值就是这么来的 UUxP4
显然,r4=r0+r1.其中,r1=8275888h,猜想它就是字模的地址.而r0是字模的偏移,将它重新右移6位,就是字模的编号. ?f=7F %
通 过中断,观察一句话中几个连续的字模编号,如35 35 F7 75 54.猜想在Rom中直接储存编号,于是先后尝试用单字节方式搜索(3535F57554)及双字节方式搜索(35003500F500750054), 但都失败了.相关搜索也不管用.看来我们还需要继续追溯r0内容的来源. ]H=P( Z -
IYB;X
再向上,又有一个循环: K?,`gCN}v

复制代码

  1. 08006D68 lsl r0,r3,1h
  2. add r1,r0,r4
  3. ldrb r1,[r1]
  4. lsl r1,r1,8h
  5. add r0,1h
  6. add r0,r0,r4
  7. ldrb r2,[r0]
  8. orr r2,r1 ;r1和r2分别存放字符编码的高低位
  9. cmp r2,r5 ;r5就是要显示的字符编码了!
  10. beq 08006D94h ;这是循环的出口
  11. add r0,r3,1h
  12. lsl r0,r0,10h
  13. lsr r3,r0,10h ;这两句又是变相清零
  14. cmp r2,r6 ;r6=4544h,看来这是某个特殊控制字符
  15. bne 08006D68h ;这是上面的控制字符的出口

[3io6XG x@
其中,r4=08301D08,在这里的数据如下: n]bxG8~t
81A681A181978187… r%^XOw<’
猜想这就是码表,在Rom文件中搜索,终于找到了!将r5中的编码值和导出的字模位置做比较,就可以根据字模推出整个码表了.后面的工作和源代码没什么关系,就略去了. [ jgC`
cb9@ 0^-
总的看来,可以知道在这个游戏中,是这样把Shift-JIS码最终变成字符显示出来的: BaE}|4
(1)在码表中查找与字符编码相同的,相应的给一个字符编号. <F+9#-
(2)根据字符编号,找到字模的地址,并通过一个循环,将字模内容复制到03007D48h处. \h7XdmA]~
(3)通过设置寄存器,将03007D48h处的内容复制到Tile地址(如06002980). Aq{7WA
a8r+G]Z
源代码级的跟踪调试就好像PC上的加密解密,需要一定的汇编知识,经验和耐心.上面我采用的是从结果一步步找原因的方法,旨在抛砖引玉,希望有能力的汉化者能从更高的角度创造出更完美的汉化. 3G-f+HN^E

关键字:
喜欢兔友汉化组的文章,那就通过 RSS Feed 功能订阅阅读吧!

我要评论

*

* 绝不会泄露



返回首页 | 关于我们 | 联系我们 | 广告合作 | 网站地图 | 友情链接 | 版权声明 | 模板设计