Aug 24, 2010

[转]不求人!DIY 自己找寻 NDS 游戏金手指密码_2 (ARDS 条件判断式指令)

原文地址:http://www.ndsbbs.com/read.php?tid=119933

前 言
在第一篇教程推出后,有朋友反映了一个问题,就是使用过 HasteDS ,发现连系模拟器后,
0x02000000 的定址不准确。
另外有朋友说所用的烧录卡不支援金手指,只能使用作弊补丁。
有关 HasteDS 定址问题,大家可转用其他习惯使用的搜寻工具来搜寻作弊码,
而作弊补丁是以工具对修改后的 Rom 比较原 Rom 后产生的文件,
使用者只需以补丁工具使用该作弊补丁文件写入到原 Rom 即可,
本文(或往后的续篇)将不会详述及示范补丁工具的使用,只示范修改 Rom 的例子,
有关补丁工具的使用,请大家在网上查找一下,很容易就能找到补丁工具及使用说明的了。

另外有朋友向本人介绍一个搜寻工具 Renegade v1.67
优点 - 是支援 No$gba 2.4a、搜寻选项及过滤条件很多,与及可以在该工具使用金手指码...
缺点 - (个人认为)是界面复杂及太多与 NDS 无关的功能选项。
有兴趣使用的朋友可在网上找来测试使用。

本来前天就已写好这第二篇的内容,示范把作弊码找出后转为 DipStar 金手指,
并配合 Slot-2 卡使用,及验证 HasteDS 定址的准确性,当完成原稿及截图后,
在版区看到有另外的热心朋友曾发布修改教程,用的是 GM8,从回帖中也看到此作弊修改工具,
颇受大家欢迎,也很多朋友长期使用这个,而且,似乎更多朋友对静态修改感兴趣,
因此,本人把已写好的原稿及截取的图片删除,重新编写本篇内容,题材也改变了,
不进行验证 HasteDS 定址的准确性了。(反正验证后的结果就是确定间中会出现定址错误),
DipStar 范例也不要了,有使用支援 DipStar 烧录卡的玩家,应该早已懂得使用的了。




Action Replay DS 条 件 判 断 式 指 令
依照第一篇教程的范例,相信学习者都已懂得自己找寻作弊码了,
但若果只能单调地反覆不停对记忆体写入数据,显然不足以应付不同情况下的使用需要,
幸好 ARDS 提供条件判断式指令,这就令 ARDS 金手指的应用范围大大提高,
现在就先来介绍一些常用的条件判断式指令。

9XXXXXXX ZZZZYYYY ( 等 于 )

这是条件断判式指令中最常用的一个,检查 0XXXXXXX 位址上的值是否等如 YYYY

使用场合:
1.依按键值来启动作弊码 (这里的 "作弊码" 狭义解作 "直接写入记忆体" 的金手指码)。
2.当变量达到指定的值才启动作弊码。

使用例子:94000130 000001BB  检查使用者是否按下 Select + L + Up 键
220031C0 000000FF  把 1 Byte 数据 0xFF 写入到位址 0x020031C0
D0000000 00000000  结束

指令原型:if YYYY == (not(ZZZZ) & [XXXXXXXX])
指令意思:假如 2 byte 数据 YYYY 等如 not(ZZZZ) & XXXXXXXX 位址上的 2 byte 数据。

== 是 "等如" 的意思,not& 是运算符,& 也等同 AND,用法如下:

Not 参数只有一个,用来把真假值反转,
Not(1) = 0
Not(0) = 1

AND 的参数有两个,要两个都为真值结果才会是真,否则就是假。
1 AND 1 = 1
1 AND 0 = 0
0 AND 1 = 0
0 AND 0 = 0

就以上面的例子 94000130 000001BB 来详细说明,
4000130 即是位址 0x04000130 ,也就是键盘I/O影射区的位址,
0x01BB 是 Select + L + Up 的按键值。
NOT(0000) = FFFF  
(不要误认为应该是 1111 ,因为 0x0000 是 16 bit,二进位是 0000000000000000,
反转成为 1111111111111111,转换为十进位是 65535,转换为十六进位就是 FFFF。)
FFFF 的二进位表示式是 1111111111111111
01BB 的二进位表示式是 0000000110111011
FFFF01BB 进行 AND 运算,如下:
1111111111111111 (0xFFFF)
0000000110111011 (0x01BB)
-------------------------    
0000000110111011 (0x01BB)

如果执行指令 94000130 000001BB 时,使用者是按了 Select + L + Up 键的话,
代入数值 01BB == (not(0000) & 01BB)
就合乎了 YYYY == (not(ZZZZ) & [XXXXXXXX]) 的比较条件,所以能执行下面其他的指令。

好像挺复杂般,其实不然,大家只要把 9XXXXXXX ZZZZYYYY 理解成这样:
( 在 ZZZZ0000 的情况下 )
假如 2 byte 数据 YYYY == (等于) 位址 0XXXXXXX 上的 2 byte 数据,
就执行其下的指令。
这样去理解是否立即简单了许多呢?

本例子中的 D0000000 00000000 用作条件判断式指令下的结束,
作用是载入先前的执行状态 (如果不存在,就保持在上面指令执行时的状态),
很多朋友都曾见过这类金手指,都是以这个或是 D2000000 00000000 作结束的,
由于作出比较时,得到的结果会影响状态位,所以当一个比较条件下其他的指令中,
又包含条件判断指令,这时候状态位对指令的执行权会作出影响,
所以就要决定因应状态位的应用,而决定使用不同的结束指令。
D2000000 00000000 它的其中一个作用是结束时清空状态位、偏移值及 C 码设定。
C 码配合的话 Dx 的值作为设置,挺复杂的说,由于不常用,故对于 C 码及 Dx 的配合,
就不予以解说了。

好像又越说越乱了,大家除非像编程般的运用他们,才要彻底的理解他们的分别及作用,
否则一般使用上,习惯以 D2000000 00000000 作为条件判断式指令下的结束就可以了。


*** 下面的指令不再以上面那种麻烦的方式作详述,只以最简单、最易理解的方式去说明***


3XXXXXXX YYYYYYYY ( 大 于 )
假如 4 byte 数据 YYYYYYYY > (大于) 位址 0XXXXXXX 上的 4 byte 数据

4XXXXXXX YYYYYYYY ( 小 于 )
假如 4 byte 数据 YYYYYYYY < (小于) 位址 0XXXXXXX 上的 4 byte 数据

5XXXXXXX YYYYYYYY ( 等 于 )
假如 4 byte 数据 YYYYYYYY == (等于) 位址 0XXXXXXX 上的 4 byte 数据

6XXXXXXX YYYYYYYY ( 不 等 于 )
假如 4 byte 数据 YYYYYYYY != (不等于) 位址 0XXXXXXX 上的 4 byte 数据

7XXXXXXX ZZZZYYYY ( 大 于 )
( 在 ZZZZ0000 的情况下 )
假如 2 byte 数据 YYYY > (大于) 位址 0XXXXXXX 上的 2 byte 数据

8XXXXXXX ZZZZYYYY ( 小 于 )
( 在 ZZZZ0000 的情况下 )
假如 2 byte 数据 YYYY < (小于) 位址 0XXXXXXX 上的 2 byte 数据

AXXXXXXX ZZZZYYYY ( 不 等 于 )
( 在 ZZZZ0000 的情况下 )
假如 2 byte 数据 YYYY != (不等于) 位址 0XXXXXXX 上的 2 byte 数据

BXXXXXXX 00000000 ( 读取记忆体数据设为偏移值 )
把位址 0x0XXXXXXX 上的 4 byte 数据,读取成为偏移值

这个是很实用的一个指令,希望大家能了解及活用它。

使用场合:
1.如果在游戏中要锁定很多变量值(例如道具、收集品)时,用这个很方便的。
2.如果同一变量的位置不固定时,先找出变化位址的存放点,用 B 码读取成为偏移值,
(其实个人认为这个称为变量基址才更贴切,以这个变量基址 + 偏移值访问不同的变量)
就不怕下次再玩时,作弊码失效的了。

使用例子:
(以 Mario Kart DS 的作弊功能 "按 X 获得道具 <雷暴>" 来说明)
Press X for Thunderbolt
923d629a 00000400  读取 (被游戏程序处理过的)按键值来作判断
6217bc2c 00000000  假如位址 0x0217BC2C 上的值不等于 0x00000000  
b217bc2c 00000000  在位址 0x0217BC2C 读取 4 byte 数据作为偏移值 (变量基址)
2000004c 00000008  到变量基址 + 0x4C 偏移值的位址,写入 1 byte 数据 0x08
20000054 00000001  到变量基址 + 0x54 偏移值的位址,写入 1 byte 数据 0x01
d2000000 00000000  结束

补充:
1.在本例子的游戏中查看位址 0x023d629a 的值,当按下不同的键,这个值就会改变的。
2.使用 B 码后,如未遇到结束指令,其后的 "直接写入记忆体指令" ,
都会一直以变量基址 + 偏移来定址及写入的。 

EXXXXXXX YYYYYYYY
从现时的指令位置 + 8 的位址,读取 YYYYYYYY byte 数据到 0x0XXXXXXX + 偏移值的位址上。

FXXXXXXX YYYYYYYY
从偏移值的位址,读取 YYYYYYYY byte 数据复制到位址 0x0XXXXXXX
使用 F 码前,需要先使用 D3DCB 码以取得偏移值。
D3000000 ZZZZZZZZ  设 4 byte 数据 ZZZZZZZZ 为偏移值。
DC000000 ZZZZZZZZ  偏移值 = 偏移值 + ZZZZZZZZ (offset = offset + ZZZZZZZZ)

活用上面的条件判断式指令,一般的应用上来说,是够用有余的了,就说到这里好了。




p.s. 本来跟部份朋友说了将在本篇中讲述修改 Rom 的,不过写完上面这些巳实在太累了,只能留待下一篇才继续了,抱歉!

0 comments:

Twitter Delicious Facebook Digg Stumbleupon Favorites More

 
Powered by Blogger