最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

【解釋向】超級(jí)馬里奧水下256關(guān)的成因解析

2022-06-04 21:33 作者:SKY2008_233  | 我要投稿

閱前提醒:所有研究的資料來源于百度貼吧的“溢出關(guān)卡吧”!

眾所周知,2015年,敖廠長(zhǎng)上傳過一個(gè)探索過超級(jí)瑪麗水下256關(guān)的視頻。此后便不斷有人去探索這些神秘的關(guān)卡。然而,早在2012年便有人進(jìn)行過了探索,并且一發(fā)不可收拾了好幾年,留下了很多寶貴的結(jié)論。

我自己也曾在2021年研究過這些老帖子,直到前些天,我看到了一個(gè)2019年的老視頻。

視頻里提到的這些改動(dòng)所導(dǎo)致的水下256關(guān)其實(shí)都是比較“邪門”的改法,那么為您呈現(xiàn)的,便是整套的溢出關(guān)卡體系。

(由于很少改版改過這個(gè)區(qū)域,所以這一規(guī)律基本通用)

開始前,我們先說明一些基本概念。

溢出關(guān)卡:(來自百度百科)由馬里奧系列游戲,通過修改內(nèi)存或運(yùn)用bug技而進(jìn)入的數(shù)據(jù)指針錯(cuò)誤的非正常關(guān)卡。

(研究后的補(bǔ)充定義)溢出關(guān)卡是通過直接修改內(nèi)存(包括關(guān)卡號(hào)、空間編號(hào)、數(shù)據(jù)指針內(nèi)存)或運(yùn)用bug技達(dá)到修改如上內(nèi)存目的而進(jìn)入的數(shù)據(jù)錯(cuò)誤的非正常關(guān)卡。

水下256關(guān):(大概為敖廠長(zhǎng)的原意)SMB(就是超級(jí)瑪麗/超級(jí)馬里奧Super Mario Brothers的簡(jiǎn)稱,下文都將以此代指)本身只有8個(gè)世界(大關(guān)),而通過內(nèi)存溢出進(jìn)入的溢出關(guān)卡大關(guān)能有256個(gè),而這些關(guān)卡多在水下,所以被稱為“超級(jí)馬里奧水下256關(guān)”。

大關(guān)號(hào):即世界數(shù),游玩UI下的A-B中的A所代表的數(shù)字。

小關(guān)號(hào):游玩UI下A-B中B所代表的數(shù)字。需要注意的是,游戲存儲(chǔ)了兩個(gè)小關(guān)號(hào),有時(shí)兩個(gè)小關(guān)號(hào)數(shù)值會(huì)不一樣,UI中則只顯示一個(gè),稍后便會(huì)提到。

十六進(jìn)制:一種計(jì)數(shù)方式,逢十六進(jìn)一,10~15分別用字母A~F表示,能夠和二進(jìn)制較方便地轉(zhuǎn)換。

空間號(hào):也稱房間號(hào)(Room),每個(gè)關(guān)卡/場(chǎng)景都會(huì)對(duì)應(yīng)一個(gè)空間,而重復(fù)的關(guān)卡/場(chǎng)景對(duì)應(yīng)的是一個(gè)空間,每個(gè)空間會(huì)對(duì)應(yīng)一個(gè)十六進(jìn)制的空間號(hào)。(十六進(jìn)制與十進(jìn)制的數(shù)下文不作嚴(yán)格區(qū)分,需要的地方才會(huì)注明,但空間號(hào)一定是十六進(jìn)制的)

6502匯編:一種匯編語(yǔ)言,即編程語(yǔ)言,所有紅白機(jī)游戲所采用的語(yǔ)言。

地址:內(nèi)存中一個(gè)或多個(gè)字節(jié)所在內(nèi)存中的位置、序號(hào)。一般用十六進(jìn)制表示,并且在前面會(huì)加上一個(gè)$美元符號(hào);相對(duì)應(yīng)的,在程序中的數(shù)值用#$作為前綴。6502中,地址后面打上逗號(hào)","相當(dāng)于地址的相加;地址外面打上括號(hào)"($xx)"則代表的是“相對(duì)地址”,實(shí)際地址是這個(gè)地址指向依次的兩個(gè)字節(jié),如:$00、$01兩個(gè)字節(jié)為45,11,($00)則代表的是$1145。

指針:數(shù)據(jù)/代碼所指向的地址。

6502地址布局:在65536字節(jié)的CPU內(nèi)存中,$0000-$07FF為RAM,$0800-$1FFF為其3次鏡像(讀寫都會(huì)在實(shí)際對(duì)應(yīng)區(qū)域鏡像,但是有例外);$2000-$2007為PPU圖形寄存器,$2008-$3FFF為其反復(fù)鏡像(同上,但是代碼讀取方面有待考究);$4000-$4017為APU聲音寄存器,$4018-$5FFF為無效內(nèi)存,與程序執(zhí)行過程有關(guān);$6000-$7FFF為SRAM(SaveRAM),大部分時(shí)候可做RAM使用,有記憶存儲(chǔ)的功能;$8000-$FFFF為ROM部分。

6502寄存器:主要有4個(gè):A累加器,X、Y變址寄存器,P狀態(tài)寄存器,本質(zhì)都為8位的一字節(jié)寄存器。一些二進(jìn)制的邏輯運(yùn)算主要依托于A,而X、Y為前文提到的地址中逗號(hào)后接著的,因而得名;P則主要在程序中受一些比較、加減、讀取操作的影響,并提供結(jié)果,而其中7位都分別代表了一個(gè)標(biāo)志位,包括N,V,B,D,I,Z,C。


一、關(guān)于用大關(guān)號(hào)、小關(guān)號(hào)確定空間號(hào)的過程

大關(guān)號(hào)位于$075F,而此處使用的小關(guān)號(hào)位于$0760。一段代碼如下:

“LD”為load的縮寫,表示讀?。籆LC表示清除C標(biāo)志位;ADC為“帶進(jìn)位位C的加法”;RTS為返回主程序,相當(dāng)于這只是一段子程序,用于調(diào)用。那么這段程序解釋起來如下:

讀取大關(guān)號(hào)的值,作為$9CB4往后的偏移值(稱為y值,即實(shí)際指針為9CB4+(075F的值)),再與$0760相加得到一個(gè)值;把這個(gè)值作為$9CBC往后的偏移值存入累加器A中。

那么這段程序代表了什么呢?我們看一下$9CB4,$9CBC后的一些數(shù)據(jù):

實(shí)際上,$9CBC起(即25 29 C0 26往后)的是每一關(guān)的空間編號(hào)。不過推導(dǎo)之前,就要說一下我們之前提到的“小關(guān)號(hào)的伏筆”——空間29。眾所周知,在1-2、2-2、4-2、7-2四關(guān)開始前,會(huì)有一個(gè)馬里奧自動(dòng)進(jìn)水管的過場(chǎng)動(dòng)畫。這一過場(chǎng)動(dòng)畫顯示上(用的是$075C)是沒有增加小關(guān)號(hào)的,但這里用到的$0760卻被增加了,也就說真正的1-2這里是1-3,真正的2-2這里是2-3,本身的1-2、2-2都是這一“自行走關(guān)卡”。

結(jié)合我們分析的代碼,在1世界中,1-1~1-4分別對(duì)應(yīng)$9CBC偏移的0、2、3、4(自行走關(guān)卡不計(jì)),對(duì)應(yīng)的空間編號(hào)便是25,C0,26,60;當(dāng)在2-1時(shí),$075F為01(實(shí)際上顯示的關(guān)卡號(hào)比原本要+1),偏移$9CB4后,$9CB5的值為05,$9CBC偏移的也就為5、7、8、9,對(duì)應(yīng)的空間編號(hào)也就是28,01,27,62了,以此類推。

通過這個(gè),我們能說明一個(gè)問題:“關(guān)卡復(fù)用”。比如說,1-3與5-3地形完全一致,5-3敵人會(huì)多一些;1-4與6-4,2-2與7-2,2-3與7-3,2-4與5-4同理。而通過上圖,我們能得出,每組關(guān)卡的對(duì)應(yīng)空間號(hào)為26,60,01,27,62,也就是每組用的是同一空間號(hào),而敵人的不同則是關(guān)卡內(nèi)敵人的一些設(shè)置問題了。

由此,我們也能得出一個(gè)結(jié)論:所有水下256關(guān)都能夠轉(zhuǎn)化為1-x,也就是其所在的“y值”+1。比如(都計(jì)入自行走關(guān)卡,即0760的值):2-1就是1-6,8-1就是1-33,9-1就是1-38(其實(shí)8-5并非9-1,而是8-6,因?yàn)閃9對(duì)應(yīng)的y值是1-1的空間編號(hào)25,即37,越過了空間編號(hào)所在9CE0的1F,直接鏈接到9CE1的06).

RTS后,實(shí)際程序還有一段才會(huì)又一個(gè)RTS(子程序套子程序是非常普遍的現(xiàn)象):

JSR表示“調(diào)用子程序”,我們剛才9C13起的程序是返回到9C06的;“ST”為store的簡(jiǎn)稱,即存儲(chǔ),AND表示“與”運(yùn)算,ASL為算術(shù)左移,ROL為循環(huán)左移。

是不是這些運(yùn)算太多了?實(shí)際上,這些都是二進(jìn)制的邏輯運(yùn)算。我們把剛剛得到的結(jié)果化成二進(jìn)制來看:

首先,$9CBC偏移后的值存入$0750(這也是空間號(hào)的存儲(chǔ)地方,但有時(shí)實(shí)質(zhì)是暫存),這里假設(shè)是1-1的25,二進(jìn)制表示為0010 0101;接著AND #$60,即0110 0000。0010 0101和0110 000作與運(yùn)算,與運(yùn)算對(duì)于每一位,只有兩個(gè)都為1結(jié)果的位上才輸出1。所以結(jié)果是0010 0000,即十六進(jìn)制的20;算術(shù)左移就是把每一位的數(shù)據(jù)都向左移動(dòng)一位,最低為填充0,可以理解為十進(jìn)制上的“乘2”,結(jié)果為0100 0000,40;ROL為循環(huán)左移,會(huì)把左移后最高位存入C位,C位移入最低位,三次左移后變成了1000 0000,0000 0000,0000 0001,最終為01,存入074E。

其實(shí),這一段就是確定074E“場(chǎng)景編號(hào)”的程序,之后還會(huì)再用一次。


二、確定關(guān)卡的指針

這一段代碼便比較長(zhǎng)了。

沒有新的命令語(yǔ)法,直接分析:讀取0750的值,執(zhí)行9C09的子程序(是前面提到的確定074E的程序),存到Y(jié)內(nèi);讀取0750,做和#$1F的與運(yùn)算,存入074F(相當(dāng)于取其二進(jìn)制的后5位)。以Y為偏移值,讀取9CE0偏移后的數(shù)值,加上074F,作為新的Y值;以此為新偏移值,讀取9CE4,9D06偏移后的數(shù)值,分別存入$E9,$EA;類似的,讀取074E,以此讀取9D28偏移后的值,再加074F,作為新偏移值;讀取9D2C,9D4E偏移后的數(shù)值,分別存入$E7,$E8。

如果不清楚的話,可以以這張圖來說明:

$E9,$EA兩個(gè)字節(jié)是敵人指針,$E7,$E8兩個(gè)字節(jié)是地形指針。

限于本人概括能力不足,引用原貼的話:

結(jié)合這張圖,我們對(duì)這一大段代碼進(jìn)行分析。

首先是重新獲取場(chǎng)景代碼的過程,在后面的代碼中,我們得知,這一場(chǎng)景代碼是在讀取“敵人偏移值”和“地形偏移值”時(shí)作為偏移值使用的。

然后分別是獲取敵人代碼和地形代碼(分別有2個(gè))的過程??匆幌律厦娴膱D,我們發(fā)現(xiàn),敵人代碼和地形代碼合起來一共有4組,每一組都有34個(gè)數(shù)值。為什么是34個(gè)數(shù)值呢?想想樓上發(fā)過的表格,發(fā)現(xiàn)什么了沒有?沒錯(cuò),正常關(guān)卡的地形一共有34種,對(duì)應(yīng)的敵人也有34種。

接下來,獲取的敵人代碼和地形代碼分別被存到了如下內(nèi)存地址:00E7(地形代碼1)、00E8(地形代碼2)、00E9(敵人代碼1)、00EA(敵人代碼2)。注意到其中的00E8了沒有?沒錯(cuò),它儲(chǔ)存了一個(gè)地形代碼!所以使用金手指00E8會(huì)改變地形……

存入上述4個(gè)代碼之后,接下來的過程就跟這張圖沒關(guān)系了。

備注:各個(gè)代碼區(qū)的起始地址為:y值9CB4,空間編號(hào)9CBC,敵人偏移值9CE0,敵人代碼1 9CE4,敵人代碼2 9D06,地形偏移值9D28,地形代碼1 9D2C,地形代碼2 9D4E

所以說每一空間對(duì)應(yīng)的關(guān)卡都能確定;換句話說,所有能通過256大關(guān)、256小關(guān)進(jìn)入的關(guān)卡都能確定了。原貼中整理了這樣兩個(gè)表:

這張是地形的
這張是敵人的

值得注意的是,實(shí)際空間編號(hào)有效的只有00-7F。因?yàn)榇a里從頭到尾就沒碰過第7位,也就是最高位,所以說80-FF等效于00-7F。而之后還有一個(gè)值得注意的地方:

9C58-9CA5之間的代碼做了一件事——讀取地形頭部數(shù)據(jù)。地形頭有兩個(gè)字節(jié),每幾位一組各代表了一些數(shù)據(jù),包括初始的地板樣式、背景樣式、出場(chǎng)高度、時(shí)間等。而實(shí)際的地形單位數(shù)據(jù)在這兩個(gè)字節(jié)后,所以需要地形指針整體+2。也就不可避免地提到ADC的“C”問題了:進(jìn)行加法運(yùn)算時(shí),兩個(gè)8位的二進(jìn)制數(shù)相加是可能會(huì)溢出到第9位的,會(huì)存入C中;這也相當(dāng)于是加法的運(yùn)算進(jìn)位了,所以ADC #$00實(shí)際上加的可能不是0,也有可能因?yàn)镃置1的進(jìn)了位而加1,相當(dāng)于最終結(jié)果也是整體在加減。由此保證了地圖讀取的正常性。


所以視頻中反映的問題在哪里呢?0x1CC0與0x1D39這兩處,對(duì)應(yīng)內(nèi)存中的便是$9CB0和$9D29。如果你還記得的話,剛才這段代碼緊接著就是$9CB4,所以9CB0其實(shí)對(duì)應(yīng)的是“ADC #$00”這一句中的數(shù)據(jù)“00”。更改這里,相當(dāng)于就是在地形指針的高位又加了一個(gè)數(shù),而不僅僅只是2,最終的效果便是改變了地形指針的高位,而低位相比正常沒有改變。本質(zhì)上不是水下256關(guān),但也屬于溢出關(guān)卡。

第二種情況更改的是地形指針的地上“場(chǎng)景偏移值”,074E的值為1所偏移到的。原本為03,改了之后,074F加上這個(gè)偏移值就能去很多別的不同地形,比如改為10,1-1的25地形則對(duì)應(yīng)到了32,8-2,敵人卻仍然是1-1的;改為FF,1-1則地形對(duì)應(yīng)21,3-1;視頻里改為00,則變?yōu)?2 4-1,與本身074F的取值有關(guān)。數(shù)值改大一點(diǎn)可能還會(huì)出現(xiàn)更有趣的現(xiàn)象,出現(xiàn)更多的地形。本質(zhì)上也不是水下256關(guān),但是也是溢出關(guān)卡。

最后再提一嘴“水下”256關(guān)的問題。再回到這張圖:

9CBC-9DBB(是最后一行那個(gè)數(shù)9D的地方)即為正常空間號(hào)的所有取值范圍。當(dāng)中別的不看,9D06-9D1C是很大一片水下空間(9D-9F相當(dāng)于1D-1F),對(duì)應(yīng)的空間編號(hào)偏移值為4A~60(十進(jìn)制的1-75~1-97),很容易就會(huì)取到這一片。并且再根據(jù)這張圖:

空間1D~1F正好對(duì)應(yīng)水下4-4,2-4,3-4,所以基本上從x-1開始進(jìn)去就是一關(guān)就停,也看不到后面的關(guān)卡。所以水下的占比實(shí)質(zhì)上和感受上都較多。

(注:著名的0-1相當(dāng)于1-77,對(duì)應(yīng)的是9D08處9D這一數(shù)值,由此為空間1D水下4-4,并且0-3就是水下2-4,部分D版ROM有可能會(huì)因?yàn)樽孕凶哌^場(chǎng)等問題使0-3顯示為0-2)

【解釋向】超級(jí)馬里奧水下256關(guān)的成因解析的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
本溪市| 民和| 桃园县| 横峰县| 宁蒗| 岳西县| 桐庐县| 福清市| 宁阳县| 从江县| 双辽市| 邹平县| 阜平县| 阳高县| 株洲市| 黑山县| 安图县| 石台县| 六盘水市| 江源县| 察雅县| 临沧市| 石柱| 新丰县| 玛沁县| 乳源| 湟中县| 资溪县| 开阳县| 宁武县| 贵州省| 延边| 图木舒克市| 万源市| 巴林右旗| 龙岩市| 新民市| 商城县| 高州市| 黄龙县| 嘉祥县|