RetroGenY English

扩展码

RetroGenY 自己的金手指格式。普通金手指只能「往一个地址写一个数」;扩展码是一小段程序,能跟指针、能循环、能判断条件,还能做游戏用来藏数值的那些运算。

普通金手指哪里不够用

GameShark、Action Replay、CodeBreaker 是二十多年前给卡带设计的格式,擅长的就是「这里一直写 99」。可很多游戏的数据不在固定的地方:

  • 地址会变。宝可梦和很多 RPG 的背包、队伍、金钱挂在指针后面,每次存档、甚至每次开菜单地址都可能变。写死地址的金手指今天能用,明天就悄悄失效。
  • 数值是加密的。火红、叶绿的金钱和每个存档自己的钥匙做了异或。直接写 999999,读出来是个乱数;得先读出钥匙再算。
  • 一整排格子。把 42 格背包都改成 99 个,要写 42 条码,捡起一样东西顺序一变就全乱了。
  • 条件。「按住 L+R 才生效」「只改有东西的格子」「只在战斗里」,基本做不到。

扩展码就是为这些情况做的。

能做什么

  • 跟指针:和游戏自己找数据的方式一样,换了存档照样能用。
  • 循环:用 repeat 42 … end 走遍背包、队伍、电脑箱子。
  • 判断条件:比较内存、测试某一位、跳过空格子,还能写「否则」else。
  • 按键触发:只在按住某组按键时执行,做「按 L+R 回血」这种。
  • 计算:8 个寄存器,加减乘、与或异或、移位都有,足够按游戏的方式把数值加密好再写进去。
  • 复制:把一个值或者一整排格子从别处拷过来。
  • 改游戏本身:用 rom 行改程序,做单改数值做不到的效果(商店 1 块钱、穿墙)。
  • 给玩家选项:写一行 option,金手指列表里就会出现下拉菜单,玩家直接选「×2 / ×5 / ×10」,不用改码。
添加扩展码在金手指列表里选选项

左:边输入边检查语法。右:带选项的码,在列表里就有下拉菜单。

真实的例子

火红(英文 v1.0)金钱 999999。钱挂在指针后面,还用存档的钥匙加了密,普通金手指做不了:

hhcode 1
r0 = [0x03005008]        # 存档块1:钱、道具都在这里
r1 = [0x0300500C]        # 存档块2:钥匙在这里
r2 = [r1 + 0xF20]        # 读出钥匙
r2 = r2 ^ 999999         # 用钥匙把 999999 加密
[r0 + 0x290].32 = r2     # 写进钱

背包里每样道具都变成 99 个,空格子跳过:

hhcode 1
r0 = [0x03005008]
r1 = [0x0300500C]
r2 = [r1 + 0xF20]
r2 = r2 ^ 99             # 数量也是加密的
r0 = r0 + 0x310          # 道具口袋,42 格
repeat 42
  if [r0].16 != 0        # 空格子跳过
    [r0 + 2].16 = r2
  end
  r0 = r0 + 4            # 下一格
end

按住 L+R 回满血(地址仅作示意):

hhcode 1
if button L + R
  [0x02024330].16 = 999
end

让玩家在金手指列表里自己选:

hhcode 1
option 倍数 = 2 { 2 ×2; 5 ×5; 10 ×10 }
[0x02001000].8 = $倍数

怎么用

  1. 在游戏里打开金手指面板,进「我的金手指」,点 +。
  2. 起个名字,输入或粘贴代码。第一行必须是 hhcode(或 hhcode 1)。
  3. 编辑器边输入边检查每一行。写错了会指出是第几行;没问题会显示「语法正确」。
  4. 看不懂一段码,比如别人发给你的?点 「查看代码说明」,它会用大白话把这段码念给你听。
  5. 不想从零写?打开 「扩展码模板」:锁定数值、指针链、连续格子、复制数值、遍历表、条件写入、否则分支、按键触发、位开关等等。选一个,改改地址和数值就行。
  6. 点「添加」,打开开关。和其他金手指一样,每一帧都会执行。

很多时候根本不用自己写:内存工具能帮你找到数值,并直接生成跟指针的扩展码。

语法速查

写法作用
[addr] = v写入(默认 32 位)
[addr].16 = v指定宽度写入:.8 / .16 / .32
[addr] = 40,42,0F连续写一串字节
[addr].16 = 99 repeat 30 step 4写 30 格,每格隔 4 字节
[dst].16 = [src]复制一个值
[addr].16 += 5读出、修改、写回:+= -= &= |=
r0 = [0x03005008]把内存读进寄存器(指针链的第一步)
r0 = [r0 + 0x14]再跟一层指针
[r0 + 4].8 = v按寄存器偏移写入
r0 = r0 + 4运算:+ - * & | ^ << >> 和取反 ~
repeat 30 … end固定次数循环
if [addr] == v … end条件:== != < > <= >=,无符号 <u >u,位测试 & 和 !&
if button L + R … end按住这些键时才执行
… else … end否则
rom [addr].16 = v改游戏程序本身(重进游戏才会恢复)
option 名字 = v { v 说明; … }在金手指列表里出现的选项,码里用 $名字
# 文字注释

完整的规则在 App 里:金手指面板 ›「详解」› RetroGenY 扩展码。

写错了也不怕

  • 不会卡死游戏。每趟最多执行 20 万条指令,写错的循环到点就停。
  • 宽度很宽容。数值装不下你写的宽度时会自动加宽并提示你,不会悄悄截断。
  • 会提醒可疑的写法,比如一个看起来像别的格式里「偏移量」的地址。
  • 写的就是数值。十进制和十六进制一样,写的是数本身,不用管字节顺序。

整个金手指库都是扩展码

自带库里 1700 多个游戏、9000 多条金手指已经全部转成扩展码,每一条都和原码逐字节核对过。有些游戏还加了旧格式写不出来的手写扩展码,比如火红的加密金钱、整个背包。GameShark、Action Replay、CodeBreaker 照样能用,和以前一样。