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

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

夢開始的地方——FC游戲開發(fā)指南(7)高性能的秘密:DMA

2021-10-28 16:23 作者:皮皮關(guān)做游戲  | 我要投稿

(本系列是一個(gè)回歸電子游戲原點(diǎn)的特別系列,作者 @goodorc_gamedev

上期鏈接:https://www.bilibili.com/read/cv13722007

上次文章介紹了精靈的概念。按照我們玩FC游戲的的經(jīng)驗(yàn),F(xiàn)C同屏處理幾十個(gè)精靈應(yīng)該不是難事。比如《沙羅曼蛇》,在模擬器里將背景層關(guān)閉,就可以看到同屏有幾十個(gè)精靈同時(shí)在屏幕上運(yùn)動(dòng):(一個(gè)敵人是由4個(gè)左右的精靈組成的,所以下圖至少有30個(gè)以上的精靈)

但是當(dāng)我用上次視頻的方法,將精靈拷貝到顯卡,發(fā)現(xiàn)只要超過10個(gè)精靈,就無法正常顯示了。

這是為什么呢?

還是因?yàn)镕C的CPU太慢了,速度不到PPU的三分之一,如果每幀通過0x2004端口循環(huán)拷貝幾十個(gè)精靈,那么CPU會死給你看。

所以FC高性能的秘密,就在于——精靈數(shù)據(jù)能夠以極高的速度傳輸給PPU,每秒輕松傳遞幾十次,實(shí)現(xiàn)數(shù)十個(gè)精靈每秒幾十次的移動(dòng)、變換。

1、DMA(Direct Memory Access)

百度百科上DMA的介紹很直截了當(dāng):

DMA(Direct Memory Access,直接存儲器訪問) 是所有現(xiàn)代電腦的重要特色,它允許不同速度的硬件裝置來溝通,而不需要依賴于CPU的大量中斷負(fù)載。

簡單來說,就是有一個(gè)專用硬件,它受CPU控制。只要CPU告訴它,把內(nèi)存里的哪一段地址的數(shù)據(jù)搬到PPU,它就會以極高的速度將內(nèi)存數(shù)據(jù)搬進(jìn)PPU。而且它走的還是一條“高速公路”,叫做DMA總線。

在DMA傳輸階段,CPU還可以騰出手做其它事情。

2、基于DMA的渲染流程

我按照參考資料,基于DMA改善了FC渲染流程,如圖:

解釋:

  1. 很多精靈對象,用struct數(shù)組表示,數(shù)組做成固定長度的即可。

  2. ★ 注意精靈數(shù)組的起始地址是專門指定的,下面會提到。

  3. 每一幀更新每個(gè)精靈對象的tile、位置等等。不需要的精靈填0即可。

  4. 在原來的程序中,每一幀要通過load_SP函數(shù)將精靈拷貝到PPU。但這次改為直接控制DMA,作用一樣是把很多精靈對象更新到PPU。

一旦想清楚了,就是這么簡單。

DMA傳輸?shù)腃語言寫法:




參數(shù)page=2,start=0是怎么回事呢?

任天堂文檔里是這么說的:

$4014 寫

DMA 訪問精靈 RAM:通過寫一個(gè)值 xx 到這個(gè)端口,引起 CPU 內(nèi)存地址為$xx00-$xxFF 的區(qū)域傳送到精靈內(nèi)存

簡單解釋:端口0x4014是一個(gè)DMA控制端口,往里寫一個(gè)0~255的數(shù)字,就會啟動(dòng)DMA,將內(nèi)存中0xXX00 ~ 0xXXFF的數(shù)據(jù)傳輸?shù)絇PU的精靈區(qū)。比如寫上2,就會自動(dòng)拷貝0x0200 ~ 0x02FF這一段精靈數(shù)據(jù)。

內(nèi)存中一整塊256字節(jié)的區(qū)域,比如從0x1A00 ~ 0x1AFF ,稱之為一頁(page)。

另一個(gè)參數(shù)start應(yīng)該是偏移量,暫時(shí)填0即可。

3、C語言特性——直接指定變量的內(nèi)存地址

我們一般學(xué)習(xí)C語言都是用PC機(jī)學(xué)習(xí),內(nèi)存足夠用,內(nèi)存地址也是由操作系統(tǒng)分配。但到了FC這種單片機(jī)系統(tǒng),就要借用更高級的C技巧了。

既然DMA要求必須事先說定精靈數(shù)據(jù)的地址,而且說好是傳一整頁。這就要求必須把精靈放在指定的地方,比如從0x0200開始,一直放到0x02ff,共256字節(jié)。每個(gè)精靈對象4字節(jié)(tile, x, y, attr),一頁可以放64個(gè)精靈。

寫法像這樣:




如果這樣定義,初始化的寫法:




只要用到精靈數(shù)據(jù)的地方,都要用類似的寫法修改。也許有更好的寫法。

至此,大家既可以參考第一篇文章放出的《spitfire》射擊游戲項(xiàng)目,也可以在《移動(dòng)》簡單項(xiàng)目中修改。

4、實(shí)例

《移動(dòng)》的測試項(xiàng)目,加入DMA后代碼修改如下:




上面這段代碼與之前的效果相同。讀者可以給它加上發(fā)射子彈的功能,看看最多能同時(shí)發(fā)射多少子彈。

5、將DMA指令寫成匯編

像DMA這種每幀調(diào)用的必要操作,寫在C語言循環(huán)里仍然不是最佳選擇。最好的辦法是直接寫成匯編,連函數(shù)調(diào)用也省了。

修改之前看過的crt0.s文件,找到中間的標(biāo)簽nmi:




nmi是一個(gè)特殊的中斷,在電視機(jī)的每幀渲染完畢后觸發(fā),在這里做一些每幀都需要做的DMA工作再合適不過了。

在inc tickcount那句代碼之前,插入DMA操作代碼:




編寫完畢后,應(yīng)刪除C語言中的SP_DMA(2,0)函數(shù)調(diào)用,顯示效果不變。


至此關(guān)于精靈Sprite的討論告一段落,下一期將介紹FC的背景地圖與卷軸功能。

(本文作者?@goodorc_gamedev。歡迎加入游戲開發(fā)群歡樂攪基:1082025059

對游戲開發(fā)感興趣的童鞋可戳這里進(jìn)一步了解:levelpp.com/


夢開始的地方——FC游戲開發(fā)指南(7)高性能的秘密:DMA的評論 (共 條)

分享到微博請遵守國家法律
自贡市| 永和县| 乾安县| 浮山县| 莱阳市| 峨眉山市| 台湾省| 历史| 宁晋县| 邳州市| 利辛县| 慈溪市| 松原市| 淄博市| 宜丰县| 湘乡市| 石门县| 阿尔山市| 鹿泉市| 东城区| 宜君县| 拉孜县| 东兰县| 峡江县| 翼城县| 白山市| 乳源| 酒泉市| 宁夏| 手机| 景东| 军事| 盐池县| 监利县| 化州市| 霍林郭勒市| 蒲城县| 绩溪县| 山东| 罗江县| 日照市|