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

 

本文待完善。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM