zoukankan      html  css  js  c++  java
  • FC超级玛丽研究(NES游戏)

    理解本文需要6502汇编语言基础,读者可先阅读本人之前的一篇文章6502汇编指令速查表.pdf

    为便于理解,本文所有内存地址都用[]表示(如:[00CE]),所有ROM文件地址都用<>表示(如:<00CE>),所有数值都用$前缀或0x前缀表示(如:$CE或0xCE),$CE主要用于表示汇编语言十六进制数,0xCE主要用于表示文字注释十六进制数。

    定义关卡表示方式

    第x大关的第y小关简称x-y,例句:关卡8-4为最后一关。

    8-4过去后可进入难度加大版,同样是从1-1关开始,变化主要有:蘑菇怪变铁乌龟,一些敌人步行速度快了,梯子短了,锤子龟爆发容忍时间短了。

    定义敌人名称

    蘑菇怪:最简单的敌人,只能在地上缓慢步行,一踩就死。

    乌龟:踩一下静止不动,再碰一下就滑行。

    铁乌龟:同乌龟,但不怕火力花。

    刺猬:不可踩,但怕火力花。

    快乐云:不断放置刺猬,但场景里一般最多出现3个刺猬(内存限制)。

    章鱼:在水里出现,斜向上运动或垂直向下运动。

    鱼群:在水里出现,或成为飞鱼。

    锤子龟:会扔锤子,但怕火力花。此敌人一开始在原地跳跃上下运动且扔锤子,过一段时间(锤子龟爆发容忍时间)后,锤子龟爆发,直接向左走,遇到障碍就跳过去,整个过程都扔锤子。

    导弹:可踩,但不怕火力花。

    火焰:不可踩(以下和火、库巴有关的均不可踩),一般由库巴喷出。

    火串:不断旋转。

    火球:从岩浆中向上喷出,到达最高点后降落。

    库巴:会喷火(生成不同高度的火焰)和扔锤子。

    避免在fceux中运行出现0-1关

    将<031E>处的8D5F07用EA填充

    内存地址含义

    [0057]玛丽X方向运动速度(矢量,符号位代表方向)

    [0058]-[005C]敌人X方向运动速度,最多容纳5个敌人,且出现5个敌人时,其中2个敌人会闪烁

    [0086]-[008B]玛丽横坐标和敌人横坐标

    [008D]和[008E]火力花横坐标

    [00A6]和[00A7]火力花方向(0x04向下方向,0xFD向上弹起)

    [00CE]玛丽高度,[00CF]-[00D3]敌人高度,[00D5]火力花高度

    [00FA]置1后播放暂停音效关闭背景音乐,置2后播放取消暂停音效打开背景音乐

    [00FD]-[00FF]对这3个字节其中的1bit置1可播放对应的音效(bit代表其中一位,一个字节有8位)

    [0117]和[0118]得分位置X方向,[011E]和[011F]得分位置Y方向

    [075A]生命数,0x00表示剩余可用生命数为0

    [075E]真正的金币数量地址

    [075F]当前大关,[0760]当前小关(都是从0开始标,即0x0000表示1-1,0x0703表示8-4)

    [07DD]连续6字节为分数地址

    [07EC]-[07EE]金币数量百位、十位、个位显示

    [07F8]-[07FA]时间百位、十位、个位

    运行时地址(即内存地址)与ROM文件地址对应关系

    例:运行时内存地址[C30C]对应于ROM文件地址<431C>

    关系:运行时内存地址=ROM文件地址+7FF0

    解释:运行游戏时需要将ROM文件里的指令和数据存放到内存中

    修改ROM文件可实现的效果

    <36D7>的A903指令可改火力花初始方向

    <3A41>炮台向右导弹速度,<3A42>炮台向左导弹速度

    <431C>的0xF8蘑菇怪步行速度、乌龟步行速度、铁乌龟步行速度,<431D>难度加大版对应速度

    <4336>锤子龟爆发容忍的时间默认0x80,<4337>难度加大版锤子龟爆发容忍的时间默认0x50

    将<4AA8>的内容用EAEAEA填充可使敌人不下落

    修改<4C50>的0xE8可变空中导弹速度

    <585F>的0x30乌龟滑行速度

    将<5B4C>用EAEA填充可不反转

    判断是否出现食人花
    00:98F2:AD.60.07..*LDA.$0760;00:98F5:0D.5F.07..*ORA.$075F;00:98F8:F0.2B.....*BEQ.$9925

    当[0760]和[075F]均为0时跳过食人花,均为0恰好表示1-1关(下标从0开始),所以只有关卡1-1没有食人花,其余关卡水管均有食人花。

    如将0xF0改为0x10可关闭食人花,因为这样就强制跳过布置食人花的指令(当然改为102B并不是强制向后跳转0x2B个字节,只是不为负背景下的等价)。

    判断时间是否为0,Time up
    00:B769:AD.F8.07..*LDA.$07F8;00:B76C:0D.F9.07..*ORA.$07F9;00:B76F:0D.FA.07..*ORA.$07FA;00:B772:F0.26.....*BEQ.$B79A

    如果[07F8]连续3个字节均为0则代表时间为0

    过关结算时间
    01:D312:AD.F8.07..*LDA.$07F8;01:D315:0D.F9.07..*ORA.$07F9;01:D318:0D.FA.07..*ORA.$07FA;01:D31B:F0.F1.....*BEQ.$D30E
    100金币生命数+1
    00:BC0C:EE.5E.07..*INC.$075E;00:BC0F:AD.5E.07..*LDA.$075E;00:BC12:C9.64.....*CMP.#$64;00:BC14:D0.0C.....*BNE.$BC22;00:BC16:A9.00.....*LDA.#$00;00:BC18:8D.5E.07..*STA.$075E;00:BC1B:EE.5A.07..*INC.$075A;00:BC1E:A9.40.....*LDA.#$40;00:BC20:85.FE.....*STA.$00FE;00:BC22:A9.02.....*LDA.#$02

    这段指令为玛丽吃到金币后的事件指令。首先[075E]自增1,让金币数量加1,然后读取金币数量,和0x64(对应十进制的100)进行比较,如果不等就向后跳转0x0C个字节,吃金币事件就结束了,如果相等就不跳转,将[075E]置0,表示金币数量清零,然后[075A]自增1,表示生命数加1,最后将[00FE]置0x40,表示播放1UP的音效。

    敌人下落修改高度
    00:BFEB:75.CE.....*ADC.$CE,X;00:BFED:95.CE.....*STA.$CE,X

    0x75改成0xB5(即LDA),无法实现,因为玛丽也不下降了,将<4AA8>的内容用EAEAEA填充可使敌人不下落

    喷火速度
    01:D204:B5.87.....*LDA.$87,X;01:D206:E9.01.....*SBC.#$01;01:D208:95.87.....*STA.$87,X

    火焰横坐标自减一,实现喷火效果,如修改E901为E902则2倍喷火速度。

    求敌人反转后的X方向运动速度
    01:DB36:B5.58.....*LDA.$58,X;01:DB38:49.FF.....*EOR.#$FF;01:DB3A:A8........*TAY;01:DB3B:C8........*INY;01:DB3C:94.58.....*STY.$58,X

    首先读取敌人的速度,然后和0xFF异或一下,相当于按位取反,再存到Y里面自增一下,最后存回敌人速度内存区域。

    可形成+1和-1互换,+2和-2互换等等。即0x01和0xFF,0x02和0xFE。

    敌人反转详细汇编指令
    01:DB1C:B5.16.....*LDA.$16,X;01:DB1E:C9.0D.....*CMP.#$0D;01:DB20:F0.22.....*BEQ.$DB44;01:DB22:C9.11.....*CMP.#$11;01:DB24:F0.1E.....*BEQ.$DB44;01:DB26:C9.05.....*CMP.#$05;01:DB28:F0.1A.....*BEQ.$DB44;01:DB2A:C9.12.....*CMP.#$12;01:DB2C:F0.08.....*BEQ.$DB36;01:DB2E:C9.0E.....*CMP.#$0E;01:DB30:F0.04.....*BEQ.$DB36;01:DB32:C9.07.....*CMP.#$07;01:DB34:B0.0E.....*BCS.$DB44;01:DB36:B5.58.....*LDA.$58,X;01:DB38:49.FF.....*EOR.#$FF;01:DB3A:A8........*TAY;01:DB3B:C8........*INY;01:DB3C:94.58.....*STY.$58,X;01:DB3E:B5.46.....*LDA.$46,X;01:DB40:49.03.....*EOR.#$03;01:DB42:95.46.....*STA.$46,X

    本文待完善。

  • 相关阅读:
    HDU 2955 Robberies(01背包)
    HDU 2602 Bone Collector(01背包)
    HUST 1352 Repetitions of Substrings(字符串)
    HUST 1358 Uiwurerirexb jeqvad(模拟解密)
    HUST 1404 Hamming Distance(字符串)
    HDU 4520 小Q系列故事――最佳裁判(STL)
    HDU 2058 The sum problem(枚举)
    【破解】修改程序版权、添加弹窗
    HDU 1407 测试你是否和LTC水平一样高(枚举)
    HDU 1050 Moving Tables(贪心)
  • 原文地址:https://www.cnblogs.com/leisureeen/p/cjml.html
Copyright © 2011-2022 走看看