原文地址:http://www.romhacking.net/docs/361/
工具下载:http://www.romhacking.net/utils/297/
ROM下载:这个自行baidu,我承认这方面比google强
某些没翻译的地方:
术语如sprite, char, tile。如果不懂也不用看这篇文章了。
其他如debugging console,翻译成调试控制台也很难过,知道意思就行了。
一个简单的教程 - 使用内存断点寻找图片数据
by Labmaster, 24/03/06
(译注:就是VBA-SDL-H的作者)
这是一个很简短的教程,它将告诉你如何使用VBA-SDL-H寻找图片数据。之前你需要
了解VBA-SDL-H的指令(看一下说明文档 :p)和一些GBA的硬件知识。有任何问题请
去ROMHacking.net问。
目标:塞尔达传说 - 缩小帽(标题画面的Logo)
第一步是寻找图片在VRAM中的位置,第一处寻找的地方是BG。在普通的VBA中运行游戏,
打开Map Viewer,看看是否在这几个BG中。(译注:此时使用Mode 1,共有3个BG,BG0-2)
在这个例子中,Logo(译注:The Legend of Zelda, The Minish Cap这几个字)并
没有在BG中,那么肯定在sprite中了。为了确认这点,打开OAM Viewer,不停移动滚动条
直到发现logo的一部分。
现在简要说一下GBA sprites的基础知识。它的图片存放在0x06010000, (OAM数据是
控制sprite位置,放大之类的,存放在0x07000000),现在打开Tile Viewer,然后
选择0x6010000 char base.这个时候预览窗口是全黑的,所以试着变化一下调色板,
直到出来些东西。你应该会看到构成logo的tile出现了(有3个不同的调色板,
The Legend of Zelda是红黄的,The Minish Cap是绿色的,还有剑的调色板)
现在我们需要找出来这些数据在ROM中的什么地方。这时就要用到VBA-SDL-H的内存写入
断点了。随便点击构成logo的tile(比如说Z的左上角)。Tile Viewer会告诉你它的
内存地址 - 06013020。
用VBA-SDL-H打开游戏,让intro运行,只要在logo出现前停下即可(打开Tile Viewer,
勾上Automatic update,可以看到intro运行期间logo并没有写入到VRAM中)。进入到
debugging console,输入以下命令下一个内存写入断点:
bpw 06013020 20
这条命令对06013020起始的20字节下了写入断点,其实对多少字节下断并不重要(你可以
设成1)。继续游戏,不一会儿会断下,显示如下:
Breakpoint (on write) address 06013020 old:00000000 new:00000000
Breakpoint (on write) address 06013024 old:00000000 new:00000000
Breakpoint (on write) address 06013028 old:00000000 new:00000000
Breakpoint (on write) address 0601302C old:00000000 new:cccc0000
Breakpoint (on write) address 06013030 old:00000000 new:eeccc000
R00=84000580 R04=00000004 R08=00000000 R12=03000090
R01=84000000 R05=00000030 R09=00000000 R13=03007ecc
R02=040000d4 R06=03001000 R10=00000000 R14=080addcf
R03=020244c4 R07=00000000 R11=00000000 R15=080adf40
CPSR=8000003f (N.....T Mode: 1f)
080adf3e 6890 ldr r0, [r2, #0x8]
我们怎么知道这个断是对的?如果你之前打开Memory Viewer观察过06013020的话,应该
知道的确是这些值。现在我们需要知道的是哪条指令触发了这个断点。在Diassembly
Viewer中,跳转到080adf3e,然后向上找找,触发这个断点的指令就是紧邻080adf3e
上面的那条:
080adf3c 6090 str r0, [r2, #0x8]
这条指令将r0的值写入到r02 + 0x8所指的地址中。你如果了解GBA IO寄存器就方便
多了。r02的值是0x040000d4,是控制DMA传输的寄存器(如果你不知道DMA是啥,放
狗搜吧)。0x040000D4 + 0x8 = 040000DC,这条指令写入了一个word,这就对应了
两个寄存器,DMA通道3的字数寄存器和控制寄存器。(我怎么知道的?GBATEK是
对GBA Hacker来说最有用的资料了)。DMA通道3的源地址寄存器是0x040000D4,所以
我们用下面这条指令看看它的内容:
mw 040000d4 (译注:偷懒点的话mw r2也行)
显示如下:
040000d4 088d6760 06013000 04000000 00000000 `g...0..........
040000e4 00000000 00000000 00000000 00000000 ................
040000f4 00000000 00000000 00000000 0080fd44 ............D...
...
数据来源自088D6760,注意到下一个word的值是06013000,看起来眼熟吧,这是目标
地址(040000d8是DMA通道3的目标地址寄存器)。
这篇短文到此就结束了。如果这篇东西你看起来不知所云,那你还是去买点更简单的
文章看吧。
致尊贵的买家(译注:老外也搞购买帖):尽管上至下断为止的步骤对大多数游戏都是
通用的(只不过你用Tile Viewer找的话,图片可能在另一个Character bases中),
但是各个游戏将数据写入VRAM的方式是不同的。有些可能使用Software Interrupt (SWI)
去复制或者解压ROM里的数据,有些还可能有自制的解压函数去解压图片(有些直接
写入到VRAM,有些写入到WRAM,然后再用DMA或者SWI复制到VRAM,甚至用stmia/ldmia
指令来复制),所以这些都要靠你来分析断下前发生了什么。我会再写一些针对其他游戏
的类似教程,这样你就能了解这些可能的工作方式。(译注:但是坑了)