本帖最后由 supercolin 于 2011-6-22 10:27 编辑
从我的blog上搬过来给感兴趣的筒子们研究吧。
http://colinxu.ycool.com/post.4240218.html
附上幼圆字体文件,配合翻译过的文本才能变中文,别以为放进去就自动汉化了
http://www.rayfile.com/en/files/2c7ba84f-9b64-11e0-a0bc-0015c55db73d
关于翻译文本:
1. 用dungeon siege 3 OAF files extractor打开data_localized_en.oaf,到处需要翻译的文本。
2. 用dungeon siege 3 translator翻译文本std文件。
3. 用dungeon siege 3 OAF files extractor打开data_localized_en.oaf,选择patch, 输入文件名,指定包含翻译后文本所在的文件夹,完成。替换掉原来的data_localized_en.oaf, 即可。
提示:任何文件操作,要养成先备份的良好习惯。
*******************************************
作者:Colin Xu
日期:2011/06/20
声明:本文内容出于对技术的兴趣和个人爱好撰写,请勿将本文用于任何商业目的。
链接:http://colinxu.wordpress.com/2011/06/21/dungeon-siege-3-%E6%B1%89%E5%8C%96%E6%8A%80%E6%9C%AF%E5%88%86%E6%9E%90/
转载请保持完整并注明出处。
有心情做这个,绝对是出于对前作的情节。不过鉴于本作与前作有较大差别,所以我还是建议用"基于前作故事背景的新游戏"这样的态度来看待,这样就能够享受每一代游戏不同的乐趣,而不用去纠结是不是正统。
先来看看游戏目录的整体架构。
比较显眼、让人觉得有文章的就是:
Dungeon Siege III.exe,可执行文件
一堆*.oaf文件,看上去很大的样子,显然游戏的主要资源都在这些OAF文件里了。
data文件夹,里面看到movies,恩,*.bik视频文件,不用说这就是所有过场动画了。如果你有Gabest分离器RadGtSplitter.ax和bink video的动态库binkw32.dll,用kmplayer就能直接看所有动画了。
这次的目标是探索如何汉化,并且理解DS3的资源,因此感兴趣的是那一堆*.oaf文件。
关于OAF文件的细节,参加上一篇博文:
http://colinxu.wordpress.com/2011/06/17/dungeon-siege-3-oaf-%E6%A0%BC%E5%BC%8F%E5%88%86%E6%9E%90/
这里要补充两点:
1.OAF文件的分析离不开Raptor的解包工具dungeon siege 3 OAF files extractor。站在前人的肩膀上继续研究,省去了从头开始的重复工作,所以要感谢Raptor
的贡献。不过也要说明的是,Raptor的解包工具也有一些问题,比如会把未选择的文件也解包出来,在打包的时候会占用不必要的空间,等等。
2.OAF作为压缩包,其效果和解压至游戏目录的data\下是一样的。比如把语言文件data_localized_en.oaf用extractor解压到data目录下,形成这样的结构:
\data\global\loot_system\*.*
\data\global\strings\*.*
然后把data_localized_en.oaf删掉,那么游戏一样可以运行,游戏的所有字符一样可以显示。这样就很大程度上方便了修改,而不用每次修改都去打包。当然作为发布,自然还是单一文档更有优势,游戏运行前都会解压到内存中,就免去了许多小文件的读写造成的效率低下。
OAF文件的分工:
可以从名字中猜测,也可以解包查看,结果如下:
base_item_init.oaf,基本名称的定义,这里只有定义和命名,没有具体的资源。
data_archive.oaf,最大的文件,包含所有的图形和素材资源、脚本等等。
data_localized_en.oaf,这是英文版的,根据语言不同文件也不同。包含游戏中出现的所有字符串。汉化主要就是汉化这里的字符串资源。
engine.oaf,engine咯,Onyx Engine用来render的主要部分,这个应该是不需要我们去碰的。
从易到难,就先来看看字符串的汉化,也就是大量的文本翻译工作。都在data_localized_en.oaf文件中了。如果选其他语言版本当然也是可以,每条字符串所在的文件名都是一样的,字符串ID也是一样的,主要是根据语言不同而显示不同。这一步很简单,把文件解包了,翻译好,然后选择打包或者就放在\data\下,就可以了。
改好之后可以很快看到效果,但如果你改的是中文字,用日语版改的人中文有些字符不能显示,而用其他语言版改的人中文完全不能显示。现在这个年代写的代码,除非特别不注意的,基本都不会是不能处理单字节字符造成的,所以基本都是找不到合适的字体来显示非西语字符。否则日文版为什么可以显示呢?
漏掉一件事。看看\data\目录下,是否有个game.oeisku文件,这个文件是用来选择语言和语音的。如果没这个文件,那就打开data_archive.oaf解压一份放到\data\目录下吧。然后修改一下game.oeisku,就可以自由选择语言版本了。我建议把汉化后的字符串资源命名为data_localized_chs.oaf,并在game.oeisku中进行相应修改,这样即不会影响其他语言,又能在各种语言之间自由切换。
已经说了,字符串文本的翻译只是大量体力劳动,没有很多技术门槛。关键难点还在于,如何让中文字符能正常显示。接下来就重点说这个。
如果你有日文版文本data_localized_en.oaf,那么解压出localized_fonts.gfx。如果没有,也没关系,素材包data_archive.oaf中同样有这个文件。
顺便提一下,data_archive.oaf中与字体有关的文件有4个:
localized_fonts.gfx,高分辨率用的字体库
localized_fonts_stddef.gfx,标准分辨率用的字体库
localized_fonts.scn,对上述的描述
gfxfontlib.gfx,其他字体库
我在有的版本的localized_fonts.scn里面,还看到了localized_fonts_ch.gfx并且被定义为manual load,感觉像是预留了中文版。
其实只要关注localized_fonts.gfx即可,其他文件有兴趣的自行研究吧,方法相同。
找个十六进制编辑器,打开localized_fonts.gfx,注意到前三个byte是
0x43 0x46 0x58
即字符CFX
这样的GFX文件,是Scaleform GFX格式的。如果签名是CFX,则表示该文件是压缩的SWF(flash格式);如果签名是GFX,则表示该文件是未压缩的SWF。
对于CFX,把它编辑成CWS;对于GFX,把它编辑成FWS。然后把文件扩展名改成SWF,如果能正常打开,就表示正常。
对于localized_fonts.gfx,把它修改成CWS就可以正常打开了。
这里提一下Scaleform GFX格式。这种格式其本质就是一个SWF(flash),但其中加了Scaleform自己的Tag,如果你不用它提供的工具进行编辑,或者不懂它的格式,修改后的文件是无法正常作为Scaleform GFX正常使用的。
改完文件签名后继续看一下这个文件。
既然是SWF,那么其第4个byte就表示编译发布时使用的flash版本。
紧随其后的四个字节表示SWF的大小,也包含文件头。如果是压缩的,那么这个大小表示压缩前的大小;如果是未压缩的,那么就等于当前文件大小。
这前面的八个字节是SWF的文件头。
由于是压缩的SWf,接下来的数据是由zlib压缩的数据流,必须先解压缩才能继续编辑。可以使用zlib压缩工具做单纯的解压缩,也可以找一款flash的decompile工具直接反编译这个swf,根据个人需要。我是直接当做zlib的压缩流来解的,然后拼在文件头后,组成完整的未压缩SWF。如果直接反编译会漏掉很重要的一部分,也是Scaleform GFX特有的一段Tag。
文件头:
43 57 53 09 F4 F7 00 00
; CWS,压缩的SWF,flash版本9,文件大小0xF7F4
解压后的zlib流:
78 00 05 5F 00 00 0F A0 00
; 帧的大小是Xmin=0,Ymin=0,Xmax=550,Ymax=400。为什么这么算,请自己读SWF的文档吧。
00 0C 01 00
; 帧率12,帧数1
1F FA 6F 03 02 00 00 00 0E 00 00 0F 6C 6F 63 61
6C 69 7A 65 64 5F 66 6F 6E 74 73 01 00 1E 00 00
00
这一段很有看头,Tag type是1000, tag length是31。标准SWF中并没有定义这一段,这一段就是Scaleform GFX自己的特殊tag。如果处理完SWF少了这一段,一定要手动加上,否则修改后的文件无法被识别。
往后都是SWF标准的tag了。
得到正常的SWF文件,就可以反编译进行修改了。可以用Sothink SWF Decompiler配合Adobe Flash,或者直接用Sothink SWF Quicker进行修改。
看它的ActionScript文件,可以知道,字体是这样使用的:
如果定义了dt1,dt2,...,dt6,这些文本框,则把它们作为font放入字体**。看上去有6个命名,其实只有3个文本框。
当要拿get_mapped_font_name时,把字符串表示的变量作为字体名返回给调用者。
当要拿get_localized_font_name时,把字符自己的字体返回给调用者。
由于我们改的是localized字符串,因此就要改dt1,dt2,...,dt6这些文本框中字符串的字体。比如我改的是幼圆。记得要把文本中的字符都嵌入。
然后重新发布为flash。这里还是要选未压缩的SWF。因为发布时不论是Adobe Flash还是Sothink SWF Quicker,都会抛弃不认识的tag,然后压缩。这样我们就没办法把Scaleform GFX自己的特殊tag一起压缩进去了。
发布为SWF后,记得要手工把那段tag type=1000的东西放在第一个tag段,并且修改文件表示为GFX(因为现在是未压缩SWF),修改文件大小(4-8个字节),然后重新命名为localized_fonts.gfx。
好了基本完成,可以测试一下效果:把该文件放到\data\gui\localized_fonts.gfx,配合改好的中文文本,这下汉字可以正常显示了吧~
最后还有一步,如果我们希望把文本和字体一起发布为单独的语言包,完全可以把这些做成一个文件。由于Raptor的工具还有点问题,我用的是自己的工具,通用性不太强,等如果有心情写个好的打包工具再放出吧。要向自己改的话,只要照我上一篇中说的文件结构改就可以了。
技术工作告一段落~我要真正开始玩DS3啦~~
|