最近在研究wii游戏的汉化,这篇文章很不错,所以转载之。不过不知道HyperIris前辈还会不会出下。
GC、Wii汉化技术漫谈(上)
GC、Wii汉化技术漫谈(中)
---------------------------------------------------------------------------------------------------------------------------------------------------------
GC、Wii汉化技术漫谈(上)
预备知识:GC、Wii使用的是PowerPC 750家族处理器,内存数据使用Big-Endian,在PC上处理的时候要注意。
首先是GC ISO格式:GCM,先说这个,这是修改游戏内容的第一步。
GC游戏所用的格式被称为GCM,文件尺寸为1,459,978,240 字节,其实质内容并非传统意义的ISO,而是一个自定义结构的BIN文件,如下(信息来自于YAGCD,http://hitmen.c02.at/files/yagcd/yagcd/chap13.html#sec13 ):
偏移 尺寸 内容
0×00000000 0×0440 Disk header (”boot.bin”)
0×00000440 0×2000 Disk header Information (”bi2.bin”)
0×00002440 (0×2000 ?) Apploader (”appldr.bin”)
FST (’fst.bin’)
其中我们关心的是两个内容,游戏的可执行程序和文件分配表,这两个数据保存在Disk header,下面是Disk header的详细内容,其中关键内容已经用红色标记出来:
开始 结束 尺寸 内容
0×0000 0×0003 0×0004 Game Code
1 Console ID
2 Gamecode
1 Country Code
0×0004 0×0005 0×0002 Maker Code
0×0006 0×0001 Disk ID
0×0007 0×0001 Version
0×0008 0×0001 Audio Streaming
0×0009 0×0001 Stream Buffer Size
0×000a 0×001b 0×0012 unused (zeros)
0×001c 0×001f 0×0004 DVD Magic Word (0xc2339f3d)
0×0020 0×03ff 0×03e0 Game Name
0×0400 0×0403 0×0004 offset of debug monitor (dh.bin) ?
0×0404 0×0407 0×0004 addr (?) to load debug monitor ?
0×0408 0×041f 0×0018 unused (zeros)
0×0420 0×0423 0×0004 DOL偏移
0×0424 0×0427 0×0004 FST偏移 (”fst.bin”)
0×0428 0×042B 0×0004 FST尺寸
0×042C 0×042F 0×0004 最大FST尺寸
0×0430 0×0433 0×0004 user position (?)
0×0434 0×0437 0×0004 user length (?)
0×0438 0×043b 0×0004 (?)
0×043c 0×043f 0×0004 unused (zeros)
其中,DOL就是游戏的可执行文件,FST就是文件分配表。
OK,想Patch DOL,做ASM Hack的话,DOL的位置就这么确定了。下面我们来说FST,修改替换游戏文件必须经过这个(当然你可以把文件位置硬编码到补丁里面,但是这样就无法处 理经过减肥和压缩的GCM)。
FST格式:
开始 结束 尺寸 内容
0×00 0×0c 0×0c 根目录
0×0c … 0×0c 文件项
N项
… … … 字符串表,文件和目录名
FST文件项含义:
偏移 尺寸 内容
0×00 1 标志位,0:文件 1:目录
0×01 3 文件名,在字符串表中的偏移
0×04 4 文件偏移或者目录相对于父目录的偏移
0×08 4 文件长度或者内容数量(根目录)或者下一个目录偏移
GCM的关键格式我们都知道了,具体怎么操作呢?下面是Pascal伪代码(代码摘自Nitendo GameCube GCM Patch Tool v3.5 HyperIris)。
TFSTItem = packed record
ItemType: byte; //0 file; 1 dir
FileName: array[0..2] of byte; // Filename offset in string table
FileOffset: DWORD;
FileSize: DWORD;
end;
//读取FST信息:
Seek($0424, soFromBeginning);
Read(FstOffset, 4);
Read(FSTSize, 4);
//读取FST根目录
Seek(FstOffset, soFromBeginning);
Read(FSTRoot, 12);
FstItemCount := ToLeDWORD(FstRoot.FileSize);
//读取所有的FST数据
Seek(FstOffset, soFromBeginning);
GetMem(FST, FstItemCount * Sizeof(TFSTItem));
ReadBuffer(FST^, FstItemCount * Sizeof(TFSTItem));
OK,这样我们就可以在内存中直接遍历FST查找我们需要的文件信息了。
以上是纯技术讨论,其实有现成的工具(比如GC-Tool)可以提取替换GCM中的内容,但是我们的目标显然是直接修改GCM,编写自己的补丁。
有了打开GCM文件的钥匙,我们就可以一窥游戏的内容了。下面我们来说说GC数据文件格式,注意这些格式要么是硬件要求的,要么是任天堂官方SDK 推荐的,大多数第三方会用自己的打包和压缩格式,处理这样的文件需要进行必要的二进制分析或者调试。
压缩格式:
yay0,yaz0:这是任天堂的传统压缩算法了,自N64时代就广泛应用,N64、GC、Wii,DS游戏中都可见到,处理的工具也很多,不多废 话了。
cms:这个压缩格式在GCFE中使用,属于自定义压缩算法。
cmp:这个用于Metroid Prime,属于自定义压缩算法,在Metroid Prime 2/3中已不再使用。
文本格式:
bmg:常汉化DS游戏的会很眼熟,没错,基本上没什么区别。
字库:
bfn:常汉化DS游戏的会很眼熟,没错,基本上没什么区别。
图像格式:
GC、Wii硬件至少支持14种图像格式,其中游戏文件使用的是13种,如下:
I4 (4bit单色)
IA4 (4bit单色带透明通道)
I8 (8bit单色)
IA8 (8bit单色带透明通道)
CI4 (4bit索引)
CIA4 (4bit索引带透明)
CI8 (8bit索引)
CIA8 (8bit索引带透明)
RGB4A3
RGB5A1
RGB565
RGBA8
S3TC
以上各种在游戏中均有大量使用,具体解码方法,可以参考Dolphin-emu的图形插件。
但是汉化中,基本不会遇到修改索引颜色的图片。
好了,这样我们就可以拆开GC游戏,用CT之类的工具来折腾了。
GC、Wii汉化技术漫谈(中)
在这一篇中,我来说一下GC和Wii的硬件架构。
首先是GC,从硬件上来讲,GC十分的标准,简洁,高效。
NGC硬件架构:
大体上,NGC以Art-X Flipper为中心,北桥连接CPU,南桥连接24MB 1T-SRAM,东桥连接Audio DSP,Audio DSP另外连接16MB缓存。
事实上Audio DSP是集成在Flipper中的,PCB上看不到。从这种角度上看,似乎很像pc。
深 入Art-X Flipper,这块PCB上最大的芯片,集成了内存控制器,GPU,Audio DSP。注意,CPU和GPU都直接连接到内存控制器。在NGC架构中,没有显存和内存的区别,24MB 1T-SRAM 同时存放代码,贴图,顶点乃至外部FrameBuffer等等数据。这24MB 1T-SRAM用得很出彩。CPU可以很方便的对GPU处理过的数据再次进行处理。
1T-SRAM 具体原理就不介绍了,它最大的特点就是与DRAM相比,没有随机访问的延迟,不像DRAM那样需要等待大量时钟周期才会读取到需要的数据。
NGC GPU有个特殊的设计,就是Flippe中嵌入式的3MB 1T-SRAM,这个缓冲区被用作GPU内部的超高速缓冲,保存有z-buffer之类的数据,渲染中间过程的临时数据放在这里,可以不用抢主存的带宽。 注意,这个设计显然被ATI发扬光大了,XBOX360 GPU中也有这么个玩意,只不过容量大了不少。
NGC CPU Gekko是一块IBM PowerPC 750 + Paired Single多媒体扩展指令集,可以使用工业标准的c/c++,同时汇编语言也易于掌握。
有关于Paired Single的介绍,可以参考我写的IDA插件。
(http://hitmen.c02.at/html/tools_ida.html 或者 http://code.google.com/p/openhyper )
NGC GPU 从概念上类似于OpenGL,可以设置大量的状态,CPU通过专用FiFo向其发送渲染命令,即可完成渲染。
NGC Memory map非常的清晰:
0x00000000 - 0x017FFFFF 物理内存
0x80000000 - 0x817FFFFF cached 逻辑内存
0xC0000000 - 0xC17FFFFF uncached 逻辑内存
0xCC000000 - 0xCC00FFFF 硬件寄存器
0xE0000000 - 0xE0003FFF L2 cache
0xFFF00000 - +1MB IPL(BIOS BOOT ROM)
由于设备全部共享24MB主存,所以主存被映射到三个地址空间(区域),为不同的目的服务,例如程序代码使用cache映射地址。
所有设备的硬件寄存器都依次映射到寄存器地址区域,详细的分布也是很有规律的。
至于L2 cache为什么也会映射到全局地址空间,这个并没有文档介绍,个人估计是为硬件调试器使用的。
有了这个内存影射表,我们就可以在调试中知道自己所处的位置。
Wii 硬件架构:
本图片来自于http://wiibrew.org/wiki/File:Wii_hw_diagram.png
从这张图上,我们可以看到,Wii比GC主要多出了64M DDR3的内存,多出一个IOP,也就是ARM9(图中被称为Starlet的部件),这对于汉化的影响我们将在下篇中提到。