2015-12-05游戏 知乎好玩就好玩在总有这么有趣的问题。 比起你在其它地方能找到的信息,我会稍微讲得详细那么一点点,至少比各种流言更靠谱一些,但是受限于专业水平,这个答案并不完美,权当抛砖引玉好了。知乎上程序员多,总有能帮我补充的。 —————————— 我先从一个有点感人的故事讲起吧。图少字多,见谅。 这个故事讲的是一位 「Cheat Finder」 ——也就是热衷于研究「作弊码」的玩家。故事有点长,但我实在希望更多玩家知道这个人。 所谓「作弊码」你大概能猜到是什么意思,就是通过非常规的方式修改游戏内存,实现在游戏中作弊的效果,例如角色无限生命、瞬间获得强力武器等等。 当然,具体改哪里、怎么改,都是有讲究的,所以才会有人专门研究这个,他们寻找能够实现作弊的特定的「地址+值」的组合,测试,然后分享出来,以此为乐。 在这个圈子中,从1998年就致力于制作/收集/整理/分享MAME作弊码的Pugsy应该算得上是个大拿,他经常会发布最新版的作弊码合集。时至今日你下载到的各种第三方打包MAME中,作弊码部分基本都是从他的网站 「Pugsy's Cheats 」 ( http:// cheat.retrogames.com )抓来的。 然而今天的主角并不是Pugsy君,而是一名叫做 zakria 的网友,真名 Zakriya Aleem ,年龄性别国籍不详——看名字应该是阿拉伯裔男性。 2008年6月的一天,这位zakria在Pugsy的论坛上操着半生不熟的英语发了个帖: 「求『惩罚者』作弊」 。 ( http://www. mamecheat.co.uk/forums/ viewtopic.php?t=3008 ) 『惩罚者』街机上有个秘技可以杀死全屏幕的敌人,谁能发一下啊? 抱歉我英语很差但是Pugsy很厉害他找到了『Eswat』无限特殊武器的作弊码。这次我想要的作弊是在『惩罚者』中杀死屏幕上所有敌人,就像最新版作弊文件中那个『吞食天地2』清屏。( 代码 )谁能发一下『惩罚者』的吗? Pugsy当时回复道: 这个作弊很难实现。我倒是做了个改版ROM能快速清屏的,但bug太多了而且还会死机。总之我有空再看看吧。 过了3个月,可能是zakria发了私信询问研究进展,Pugsy再次回复了帖子(请注意文字的语气态度): 我已经说过了这个作弊很麻烦, 给我发私信求我给你RAM码也没用 : 1.我通常不看私信。如果你想要作弊码不如直接发帖子,得到回答的几率还高一点。 这次的话题我最后回答一遍,然后你自求多福吧 。 2.改RAM行不通,因为角色在内存中是动态分配的,它需要使用「相对地址」,或者在ROM中改一大堆东西。 我也说过了我试过改ROM然后发现要修改和测试的地方太多了,每一种扣血都有自己的代码,它们都需要被处理。我改了一点,就是之前说过特别bug的那个。 反正短期内我也不会再关注这个问题了 ,所以发给你看看,强调,特别bug。如果你想自己改的话,你最好去学学「68000汇编」和「MAME debugger」。你需要干掉所有跟敌人血量有关的sub.w d0,(36,ax)调用,有80个以上地方,而且说不定还得改别的。 ( 代码 ) 就在这个回复的十几天后,zakria又发了个帖子(还是半生不熟的英语): 「『惩罚者』清屏作弊」 ( http://www. mamecheat.co.uk/forums/ viewtopic.php?t=3132 ) 我找到了『惩罚者』杀死所有敌人的作弊码。 这个码不怎么bug所有关卡都可以用它快速通过只有第一关不行。要干掉第一关boss你可以用无限手枪那个作弊。 如果Pugsy你想给这个码改名请随意。 ( 代码 ) 可想而知,Pugsy惊诧了: 牛逼啊!这不光是「杀死所有敌人」,简直就是「直接走着过关」的作弊啊,好多敌人根本连刷都不刷了。 你能坚持下来很好。 你证明了我之前说的「改RAM行不通」是错误的(找个台阶,我当时想得是另外一种改法来着)。 zakria回复: 谢谢Pugsy他给了我们很好用的作弊搜索器。 Miguelo( *另外一位表示惊奇的回复者 ), 这个RAM作弊很简单 ,我以前在街机上见过( *估计就是中国盗版 )。 当年12月,zakria贡献了另外一个作弊码,帖子中又有了一段对话: ( http://www. mamecheat.co.uk/forums/ viewtopic.php?f=4&t=3199 ) Pugsy: 谢谢,加好了……对了在cheats.txt的贡献者名单中你想署哪个名字?zakria还是genesis?你的真名是什么? zakria: 谢谢Pugsy,我的名字是ZAKRIYA。 我不需要署名。 你说genesis,我完成他一两个作弊请求我不太明白? Pugsy: 抱歉,只是你们这两个账号发帖子用的是相同的IP地址,在我这种小众论坛这可不是常事。我已经在cheat.txt中加上你的名字了,如果你不希望露真名请告诉我。 zakria: 我非常非常抱歉Pugsy,Qayoom(genesis)是我的朋友, 我们去同一个网吧上的网。 所有的作弊码都归你。如果你愿意加上我的名字,我的名字是Zakriya Aleem。 看到这里,我鼻子有点酸。 这个非英语母语的玩家,磕磕巴巴地提了一个挺有意义的难题,却被认为该难题无解的大V前辈甩了一通脸色、拒之门外。就这样,凭着一点施舍性质的、微妙的线索,他竟花了不到两星期(而且是在网吧)自己给解决了,解法还很漂亮,还丝毫不计前嫌、慷慨地分享出来,连署名都不要…… 中东那边世道乱,希望这哥们如今过得还好,不要卷入战火。 —————————— 故事讲完了,回归正题,说下『惩罚者』这个摇无敌是怎么回事吧。 我就是顺着zakria同志的作弊码开始查的,他给出的修改很简洁: 把$FF5FA1这个字节置为FF ,所有敌人就自动全灭,道具一捡就碎,boss也不用打,和街机摇出无敌的效果一模一样。 为什么会有这样的效果呢? 用MAME debugger的Watchpoint监视,可以简单发现: 在每一关的开头,以及击杀boss的瞬间,这个地址都会有写入操作; 读取则相对非常频繁。 结合实际现象,我推测: 击杀boss过关的时候,如果屏幕上还有杂兵活着,它们会立刻被一起干掉,然后出结算画面。$FF5FA1就是触发这个判定用的。将它锁成FF的话,游戏就会一直以为你是刚刚过关的状态,因此见谁秒谁。 这是清屏的通俗原理。 那么,摇出来的无敌,跟zakria改出来的无敌,是不是一回事呢? 我用「可以摇无敌」的改版ROM(punipic)测试了一下,在第三关摇出无敌(红衣机枪敌人挣脱)的瞬间,执行情况如下: 什么意思? 我试着说一下啊——虽说我也算是个程序员,毕竟是有阵子没怎么亲手写代码了,而且更没怎么弄过汇编,水平有限,如果解释错了你们不要喷我。 首先,发挥最关键作用的是 $03BF34 这句(ROM中是50EDDFA1)。DFA1反汇编显示成-$205F,其实就是 $FF5FA1 ,程序执行到这一句就会给这个地址赋值,也就是触发了无敌状态,然后再往下走到检测时就会触发杀死敌人的效果。 换言之,大家熟知的摇无敌确实是$FF5FA1这个地址造成的。zakria改出来的无敌和你摇出来的无敌是一样的。 然而正常游戏中并不会出现无敌。 在 $03BF20 这一步,程序会检查D0寄存器的值,如果不等于#$7,就会从 $03BF24 直接跳到 $03BF38 ,跳过了上述赋值。 D0寄存器的值是动态变化的,每一次执行到这里都可能不一样,因此 即使在盗版街机上也不是100%能摇出无敌,能摇出来的前提是敌兵挣脱瞬间D0=7 。可能是我手法差,总之这里我暂且认为是随机发生的。 如果第一步没有拦住(原版也有可能通过第一步),那么往下还会有一个检查,在 $03BF28 (上图标黄的内容)。它会检查 从$000AC6起的四个字节是否等于#$0080014A ,如果相等,就跳过去,直接到 $03BF38 。 注意:000AC6是ROM中的内容,值是固定的。 继续追查,原版游戏ROM是这样的: 看到 0080014A 了么?看见了就应该明白, 原版游戏中你怎么摇也摇不出无敌的,程序100%会跳过触发无敌的那一句,根本进不去。 能摇出无敌的盗版ROM,则是这样的: 这里被改成了 0C409180 ,因此在BEQ判断处不能正常跳转,于是程序接下来会按顺序执行 $03BF34 ,然后就触发无敌了。 —————————— (图: THE PUNISHER || ENEMIES ) 总结一下, 在「中国大陆流行的盗版基板」中,触发「无敌bug」的条件是「$03BF20语句执行时D0=#$7,从而未能跳过$03BF34」。而$03BF20会在特定敌兵「TRENCH」(即上图的红衣机枪手)从揪脖子状态挣脱时执行,无论是时间到了自动挣脱,还是玩家摇出了前滚动作中止揪脖子。 之所以只有3、5、6关能无敌,是因为这个敌人只在这三关刷新。 以上是我可以确定的内容。 另外,我个人还有一些猜测,主观认为可能性很高,但没有彻底确定(精力有限,懒得通读代码): 1. 在「摇无敌」这个过程中,疯狂左右晃动摇杆可能并没有起到太大作用,只是尽量快速重复「揪脖子,挣脱」这个过程,反复碰运气而已。 2. 「无敌bug」不像是盗版dump ROM时失误所致——盗版ROM和原版ROM不只是一两位数据有出入,光是上面我截图中显示的,从$000AB2到$000B0D都大相径庭,其它还有很多不同之处。我认为这个bug很可能是人为手动修改导致的。『惩罚者』的基板并不是普通的CPS,而是CPS'(搭载QSound芯片),盗版基板阉掉了QSound,势必要在程序上有些改动。 3. 「无敌bug」也并不像是盗版者故意设计的秘技。就$03BF34这一句以及其附近的代码而言,盗版ROM和原版ROM这里是相同的。我倾向于认为它是盗版者修改程序时意外发生的副作用。 至于原版程序为什么要在这个地方留一句进不去的代码,抱歉,我也不知道。所以我说这个答案只是一知半解、抛砖引玉,等着大牛来个彻底解析吧。 就这些。禁止转载。 (如有不同见解,欢迎在评论区补充)
知乎好玩就好玩在总有这么有趣的问题。 比起你在其它地方能找到的信息,我会稍微讲得详细那么一点点,至少比各种流言更靠谱一些,但是受限于专业水平,这个答案并不完美,权当抛砖引玉好了。知乎上程序员多,总有能帮我补充的。 —————————— 我先从一个有点感人的故事讲起吧。图少字多,见谅。 这个故事讲的是一位 「Cheat Finder」 ——也就是热衷于研究「作弊码」的玩家。故事有点长,但我实在希望更多玩家知道这个人。 所谓「作弊码」你大概能猜到是什么意思,就是通过非常规的方式修改游戏内存,实现在游戏中作弊的效果,例如角色无限生命、瞬间获得强力武器等等。 当然,具体改哪里、怎么改,都是有讲究的,所以才会有人专门研究这个,他们寻找能够实现作弊的特定的「地址+值」的组合,测试,然后分享出来,以此为乐。 在这个圈子中,从1998年就致力于制作/收集/整理/分享MAME作弊码的Pugsy应该算得上是个大拿,他经常会发布最新版的作弊码合集。时至今日你下载到的各种第三方打包MAME中,作弊码部分基本都是从他的网站 「Pugsy's Cheats 」 ( http:// cheat.retrogames.com )抓来的。 然而今天的主角并不是Pugsy君,而是一名叫做 zakria 的网友,真名 Zakriya Aleem ,年龄性别国籍不详——看名字应该是阿拉伯裔男性。 2008年6月的一天,这位zakria在Pugsy的论坛上操着半生不熟的英语发了个帖: 「求『惩罚者』作弊」 。 ( http://www. mamecheat.co.uk/forums/ viewtopic.php?t=3008 ) 『惩罚者』街机上有个秘技可以杀死全屏幕的敌人,谁能发一下啊? 抱歉我英语很差但是Pugsy很厉害他找到了『Eswat』无限特殊武器的作弊码。这次我想要的作弊是在『惩罚者』中杀死屏幕上所有敌人,就像最新版作弊文件中那个『吞食天地2』清屏。( 代码 )谁能发一下『惩罚者』的吗? Pugsy当时回复道: 这个作弊很难实现。我倒是做了个改版ROM能快速清屏的,但bug太多了而且还会死机。总之我有空再看看吧。 过了3个月,可能是zakria发了私信询问研究进展,Pugsy再次回复了帖子(请注意文字的语气态度): 我已经说过了这个作弊很麻烦, 给我发私信求我给你RAM码也没用 : 1.我通常不看私信。如果你想要作弊码不如直接发帖子,得到回答的几率还高一点。 这次的话题我最后回答一遍,然后你自求多福吧 。 2.改RAM行不通,因为角色在内存中是动态分配的,它需要使用「相对地址」,或者在ROM中改一大堆东西。 我也说过了我试过改ROM然后发现要修改和测试的地方太多了,每一种扣血都有自己的代码,它们都需要被处理。我改了一点,就是之前说过特别bug的那个。 反正短期内我也不会再关注这个问题了 ,所以发给你看看,强调,特别bug。如果你想自己改的话,你最好去学学「68000汇编」和「MAME debugger」。你需要干掉所有跟敌人血量有关的sub.w d0,(36,ax)调用,有80个以上地方,而且说不定还得改别的。 ( 代码 ) 就在这个回复的十几天后,zakria又发了个帖子(还是半生不熟的英语): 「『惩罚者』清屏作弊」 ( http://www. mamecheat.co.uk/forums/ viewtopic.php?t=3132 ) 我找到了『惩罚者』杀死所有敌人的作弊码。 这个码不怎么bug所有关卡都可以用它快速通过只有第一关不行。要干掉第一关boss你可以用无限手枪那个作弊。 如果Pugsy你想给这个码改名请随意。 ( 代码 ) 可想而知,Pugsy惊诧了: 牛逼啊!这不光是「杀死所有敌人」,简直就是「直接走着过关」的作弊啊,好多敌人根本连刷都不刷了。 你能坚持下来很好。 你证明了我之前说的「改RAM行不通」是错误的(找个台阶,我当时想得是另外一种改法来着)。 zakria回复: 谢谢Pugsy他给了我们很好用的作弊搜索器。 Miguelo( *另外一位表示惊奇的回复者 ), 这个RAM作弊很简单 ,我以前在街机上见过( *估计就是中国盗版 )。 当年12月,zakria贡献了另外一个作弊码,帖子中又有了一段对话: ( http://www. mamecheat.co.uk/forums/ viewtopic.php?f=4&t=3199 ) Pugsy: 谢谢,加好了……对了在cheats.txt的贡献者名单中你想署哪个名字?zakria还是genesis?你的真名是什么? zakria: 谢谢Pugsy,我的名字是ZAKRIYA。 我不需要署名。 你说genesis,我完成他一两个作弊请求我不太明白? Pugsy: 抱歉,只是你们这两个账号发帖子用的是相同的IP地址,在我这种小众论坛这可不是常事。我已经在cheat.txt中加上你的名字了,如果你不希望露真名请告诉我。 zakria: 我非常非常抱歉Pugsy,Qayoom(genesis)是我的朋友, 我们去同一个网吧上的网。 所有的作弊码都归你。如果你愿意加上我的名字,我的名字是Zakriya Aleem。 看到这里,我鼻子有点酸。 这个非英语母语的玩家,磕磕巴巴地提了一个挺有意义的难题,却被认为该难题无解的大V前辈甩了一通脸色、拒之门外。就这样,凭着一点施舍性质的、微妙的线索,他竟花了不到两星期(而且是在网吧)自己给解决了,解法还很漂亮,还丝毫不计前嫌、慷慨地分享出来,连署名都不要…… 中东那边世道乱,希望这哥们如今过得还好,不要卷入战火。 —————————— 故事讲完了,回归正题,说下『惩罚者』这个摇无敌是怎么回事吧。 我就是顺着zakria同志的作弊码开始查的,他给出的修改很简洁: 把$FF5FA1这个字节置为FF ,所有敌人就自动全灭,道具一捡就碎,boss也不用打,和街机摇出无敌的效果一模一样。 为什么会有这样的效果呢? 用MAME debugger的Watchpoint监视,可以简单发现: 在每一关的开头,以及击杀boss的瞬间,这个地址都会有写入操作; 读取则相对非常频繁。 结合实际现象,我推测: 击杀boss过关的时候,如果屏幕上还有杂兵活着,它们会立刻被一起干掉,然后出结算画面。$FF5FA1就是触发这个判定用的。将它锁成FF的话,游戏就会一直以为你是刚刚过关的状态,因此见谁秒谁。 这是清屏的通俗原理。 那么,摇出来的无敌,跟zakria改出来的无敌,是不是一回事呢? 我用「可以摇无敌」的改版ROM(punipic)测试了一下,在第三关摇出无敌(红衣机枪敌人挣脱)的瞬间,执行情况如下: 什么意思? 我试着说一下啊——虽说我也算是个程序员,毕竟是有阵子没怎么亲手写代码了,而且更没怎么弄过汇编,水平有限,如果解释错了你们不要喷我。 首先,发挥最关键作用的是 $03BF34 这句(ROM中是50EDDFA1)。DFA1反汇编显示成-$205F,其实就是 $FF5FA1 ,程序执行到这一句就会给这个地址赋值,也就是触发了无敌状态,然后再往下走到检测时就会触发杀死敌人的效果。 换言之,大家熟知的摇无敌确实是$FF5FA1这个地址造成的。zakria改出来的无敌和你摇出来的无敌是一样的。 然而正常游戏中并不会出现无敌。 在 $03BF20 这一步,程序会检查D0寄存器的值,如果不等于#$7,就会从 $03BF24 直接跳到 $03BF38 ,跳过了上述赋值。 D0寄存器的值是动态变化的,每一次执行到这里都可能不一样,因此 即使在盗版街机上也不是100%能摇出无敌,能摇出来的前提是敌兵挣脱瞬间D0=7 。可能是我手法差,总之这里我暂且认为是随机发生的。 如果第一步没有拦住(原版也有可能通过第一步),那么往下还会有一个检查,在 $03BF28 (上图标黄的内容)。它会检查 从$000AC6起的四个字节是否等于#$0080014A ,如果相等,就跳过去,直接到 $03BF38 。 注意:000AC6是ROM中的内容,值是固定的。 继续追查,原版游戏ROM是这样的: 看到 0080014A 了么?看见了就应该明白, 原版游戏中你怎么摇也摇不出无敌的,程序100%会跳过触发无敌的那一句,根本进不去。 能摇出无敌的盗版ROM,则是这样的: 这里被改成了 0C409180 ,因此在BEQ判断处不能正常跳转,于是程序接下来会按顺序执行 $03BF34 ,然后就触发无敌了。 —————————— (图: THE PUNISHER || ENEMIES ) 总结一下, 在「中国大陆流行的盗版基板」中,触发「无敌bug」的条件是「$03BF20语句执行时D0=#$7,从而未能跳过$03BF34」。而$03BF20会在特定敌兵「TRENCH」(即上图的红衣机枪手)从揪脖子状态挣脱时执行,无论是时间到了自动挣脱,还是玩家摇出了前滚动作中止揪脖子。 之所以只有3、5、6关能无敌,是因为这个敌人只在这三关刷新。 以上是我可以确定的内容。 另外,我个人还有一些猜测,主观认为可能性很高,但没有彻底确定(精力有限,懒得通读代码): 1. 在「摇无敌」这个过程中,疯狂左右晃动摇杆可能并没有起到太大作用,只是尽量快速重复「揪脖子,挣脱」这个过程,反复碰运气而已。 2. 「无敌bug」不像是盗版dump ROM时失误所致——盗版ROM和原版ROM不只是一两位数据有出入,光是上面我截图中显示的,从$000AB2到$000B0D都大相径庭,其它还有很多不同之处。我认为这个bug很可能是人为手动修改导致的。『惩罚者』的基板并不是普通的CPS,而是CPS'(搭载QSound芯片),盗版基板阉掉了QSound,势必要在程序上有些改动。 3. 「无敌bug」也并不像是盗版者故意设计的秘技。就$03BF34这一句以及其附近的代码而言,盗版ROM和原版ROM这里是相同的。我倾向于认为它是盗版者修改程序时意外发生的副作用。 至于原版程序为什么要在这个地方留一句进不去的代码,抱歉,我也不知道。所以我说这个答案只是一知半解、抛砖引玉,等着大牛来个彻底解析吧。 就这些。禁止转载。 (如有不同见解,欢迎在评论区补充)