《超級馬里奧3》使用了什麼樣的技術可以在128KB中寫進這麼多東西?

我目前的工作是製作手機遊戲, 回頭再看FC上的有些遊戲, 不由得非常驚愕了


我寫過FC模擬器,對這個比較了解。

  • 代碼部分: 全是手寫的6502彙編,要多精簡有多精簡。

  • 聲音部分: FC有兩路方波生成器,一路三角波生成器,一路隨機雜訊,一路PCM。PCM採樣可以實現很好的效果,但數據量巨大,所以大多數遊戲沒用。用方波/三角波來發聲就類似最簡單的MIDI音樂,數據量很小。
  • 圖形部分: 這是主要佔卡帶容量的部分,下面簡單說一下

    • FC的圖形處理單元以sprite的方式組織圖像,程序能控制的最小顯示單位不是一個點,而是8x8的sprite。
    • 「那整個畫面捲動的時候不是應該一塊一塊(8像素)的跳動嗎?」——PPU另外有捲軸寄存器,可以按像素級指定捲動的量。也就是說sprite雖然是8x8的,但在屏幕上不見得總是對齊到8x8的格子里。
    • sprite里具體每個點的顏色也不像現在是豪華的16位或32位RGB直接指定,而是一個2bit的索引,從一個16色的調色板里選。
    • 既然是2bit的索引值,最多就只能指定4色。而且因為00固定代表透明,所以實際上最多只有3色。
    • 那為啥要用到16色的調色板?實際上是4個4色的調色板。每4個相鄰的sprite(16x16)可以從這4個調色板里指定一個。所以你去數,FC的一個16x16 sprite里最多只能顯示4種顏色,因此會有那種經典的單調感。
    • 16色的調色板有兩個,一個背景層用,一個角色層用。調色板從FC PPU固定死的64種顏色中選取顏色。因為這64個顏色里黑色/透明重複了多次,所以實際不同的顏色只有54種。
    • 不管你看沒看暈,上面的重點是,FC遊戲裡面一個像素只佔用2bit的卡帶空間。
    • 並且因為所有顯示內容都按sprite組織,大大方便重複使用。要顯示形狀一模一樣的兩朵雲,或者幾十個磚塊,只需要在顯存里重複寫下這些sprite的編號,而不是重複sprite的數據(8x8x2/8=16byte)
    • 因為調色板的存在,形狀一樣而顏色不同的圖案也不需要佔額外的空間,只要設置一下調色板就行了,包括變色的效果也是這樣做的。紅色的Mario和綠色的Luigi就是同一套Sprite。
    • 透明、滾動、前後景疊加、碰撞檢測都是PPU完成,不需要另外寫程序。
    • sprite的數據也不存在由CPU從卡帶讀入到RAM的過程(除了後期的磁碟機),而是直接由卡帶映射到FC的64KB地址空間進行訪問。不同的卡帶硬體(所謂的mapper)支持由程序控制將卡帶上的不同地址映射到FC的同一地址空間,所以儘管8位的FC只有64KB定址能力,但卡帶容量可以做到256KB甚至更大。

所以說白了就是在當年技術條件有限的情況下,實現了各種基礎的圖像壓縮演算法,以及對開發人員要求極高的數據重用……

之所以美版魂斗羅只有128KB容量,而日版有256KB,就是因為美版砍掉了日版里的各種片頭/過場/片尾的動畫和圖案。對,本人目前的頭像就是被美版Contra精簡掉的內容之一。


稍微說點,不會寫模擬器,就說說有關圖像構成的吧。

比如這麼一張「貼圖」,它的解析度是16*16,包括透明在內共有四種顏色。

如果用PNG存儲,大概是378B,已經很小了。

然而用FC存儲要多少呢?如果忽略掉上色問題,那麼在FC中「不經壓縮地」存儲一張「能夠區分出四種顏色的16*16圖像」,就只要64B

因為FC的圖像基本單位正常是8*8作為一個圖塊(上圖是四個圖塊),這裡就以左上角的一個圖塊來講解,涉及到的數據量是16B,其他圖塊的數據量和是一樣的。

首先,很容易看出,一個圖塊包括透明色,一共就四種顏色,這是遊戲平台的限制,用一個兩位二進位數表示一種顏色,所以共有00 01 10 11四種用於區分圖像顏色的數值,由於調色版的定製,在圖中,00是透明,01是肉色,10是紅色,11是黑色。

不過FC存儲的圖塊結構一般不是直接連續存儲這個兩位二進位數(GB就是連續存儲),而是將每個顏色的低位和高位分離出來,各自連續存儲。所以這裡我們同樣要對圖像進行顏色分離,把一張圖片變換成兩張圖片(若引起不適還請見諒)。

左圖是將紅色全部替換成黑色,並刪除肉色,這麼做是為了連續記錄圖像點陣的高位數據(高位是1的有紅色和黑色,透明和肉色的高位是0)。

右圖是將肉色全部替換成黑色,並刪除紅色,這麼做是為了連續記錄圖像點陣的低位數據(低位是1的有肉色和黑色,透明和紅色的低位是0)。

這麼做的話,我們就得到了兩張單色圖像,實際使用的時候,如果兩方讀取到的都是0(00),那就顯示透明了,如果在某位讀取到1而在另一位讀取到0(10或01),那麼就顯示對應的顏色,如果高低位讀取到的都是1(11),那麼就顯示黑色。現在我們將兩張圖片上的點用0代表透明 1代表顏色,進行標註,可以得到

高位的連續數據
01110011
10001111
10011111
01111101
01100001
01100010
00111111
00110000

低位的連續數據
01110011
11111100
11110000
01011111
01011111
01011111
00111111
00101111

比如左上角第一個像素點,讀取到00,便是透明

這個二進位的點陣,就是最終存儲到遊戲當中的圖像數據,二進位中每8位代表一個位元組,這裡一行就是一個位元組,16行正好16B。

(可選)你可以把這個二進位點陣轉換成平時更多使用的16進位代碼,將上面的二進位點陣,轉換成十六進位便是

738F9F7D61623F30 73FCF05F5F5F3F2F

這種轉換,微軟的計算器都能做到。

這樣就完成了一個圖塊,它的數據大小是16B,未經壓縮,FC遊戲正常的圖像都是這麼存儲的。

遊戲ROM中對應圖像的四行。你可以用同樣的方法反推導出圖片,修改並再次導入回去(當然,如果真要改,有專用工具,不用這麼麻煩)。

所以其實並不是說遊戲用了什麼技術能寫進這麼多東西,而是本身的設計就是如此裝入數據,說白了,對數據所能提供的信息量進行限制,那麼用於表達數據所需要的數據量自然也就跟著減小,對於圖像來說,單個圖塊最多4色就是一個明顯的限制,更不用說什麼同屏允許多少圖塊,同屏多少顏色等等的限制了。

註:實際遊戲中兩個點陣中讀取到的0和1一共對應四種顏色00 01 10 11,實際上是哪種顏色是由調色板處理完成,並不是說00就一定是透明,11就一定是黑色。這裡的例子是Mario,然而Luigi用的圖像數據也還是這一段,不過通過調色版選擇了其他顏色(比如紅色換成綠色)來代表Luigi。

上面的講述改來改去,也不知道如何能夠用比較合適的方式來說清楚,先這樣吧。


說一點,重構。

以前哪裡看到的,草堆和雲朵的形狀是一樣的。

其實這並不是超級馬里奧3…

跑題了+_+

但是重構確實很重要:-D


感謝邀請, 如有疏漏歡迎指正, 補充

先來了解下FC 的技術參數:

FC使用一顆理光製造的8位的6502中央處理器,PAL制式機型運行頻率為1.773447MHz,NTSC制式機型運行頻率為1.7897725MHz,內存和顯存為2KB。

FC有一顆可顯示64種顏色的圖像控制器(PPU),畫面可顯示2層捲軸和5個頁面,其中2個背景頁面各佔用1KB顯存;由於顯存的限制,最多只能顯示16種顏色。

FC遊戲通常以只讀內存形式存放於可插在主機插槽上的遊戲卡中,容量有LA系列24K,LB系列40K,LC系列48K,LD系列64K,LE系列80K,LF系列128K,LG系列160K,LH系列256K,特卡系列和多合一卡帶等。還有一些帶有電池用來保存遊戲進度。

超級瑪麗3 是1988年出來的, 128K 在當時已經算是FC上的大作. 8位機的極限內存定址是256k, 所以當時128k 已經是"龐大"的容量, 就如同32位機時代初期, 開發一個使用2G內存的遊戲一樣的感覺. 只是由於摩爾定律, 讓現在的我們覺得不可思議而已.

由於當時的開發都是使用彙編語言, 彙編開發更加需要考慮性能和空間的問題, 所以整個遊戲的邏輯代碼會很精簡. 而在當時解析度下, 16色圖片的資源量很小. 再通過顯存的大小我們可以看出來, 最大的資源都不可能超過2KB.

不得不說, 在當時這樣"惡劣"的環境底下, 能開發出來至今依然讓人覺得精美好玩的遊戲, 的確是很強大. 宮本茂大叔的確不是徒有虛名.=D


超級馬里奧3其實是128KB的程序ROM(16KB頁面x8)加上128KB的字元RAM(8KB PPU字元頁x16)。

由於FC的CPU對卡帶的CPU RAM部分(這裡要說一下,FC的卡帶是直接連接到CPU的RAM匯流排的,ROM和RAM一視同仁)最大只能支持2個頁面也就是32KB的定址,超級馬里奧3使用了中期以後FC遊戲普遍採用的頁面切換晶元,一個頁面16KB作為遊戲核心程序,另一個頁面用來動態載入數據和邏輯。而FC的圖形輸出不是frame buffer模式而是PCG模式(類似於PC的字元模式,但是加入了捲動和掃描線控制,以及硬體活動塊功能),8KB包含512個8x8的字元,其卡帶的頁面切換晶元可以以1/4頁面為單位切換,可以形成很多種組合。


這對你其實意義不是很大了,你可以看下Wii U上的《馬里奧3D世界》印象上應該是150關左右,容量壓縮到了3G左右,不說秒殺,也算是碾壓現在幾乎所有動作遊戲的存在。還有對麥克風 觸摸屏 體感的教科書級別的支持,只此一家。

素材的重利用度主要集中在後幾大關,而前面的關卡光是建模放到其他廠商哪裡,不一定有多少個G。

然後就神級的動畫渲染,建模精度不高的情況下,渲染來提高畫面,還有各種複雜唬人的光效,你值得學習。


其實看看現在的遊戲,容量里佔大頭的是動畫、貼圖(特別是高清4K貼圖)、音頻啥的,代碼占容量並不多,而馬里奧的那個年代貼圖啥的基本不存在,所以容量才小,技術上的細節樓上的各位大神解釋過了我就不說了(這逼裝的好其實我不懂_(:з」∠)_)


每一代主機的後期都會出現一批所謂「吃透了機能」的作品。世嘉md有16人街霸,超任甚至移植了少年街霸2.


其實代碼占的容量遠沒你想像的大,就是後來PS和土星年代,一張CDROM里遊戲代碼部分也只幾十MB,其它都是動畫和音樂占容量


你肯定不知道在PC上,4k的文本(注意是可編輯文本)可以成為一個帶音樂的時間很長的3D動畫,128K的exe可以是一個功能完整的CS遊戲。

震撼吧?然並卵啊~

FC的那幫人,今天用大容量PC也沒倒騰出什麼像樣的世界級經典遊戲......嗎?比如【尾行3】?


推薦閱讀:

有沒有國產的遊戲引擎?為什麼很多遊戲公司都是去購買的引擎?
我最近在看 《遊戲引擎架構》 這本書,想做引擎是不是要先從普通的遊戲邏輯功能開發開始做起再參與引擎?
為什麼任天堂的壓縮技術如此黑科技?
為什麼日本的遊戲製作人這麼出名,而許多歐美遊戲被評論時我們很少提及他們的核心製作者。?
為什麼沒有一款日本手游能在中國市場本土化成功?

TAG:遊戲開發 | 馬力歐遊戲角色 | 小霸王遊戲機 | 紅白機FamilyComputer,FC | 懷舊經典遊戲 |