日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于STM32设计的掌上游戏机(运行NES游戏模拟器)详细开发过程

發(fā)布時(shí)間:2023/12/14 编程问答 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于STM32设计的掌上游戏机(运行NES游戏模拟器)详细开发过程 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、環(huán)境與硬件介紹

開發(fā)環(huán)境:keil5

代碼風(fēng)格: 寄存器風(fēng)格,沒有采用庫函數(shù),底層代碼全部寄存器方式編寫,運(yùn)行效率高,注釋清楚。

MCU型號(hào): STM32F103ZET6

開發(fā)板: 正常的一塊STM32開發(fā)板,帶LCD插槽,帶4顆獨(dú)立按鍵。

游戲模擬器:? NES游戲模擬器

LCD :? ALIENTEK的3.5寸屏幕。(屏幕型號(hào)不重要,隨便一款都可以的,把屏幕底層驅(qū)動(dòng)代碼寫好,適配即可)

聲音輸出設(shè)備 : 采用VS1053 (SPI接口,操作方便)

游戲手柄: 支持FC游戲手柄

完成這個(gè)掌上游戲機(jī)需要使用的硬件設(shè)備不復(fù)雜,如果想要體驗(yàn)游戲,需要的必備硬件:

1. (必要)STM32F103系列最小系統(tǒng)版一個(gè)

2. (必要)LCD屏一塊。 2.8寸就可以了,價(jià)格便宜。

3. (非必要)FC游戲手柄一個(gè),驅(qū)動(dòng)時(shí)序很簡單(后面有單獨(dú)章節(jié)介紹),支持組合鍵,玩游戲體驗(yàn)感非常好。

? ? 如果不用FC游戲手柄,使用開發(fā)板幾個(gè)獨(dú)立按鍵也行,只是手感不好。

4.? (非必要)VS1053或者其他系列聲卡模塊一個(gè),游戲是有聲音的,要完美的體驗(yàn)游戲聲卡肯定是要的,不要也可以玩,只是沒有聲音而已。VS1053模塊支持SPI接口控制,時(shí)序簡單,驅(qū)動(dòng)代碼也不復(fù)雜,資料比較多,學(xué)起來,理解起來很容易。

5. (非必要)SD卡一張。主要存儲(chǔ)NES游戲文件,可以動(dòng)態(tài)加載想要玩的游戲,切換比較方便。

如果沒有SD卡,也想體驗(yàn)也可以,直接把游戲取模成二進(jìn)制放在數(shù)組里存放到STM32的FLASH里即可,STM32F103ZET6有512K的FLASH,存放一個(gè)游戲完全夠用,加載速度更加快。

6. (非必要) SRAM外部擴(kuò)展內(nèi)存,如果不需要從SD里加載游戲,就不需要外部內(nèi)存;如果使用SD卡加載游戲,就需要把游戲數(shù)據(jù)從SD卡里讀取出來,然后放在SRAM外部擴(kuò)展內(nèi)存芯片里。因?yàn)镾TM32F103ZET6本身只有64K內(nèi)存,放不下。

游戲體驗(yàn):STM32可以超頻到128M,運(yùn)行起來還是非常流暢,玩起來的感覺和正常的FC游戲機(jī)是一樣的,沒有卡頓,延遲。

游戲模擬器移植的是NES模擬器,開發(fā)過程中,代碼編寫了3個(gè)版本:

版本1:?精簡版的掌上游戲機(jī),最適合學(xué)習(xí),代碼牽扯很少,只有外設(shè)硬件只用到了LCD而已,最適合學(xué)習(xí),理解代碼運(yùn)行原理;不支持聲音輸出,不支持FC游戲手柄,不支持SD卡和文件系統(tǒng)(也就是不支持從SD卡上選擇游戲加載)。 這個(gè)版本的游戲是直接使用數(shù)組存放在代碼里的,游戲的操作是通過開發(fā)板上的4個(gè)按鍵控制(開發(fā)板的4個(gè)按鍵,分別控制角色的前進(jìn)、后退、暫停、跳躍),因?yàn)橹挥?個(gè)按鍵,沒有支持組合按鍵,所以體驗(yàn)起來不是很舒服,控制比較困難,完美體驗(yàn)還是要繼續(xù)加上FC游戲手柄。

版本2:?這也是精簡版的掌上游戲機(jī),在版本1的基礎(chǔ)之上加了VS1053模塊,支持聲音輸出,體驗(yàn)感要好一點(diǎn),能聽到游戲聲音。

版本3:?這是完整版本的掌上游戲機(jī),加入了FC游戲手柄支持,加入了VS1053聲卡驅(qū)動(dòng),加入了SD卡和FATFS文件系統(tǒng),可以正常從SD卡加載指定的游戲運(yùn)行,體驗(yàn)非常好。

3個(gè)版本的源代碼和NES的游戲集合,在下面的第3章有下載地址。

二、游戲運(yùn)行效果(超級(jí)瑪麗示例)

2.1? 超級(jí)瑪麗運(yùn)行截圖

2.2? 僅僅使用獨(dú)立按鍵操作游戲效果

單手錄制,單手操作,操作起來起來不太方便。

STM32上移植NES游戲框架-運(yùn)行超級(jí)瑪麗游戲

2.3?游戲自動(dòng)待機(jī)運(yùn)行效果(沒有操作)

基于STM32移植NES游戲框架-超級(jí)瑪麗游戲(動(dòng)畫)

三、資料下載地址

3.1 NES游戲集合下載?

一共有293款游戲,總有一款適合你。常見的超級(jí)瑪麗、魂斗羅、都有包含的。

地址:https://download.csdn.net/download/xiaolong1126626497/20722451

3.2? 工程源碼下載

地址:?https://download.csdn.net/download/xiaolong1126626497/20973545

?一共3個(gè)版本,它們之間的區(qū)別在第一章已經(jīng)介紹過。

三個(gè)都是keil工程,下載下來直接編譯、下載運(yùn)行體驗(yàn)。

四、什么是NES ??

NES就是紅白機(jī)的游戲,所謂的NES意思是歐美版的紅白機(jī),FC的美版,Nintendo entertainment system(任天堂娛樂系統(tǒng)),而日本的紅白機(jī)則叫family computer(FC)。

發(fā)展歷史-來至百度百科
1983年7月15日,由日本任天堂株式會(huì)社(原本是生產(chǎn)日式撲克即“花札”)的宮本茂先生領(lǐng)導(dǎo)開發(fā)的一種第三代家用電子游戲機(jī):FC,全稱:Family Computer,也稱作:Famicom;在日本以外的地區(qū)發(fā)售時(shí)則被稱為NES,全稱:Nintendo Entertainment System;在中國大陸、臺(tái)灣和香港等地,因其外殼為紅白兩色,所以人們俗稱其為“紅白機(jī)”,正式進(jìn)入市場銷售,并于后來取得了巨大成功,由此揭開了家用電子游戲機(jī)遍布世界任何角落,電子游戲全球大普及的序幕。

1985年,NES在北美地區(qū)的銷量3300萬臺(tái),比日本地區(qū)高出近一倍, 也占據(jù)了其全球市場份額的一半。 ?NES在北美首發(fā)時(shí)的捆綁游戲《打鴨子》(Duck hunt)總共取得近3000萬套(基本全部來自北美市場)銷量, [6] ?這在紅白機(jī)游戲中名列第二,僅次于《超級(jí)馬力歐》。?

1986年,任天堂在美國收3.1億美元,這一年美國游戲產(chǎn)業(yè)的規(guī)模4.3億美元,而在一年前,深陷雅達(dá)利沖擊的美國游戲業(yè)的收入僅1億美元。 [7] ?1988年發(fā)售的《超級(jí)馬力歐兄弟3》(Super Mario Bros. 3)在美國售出700萬套,在日本銷量達(dá)400萬,銷售額5.5億美元。

1989年,任天堂的游戲機(jī)已占領(lǐng)美國90%和日本95%的市場,任天堂成為游戲界巨無霸。?

?
2003年7月,FC發(fā)售二十周年,任天堂宣布FC游戲機(jī)正式停產(chǎn)。至此,FC全世界已累計(jì)銷售6000萬部以上。至今中國大陸、臺(tái)灣、香港與泰國甚至日本等地仍然在制造FC規(guī)格的兼容品。

任天堂成為了現(xiàn)代游戲產(chǎn)業(yè)的開創(chuàng)者,在很多方面上確立了現(xiàn)代電子游戲的標(biāo)準(zhǔn)。
FC巨大成功使任天堂年純利從1985年開始一直保持5億美元以上 ,其股票成為東京證券交易所績優(yōu)股代名詞,一度超越了3萬日元,市值超松下等企業(yè),很多人都把任天堂成功譽(yù)為新時(shí)代商業(yè)神話。?
任天堂紅白機(jī)(FC/NES)發(fā)行于1983年,在日本發(fā)行之后引起了不小的轟動(dòng),兩年之后進(jìn)軍北美市場,更加奠定了任天堂的家用游戲機(jī)霸主地位。當(dāng)人們正需要一個(gè)高品質(zhì)的家用游戲機(jī)的時(shí)候,任天堂拿出了他們的全部家當(dāng),首發(fā)的數(shù)款游戲都贏得了玩家的贊譽(yù),超級(jí)馬力歐更成為了永遠(yuǎn)的經(jīng)典。在那個(gè)年代,擁有一臺(tái)紅白機(jī)應(yīng)該是孩子們最大的夢想了。 根據(jù)外媒的數(shù)據(jù),在1990年30%的美國家庭都擁有NES主機(jī)。

五、工程源碼分析: 以精簡版本(1)為例

工程源碼全部采用寄存器代碼風(fēng)格,基本上每行都有詳細(xì)的注釋;雖然STM32支持庫函數(shù)方式開發(fā),效率更加快,但是寄存器方式可以更方便了解CPU底層寄存器的一些配置,對以后在學(xué)習(xí)使用其他類型的微處理器是非常有幫助的。

5.1 工程文件布局

?5.2 主函數(shù)代碼

主函數(shù)里完成LCD屏幕初始化,按鍵初始化,LED燈初始化,串口初始化,FC游戲手柄初始化,默認(rèn)把LCD屏幕清屏為黑色。

LCD屏采用FSMC驅(qū)動(dòng)的,把FSMC時(shí)序速度配置到最快,達(dá)到STM32能支持的最快速度,提高LCD刷屏速度。

初始化完畢最后,調(diào)用了LoadNes函數(shù),完成游戲加載;如果加載失敗,就回到下面執(zhí)行while循環(huán),閃爍LED燈。

代碼如下:

#include "stm32f10x.h" #include "led.h" #include "lcd.h" #include "delay.h" #include "key.h" #include "usart.h" #include <string.h> #include <stdio.h> #include "joypad.h"extern u8 LoadNes(u8* pname,u32);//游戲文件可以通過winhex文件生成C源碼數(shù)組 extern const unsigned char nes_data1[40976];//超級(jí)瑪麗游戲的文件 extern const unsigned char nes_data2[262160];//魂斗羅游戲的文件/* 移植說明: 1. 加入游戲手柄 2. 優(yōu)化了游戲刷新的幀率 3. 加入開發(fā)板本身自帶按鍵控制 */ int main() {BeepInit(); //蜂鳴器初始化LedInit(); //LED燈初始化 UsartInit(USART1,72,115200);KeyInit(); //按鍵初始化printf("串口工作正常!\r\n");LcdInit(); //LCD初始化//JoypadInit(); //游戲手柄初始化LcdClear(0xFFFF);/* 0000 0000:保留 0000 0001: DATAST保持時(shí)間=2個(gè)HCLK時(shí)鐘周期 0000 0010: DATAST保持時(shí)間=3個(gè)HCLK時(shí)鐘周期 …… 1111 1111: DATAST保持時(shí)間=256個(gè)HCLK時(shí)鐘周期(這是復(fù)位后的默認(rèn)數(shù)值) 0、1、2、3、4、5、6、7、8、9、10、11、12、13、14 */LcdClear(0);//開始運(yùn)行游戲LoadNes((unsigned char*)nes_data1,40976); //超級(jí)瑪麗//LoadNes((unsigned char*)nes_data2,262160); //魂斗羅while(1){ LED1=!LED1;DelayMs(400);} }

?5.3 加載NES游戲:LoadNes函數(shù)介紹

LoadNes函數(shù)原型:

u8 LoadNes(unsigned char* pname,u32 size)

該函數(shù)傳入NES游戲數(shù)據(jù)地址,和游戲數(shù)據(jù)大小進(jìn)來。

現(xiàn)在這個(gè)版本沒有使用SD卡和文件系統(tǒng),游戲的文件數(shù)據(jù)是直接加到代碼里編譯的。

?這兩個(gè)數(shù)組是超級(jí)瑪麗和魂斗羅的數(shù)據(jù)。(直接使用打開文件,使用WinHEX軟件打開,全選,右鍵編輯,選擇復(fù)制,選擇C源碼,復(fù)制成數(shù)組形式粘貼到keil里即可)

?函數(shù)里面主要完成了NES模擬器基本的初始化。

主要完成了STM32超頻配置,配置鎖相環(huán)為16倍,超頻到128MHZ。

超頻配置代碼如下:

/* 函數(shù)功能:頻率設(shè)置 參 數(shù):PLL,倍頻數(shù) */ void NesClockSet(u8 PLL) {u8 temp=0; RCC->CFGR&=0XFFFFFFFC; //修改時(shí)鐘頻率為內(nèi)部8M RCC->CR&=~0x01000000; //PLLOFF RCC->CFGR&=~(0XF<<18); //清空原來的設(shè)置PLL-=2; //抵消2個(gè)單位RCC->CFGR|=PLL<<18; //設(shè)置PLL值 2~16RCC->CFGR|=1<<16; //PLLSRC ON FLASH->ACR|=0x12; //FLASH 2個(gè)延時(shí)周期RCC->CR|=0x01000000; //PLLONwhile(!(RCC->CR>>25)); //等待PLL鎖定RCC->CFGR|=0x02; //PLL作為系統(tǒng)時(shí)鐘 while(temp!=0x02) //等待PLL作為系統(tǒng)時(shí)鐘設(shè)置成功{ temp=RCC->CFGR>>2;temp&=0x03;} }

接下來初始化NES游戲模擬器的必要參數(shù),最后調(diào)用NesEmulateFrame函數(shù)進(jìn)入NES游戲主循環(huán)代碼,開始運(yùn)行游戲。

LoadNes函數(shù)完整代碼如下:

/* 函數(shù)功能:開始nes游戲 參 數(shù):pname:nes游戲路徑 u32 size 游戲大小 返 回 值:0,正常退出1,內(nèi)存錯(cuò)誤2,文件錯(cuò)誤3,不支持的map */ u8 LoadNes(unsigned char* pname,u32 size) {u8 res=0; res=NesSramMalloc(); //申請內(nèi)存 romfile=(u8*)pname; //游戲源碼地址NESrom_crc32=get_crc32(romfile+16,size-16);//獲取CRC32的值 res=LoadNesRom(); //加載ROMprintf("res=%d\r\n",res); NesClockSet(16); //設(shè)置系統(tǒng)時(shí)鐘為128MHZ 16*8JoypadInit(); //游戲手柄初始化cpu6502_init(); //初始化6502,并復(fù)位 Mapper_Init(); //map初始化PPU_reset(); //ppu復(fù)位apu_init(); //apu初始化 NesEmulateFrame(); //進(jìn)入NES模擬器主循環(huán) return res; }

5.3 NES游戲主循環(huán)代碼

詳細(xì)代碼如下:

//nes模擬器主循環(huán) void NesEmulateFrame(void) { u8 nes_frame;NesSetWindow();//設(shè)置窗口while(1){ // LINES 0-239PPU_start_frame();for(NES_scanline = 0; NES_scanline< 240; NES_scanline++){run6502(113*256);NES_Mapper->HSync(NES_scanline);//掃描一行 if(nes_frame==0)scanline_draw(NES_scanline);else do_scanline_and_dont_draw(NES_scanline); } NES_scanline=240;run6502(113*256);//運(yùn)行1線NES_Mapper->HSync(NES_scanline); start_vblank(); if(NMI_enabled()) {cpunmi=1;run6502(7*256);//運(yùn)行中斷}NES_Mapper->VSync();// LINES 242-261 for(NES_scanline=241;NES_scanline<262;NES_scanline++){run6502(113*256); NES_Mapper->HSync(NES_scanline); } end_vblank(); NesGetGamepadval(); //每3幀讀取游戲手柄數(shù)據(jù)nes_frame++;if(nes_frame>NES_SKIP_FRAME){nes_frame=0;//跳幀 }} }

?進(jìn)來就先調(diào)用了NesSetWindow(void)函數(shù),設(shè)置窗口大小,這里面就調(diào)用了LCD的接口,如果是其他的LCD屏,使用本代碼只需要把這里適配一下即可。

u8 nes_xoff=0; //顯示在x軸方向的偏移量(實(shí)際顯示寬度=256-2*nes_xoff) //設(shè)置游戲顯示窗口 void NesSetWindow(void) { u16 lcdwidth,lcdheight;lcdwidth=256;lcdheight=240; nes_xoff=0;LcdSetWindow(32,0,lcdwidth,lcdheight);LcdWriteRAM_Prepare();//寫入LCD RAM的準(zhǔn)備 }

接下來就進(jìn)入到NES游戲的主循環(huán)代碼,開始循環(huán)一幀一幀的刷出圖像數(shù)據(jù),達(dá)到游戲的效果。

設(shè)置窗口大小之后,下面就是從NES游戲數(shù)據(jù)文件里取出顏色數(shù)據(jù),然后for循環(huán)一行一行刷屏即可。

上面的設(shè)置窗口大小的代碼其實(shí)并不是必要的,只是當(dāng)前使用的LCD支持坐標(biāo)自增(一般LCD都支持的),設(shè)置LCD的窗口范圍之后,連續(xù)給LCD寫數(shù)據(jù),LCD的坐標(biāo)會(huì)自動(dòng)自增,提高刷屏效率而已。如果你的LCD屏并不支持坐標(biāo)自增或者你不會(huì)寫代碼,也想移植,那完全不用設(shè)置窗口那個(gè)函數(shù),你只需要提供一個(gè)畫點(diǎn)函數(shù),把for循環(huán)里的刷屏代碼里行掃描改掉就行。

函數(shù)里的這個(gè)for循環(huán)就是主要刷出圖像的代碼,如果想要移植到其他LCD屏,主要就改這里,示例代碼如下:

for(NES_scanline = 0; NES_scanline< 240; NES_scanline++) {run6502(113*256);NES_Mapper->HSync(NES_scanline);//掃描一行 if(nes_frame==0)scanline_draw(NES_scanline);else do_scanline_and_dont_draw(NES_scanline); }

里面調(diào)用scanline_draw函數(shù)是按行掃描(也就是一行一行繪制圖像),scanline_draw函數(shù)里面也是一個(gè)for循環(huán),細(xì)化到每個(gè)像素點(diǎn),按照每個(gè)像素點(diǎn)繪制到屏幕上,代碼里的LCD_RAM就是當(dāng)前LCD屏的地址,因?yàn)楫?dāng)前LCD屏采用的是FSMC,這個(gè)LCD_RAM就是FSMC地址,向這個(gè)地址寫數(shù)據(jù),FSMC就產(chǎn)生8080時(shí)序?qū)?shù)據(jù)送給LCD顯示屏,刷新顯示出來。

scanline_draw函數(shù)詳細(xì)刷屏代碼如下:

extern u8 nes_xoff; //顯示在x軸方向的偏移量(實(shí)際顯示寬度=256-2*nes_xoff) void scanline_draw(int LineNo) {uint16 i; u16 sx,ex;do_scanline_and_draw(ppu->dummy_buffer); sx=nes_xoff+8;ex=256+8-nes_xoff;if(lcddev.width==480){for(i=sx;i<ex;i++){ LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值 } for(i=sx;i<ex;i++){ LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值i++;LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值LCD_RAM=NES_Palette[ppu->dummy_buffer[i]];//得到顏色值} }else{for(i=sx;i<ex;i++){ LCD_RAM=NES_Palette[ppu->dummy_buffer[i++]]; LCD_RAM=NES_Palette[ppu->dummy_buffer[i++]]; LCD_RAM=NES_Palette[ppu->dummy_buffer[i++]]; LCD_RAM=NES_Palette[ppu->dummy_buffer[i++]]; LCD_RAM=NES_Palette[ppu->dummy_buffer[i++]]; LCD_RAM=NES_Palette[ppu->dummy_buffer[i++]]; LCD_RAM=NES_Palette[ppu->dummy_buffer[i++]]; LCD_RAM=NES_Palette[ppu->dummy_buffer[i++]]; LCD_RAM=NES_Palette[ppu->dummy_buffer[i++]]; LCD_RAM=NES_Palette[ppu->dummy_buffer[i++]]; LCD_RAM=NES_Palette[ppu->dummy_buffer[i++]]; LCD_RAM=NES_Palette[ppu->dummy_buffer[i++]]; LCD_RAM=NES_Palette[ppu->dummy_buffer[i++]]; LCD_RAM=NES_Palette[ppu->dummy_buffer[i++]]; LCD_RAM=NES_Palette[ppu->dummy_buffer[i++]]; LCD_RAM=NES_Palette[ppu->dummy_buffer[i]]; }} }

運(yùn)行完刷屏的for循環(huán)函數(shù),一幀游戲圖像就顯示在LCD上了。

接下來就是掃描按鍵值,完成游戲人物的控制,函數(shù)里調(diào)用了NesGetGamepadval()函數(shù),讀取按鍵值刷新按鍵狀態(tài)。

NesGetGamepadval()函數(shù)代碼如下:

/* 鍵值說明: 開始鍵:8 選擇建:4 方向右:128 方向左:64 方向上:16 方向下:32功能鍵上/左:2 功能鍵下/右:1組合鍵:方向右與讀取游戲手柄數(shù)據(jù)和功能鍵左 :130*/void NesGetGamepadval(void) { u8 key; // PADdata0=GetJoypadKey(); //讀取手柄1的值//printf("%d\r\n",PADdata0);key=GetKeyValue(0);if(key==1)PADdata0=8;else if(key==2)PADdata0=128;else if(key==3)PADdata0=64;else if(key==4)PADdata0=1;else PADdata0=0; }

NES游戲模擬器定義了兩個(gè)全局變量,分別記錄游戲手柄1和游戲手柄2的數(shù)據(jù),因?yàn)镹ES游戲是可以兩個(gè)人一起玩的。

u8 PADdata0; //手柄1鍵值 [7:0]右7 左6 下5 上4 Start3 Select2 B1 A0 u8 PADdata1; //手柄2鍵值 [7:0]右7 左6 下5 上4 Start3 Select2 B1 A0

只需要在這個(gè)函數(shù)給這兩個(gè)全局變量賦予正確的值,游戲人物就可以按照正常的動(dòng)作畫面出現(xiàn)。

至于你的物理按鍵采用FC游戲手柄,還是普通的其他按鍵,只要這兩個(gè)全局變量的值正確那就沒問題。? 所有手柄采用什么不重要,關(guān)鍵把代碼這里邏輯看懂,看懂了你就知道程序的運(yùn)行邏輯了。

到此,版本1的 主要代碼就分析完畢了,其他的詳細(xì)過程可以看工程源碼,把程序跑起來了,一切都懂了。

六、工程源碼分析: 以完整版本(3)為例

這個(gè)版本加入了游戲手柄,VS1053、SD、FATFS文件系統(tǒng)等功能,這里接著第五章分析,下面就主要分析新加入的代碼內(nèi)容。

6.1 FC游戲手柄介紹

?FC游戲手柄,大致可分為兩種:一種手柄插口是 11 針的,一種是 9 針的。但 11 針的現(xiàn)在市面上很少了,現(xiàn)在幾乎都是使用 9 針 FC 組裝手柄,下面就是介紹的是 9 針 FC 手柄,該手柄還有一個(gè)特點(diǎn),就是可以直接和DR9 的串口頭對插!這樣同開發(fā)板的連接就簡單了。

FC 手柄的外觀如圖所示:

這種手柄一般有 10 個(gè)按鍵(實(shí)際是 8 個(gè)鍵值):上、下、左、右、 Start、 Select、 A、 B、 A連發(fā)、 B 連發(fā)。這里的 A 和 A 連發(fā)是一個(gè)鍵值,而 B 和 B 連發(fā)也是一個(gè)鍵值,只是連發(fā)按鍵當(dāng)你一直按下的時(shí)候,會(huì)不停的發(fā)送(方便快速按鍵,比如發(fā)炮彈之類的功能)。

FC 手柄的控制電路,由 1 個(gè) 8 位并入串出的移位寄存器(CD4021),外加一個(gè)時(shí)基集成電路(NE555,用于連發(fā))構(gòu)成。不過現(xiàn)在的手柄,為了節(jié)約成本,直接就在 PCB 上做綁定了,所以你拆開手柄,一般是看不到里面有四四方方的 IC,而只有一個(gè)黑色的小點(diǎn),所有電路都集成到這個(gè)里面了,但是他們的控制和讀取方法還是一樣的。

游戲上手柄數(shù)據(jù)讀取時(shí)序

從上圖可看出,讀取手柄按鍵值的信息十分簡單:先 Latch(鎖存鍵值),然后就得到了第一個(gè)按鍵值(A),之后在 Clock 的作用下,依次讀取其他按鍵的鍵值,總共 8 個(gè)按鍵鍵值。

常規(guī)狀態(tài)下,LATCH為低電平,CLK為高電平,DATA為高電平,這也是初始化端口時(shí)的狀態(tài)。?

單片機(jī)讀取鍵值時(shí)序很簡單,LATCH先發(fā)送一個(gè)高脈沖,數(shù)據(jù)將鎖存到手柄內(nèi)部的移位寄存器,然后在CLK時(shí)鐘下降沿?cái)?shù)據(jù)將從DATA低位在先連續(xù)發(fā)出。按鍵映射到數(shù)據(jù)的對應(yīng)位上,有鍵按下則對應(yīng)位為0無鍵按下則為1.即不按任何鍵時(shí),讀取數(shù)據(jù)為0xFF。

鍵值:

[7]:右

[6]:左

[5]:下

[4]:上

[3]:Start

[2]:Select

[1]:B

[0]:A

驅(qū)動(dòng)代碼示例:

功 能:手柄初始化函數(shù) 硬件連接:CLK :PD3 --時(shí)鐘線PB10:DATA --數(shù)據(jù)線PB11:LAT --鎖存接口 */ void JoypadInit(void) {/*1. 開時(shí)鐘*/RCC->APB2ENR|=1<<5; //PDRCC->APB2ENR|=1<<3; //PB/*2. 配置模式*/GPIOD->CRL&=0xFFFF0FFF;GPIOD->CRL|=0x00003000;GPIOB->CRH&=0xFFFF00FF;GPIOB->CRH|=0x00003800;/*3. 上拉*/GPIOD->ODR|=1<<3; }/* 功 能:獲取手柄的按鍵值 返回值:保存了一幀按鍵的狀態(tài) 鍵值: [7]:右 [6]:左 [5]:下 [4]:上 [3]:Start [2]:Select [1]:B [0]:A */ u8 GetJoypadKey(void) {u8 key=0,i;JOYPAD_LAT=1; //開始鎖存DelayUs(30);JOYPAD_LAT=0; //鎖存當(dāng)前的按鍵狀態(tài)for(i=0;i<8;i++){key=key>>1;if(JOYPAD_DATA==0)key|=0x80;JOYPAD_CLK=1; //輸出一個(gè)上升沿,告訴手柄發(fā)送數(shù)據(jù)DelayUs(30);JOYPAD_CLK=0; //數(shù)據(jù)線保持穩(wěn)定DelayUs(30); }return key; }

6.2 加載NES游戲:nes_load函數(shù)

?這里的nes_load函數(shù)和第五章的區(qū)別就是,游戲數(shù)據(jù)的來源是從SD卡讀取的。

?傳入游戲名稱去SD卡上打開指定文件,讀取數(shù)據(jù)進(jìn)來。

這里用到了外部SRAM內(nèi)存,因?yàn)樽x出的數(shù)據(jù)需要存放到數(shù)組里,STM32F103ZET6本身的內(nèi)存只有64K,肯定不夠用,這里申請的空間是從外部SRAM模塊里申請的,所以開發(fā)板還得帶一個(gè)SRAM芯片才行,沒有自帶就去淘寶買一個(gè)SRAM模塊即可(淘寶有個(gè)叫微雪的店鋪就有賣)。

詳細(xì)代碼如下:

u8 nes_load(u8* pname) {FIL *file; UINT br;u8 res=0; file=malloc(sizeof(FIL)); if(file==0)return 1; //內(nèi)存申請失敗. res=f_open(file,(char*)pname,FA_READ);if(res!=FR_OK) //打開文件失敗{printf("%s 文件打開失敗!\r\n",pname);free(file);return 2;}else{printf("%s 文件打開成功!\r\n",pname);}res=nes_sram_malloc(file->fsize); //申請內(nèi)存 if(res==0){f_read(file,romfile,file->fsize,&br); //讀取nes文件NESrom_crc32=get_crc32(romfile+16, file->fsize-16);//獲取CRC32的值 res=nes_load_rom(); //加載ROMif(res==0) { NesClockSet(16);//UsartInit(USART1,128,115200);JoypadInit();cpu6502_init(); //初始化6502,并復(fù)位 Mapper_Init(); //map初始化PPU_reset(); //ppu復(fù)位apu_init(); //apu初始化 nes_sound_open(0,APU_SAMPLE_RATE); //初始化播放設(shè)備nes_emulate_frame(); //進(jìn)入NES模擬器主循環(huán) nes_sound_close(); //關(guān)閉聲音輸出}}f_close(file);free(file);//釋放內(nèi)存nes_sram_free(); //釋放內(nèi)存return res; }

這里面調(diào)用了nes_sound_open函數(shù)初始化了音頻設(shè)備(VS1053)。這個(gè)非常重要,要理解游戲聲音是如何輸出的,就認(rèn)真看這里的流程。

nes_sound_open函數(shù)里初始化了VS1053音頻設(shè)備,然后開啟了定時(shí)器中斷,使用定時(shí)器去調(diào)用VS1053的播放接口,在定時(shí)器中斷服務(wù)器函數(shù)里完成聲音數(shù)據(jù)的輸出,這里聲音是存放在一個(gè)全局緩沖區(qū)里,后面游戲在主循環(huán)里運(yùn)行的時(shí)候會(huì)不斷的向這個(gè)緩沖區(qū)填數(shù)據(jù),定時(shí)器超時(shí)進(jìn)中斷就查詢是否有音樂可以播放,有就播放,沒有就出來。?

VS1052聲音播放代碼示例:

//音頻播放回調(diào)函數(shù) void nes_vs10xx_feeddata(void) { u8 n;u8 nbytes;u8 *p; if(nesplaybuf==nessavebuf)return;//還沒有收到新的音頻數(shù)據(jù)if(VS1053_DREQ!=0)//可以發(fā)送數(shù)據(jù)給VS10XX{ p=nesapusbuf[nesplaybuf]+nesbufpos; nesbufpos+=32; if(nesbufpos>APU_PCMBUF_SIZE){nesplaybuf++;if(nesplaybuf>(NES_APU_BUF_NUM-1))nesplaybuf=0; nbytes=APU_PCMBUF_SIZE+32-nesbufpos;nesbufpos=0; }else nbytes=32;for(n=0;n<nbytes;n++){if(p[n]!=0)break; //判斷是不是剩余所有的數(shù)據(jù)都為0? }if(n==nbytes)return; //都是0,則直接不寫入VS1053了,以免引起噠噠聲. VS1053_XDCS=0; for(n=0;n<nbytes;n++){VS1053_SPI_ReadWriteByte(p[n]); }VS1053_XDCS=1; } }

nes_sound_open函數(shù)代碼如下:

//NES打開音頻輸出 int nes_sound_open(int samples_per_sync,int sample_rate) {u8 *p;u8 i; p=malloc(100); //申請100字節(jié)內(nèi)存if(p==NULL)return 1; //內(nèi)存申請失敗,直接退出printf("sound open:%d\r\n",sample_rate);for(i=0;i<sizeof(nes_wav_head);i++)//復(fù)制nes_wav_head內(nèi)容{p[i]=nes_wav_head[i];}if(lcddev.width==480) //是480*480屏幕{sample_rate=8000; //設(shè)置8Khz,約原來速度的0.75倍}p[24]=sample_rate&0XFF; //設(shè)置采樣率p[25]=(sample_rate>>8)&0XFF;p[28]=sample_rate&0XFF; //設(shè)置字節(jié)速率(8位模式,等于采樣率)p[29]=(sample_rate>>8)&0XFF; nesplaybuf=0;nessavebuf=0; VS1053_Reset(); //硬復(fù)位VS1053_SoftReset(); //軟復(fù)位 VS1053_SetVol(200); //設(shè)置音量等參數(shù) //復(fù)位解碼時(shí)間VS1053_WriteCmd(SPI_DECODE_TIME,0x0000);VS1053_WriteCmd(SPI_DECODE_TIME,0x0000); //操作兩次while(VS1053_SendMusicData(p)); //發(fā)送wav headwhile(VS1053_SendMusicData(p+32)); //發(fā)送wav headTimerInit(TIM6,72,1000); //1ms中斷一次free(p); //釋放內(nèi)存return 1; }

?初始化完畢之后,就調(diào)用nes_emulate_frame函數(shù)進(jìn)入到游戲主循環(huán)。

6.3 游戲主循環(huán)代碼

現(xiàn)在這份代碼比第五章代碼增加了一個(gè)聲音輸出函數(shù),調(diào)用VS1053,播放游戲的聲音。

?apu_soundoutput函數(shù)代碼如下:

//apu聲音輸出 void apu_soundoutput(void) { u16 i;apu_process(wave_buffers,APU_PCMBUF_SIZE);for(i=0;i<30;i++)if(wave_buffers[i]!=wave_buffers[i+1])break;//判斷前30個(gè)數(shù)據(jù),是不是都相等?if(i==30&&wave_buffers[i])//都相等,且不等于0{for(i=0;i<APU_PCMBUF_SIZE;i++)wave_buffers[i]=0;//是暫停狀態(tài)輸出的重復(fù)無效數(shù)據(jù),直接修改為0.從而不輸出雜音. }clocks=0;nes_apu_fill_buffer(0,wave_buffers); }

最后調(diào)用了nes_apu_fill_buffer 函數(shù)將數(shù)據(jù)賦值給VS1053緩沖區(qū)進(jìn)行播放。

在前面已經(jīng)分析了音頻初始化代碼,里面初始化了定時(shí)器,會(huì)不斷的查詢緩沖區(qū)是否有音樂數(shù)據(jù)需要播放,有就播放,沒有就輸出,這個(gè)函數(shù)就是向音頻緩沖區(qū)填充數(shù)據(jù)的。

nes_apu_fill_buffer 函數(shù)代碼如下:

//NES音頻輸出到VS1053緩存 void nes_apu_fill_buffer(int samples,u8* wavebuf) { u16 i; u8 tbuf;for(i=0;i<APU_PCMBUF_SIZE;i++){nesapusbuf[nessavebuf][i]=wavebuf[i]; }tbuf=nessavebuf;tbuf++;if(tbuf>(NES_APU_BUF_NUM-1))tbuf=0;while(tbuf==nesplaybuf)//輸出數(shù)據(jù)趕上音頻播放的位置了,等待.{ DelayMs(5);}nessavebuf=tbuf; }

到此,音頻的主要代碼就分析完畢了。 可以下載程序去體驗(yàn)一下游戲,懷戀童年時(shí)光了

總結(jié)

以上是生活随笔為你收集整理的基于STM32设计的掌上游戏机(运行NES游戏模拟器)详细开发过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

99这里只有久久精品视频 | 久久午夜免费视频 | 中文在线中文a | 女女av在线| 日韩成人精品一区二区 | 五月天激情综合 | 日韩激情视频在线 | 丝袜美腿av | 日韩欧美高清 | 欧美日韩国产在线 | 亚洲a色 | 狠狠干2018| 国产中文字幕在线看 | 国产在线黄 | 婷婷色六月天 | 黄色小说免费观看 | 成人黄在线观看 | 91高清不卡 | 在线观看一级视频 | av电影免费在线看 | 成人 亚洲 欧美 | 国产精品一区二区在线观看免费 | 婷婷av在线 | 91热这里只有精品 | 91av在线播放视频 | 最新免费av在线 | 深爱激情综合网 | 亚洲aⅴ乱码精品成人区 | 黄色网免费 | 又色又爽又激情的59视频 | 在线a人片免费观看视频 | 在线视频91 | 日韩影视精品 | 夜夜澡人模人人添人人看 | 亚洲日本精品视频 | 国产精品白浆 | 欧美视频不卡 | 国产一区二区久久精品 | 99麻豆视频 | 亚洲在线网址 | 国产精品夜夜夜一区二区三区尤 | 99热在线这里只有精品 | 成人精品视频久久久久 | 一本一本久久a久久精品综合妖精 | 欧洲性视频 | 国产五月色婷婷六月丁香视频 | 毛片www| 日韩欧美大片免费观看 | 日韩在线免费小视频 | 日本福利视频在线 | 黄色1级大片 | 91亚洲欧美激情 | 在线免费观看视频一区 | 人人爱人人添 | 国产精品久久久久一区二区三区共 | 岛国精品一区二区 | 国产免费又爽又刺激在线观看 | 久久精品99国产精品酒店日本 | 久久99九九99精品 | 4438全国亚洲精品观看视频 | 中文在线a√在线 | 国产精品毛片久久久久久久久久99999999 | a久久久久久 | 夜夜视频 | 福利视频一区二区 | 四虎影视成人永久免费观看亚洲欧美 | 在线观看国产高清视频 | 久久电影网站中文字幕 | 特黄一级毛片 | 激情偷乱人伦小说视频在线观看 | 国产一级电影免费观看 | 91黄色免费网站 | 黄色av电影一级片 | 国产精品亚洲片夜色在线 | 亚洲黄色免费观看 | 深爱综合网 | 欧美日韩亚洲第一页 | 国产精品麻豆欧美日韩ww | 国产精品自产拍 | 五月婷婷久久丁香 | 天天干,狠狠干 | 久免费视频 | 在线视频一区观看 | 天天干天天操天天 | 国产精品系列在线播放 | 久99久视频 | 天天天干 | 国产婷婷vvvv激情久 | av免费福利| 亚洲区精品视频 | 久久只精品99品免费久23小说 | 中文字幕亚洲欧美 | 国产一区视频导航 | 亚洲精品xxx | 这里只有精品视频在线观看 | 中文字幕电影高清在线观看 | 亚洲激情国产精品 | 亚洲精品中文字幕在线 | 日日碰狠狠躁久久躁综合网 | 成人丝袜| 久久久午夜视频 | 在线观看免费一区 | 免费看黄色毛片 | 久久成人午夜 | 丝袜美腿亚洲综合 | 一级一级一片免费 | 欧美国产日韩在线观看 | 91av中文字幕 | 日女人电影 | 天天综合天天综合 | 免费精品视频在线观看 | 日本久久中文 | 久久久久亚洲国产精品 | 久久视频这里只有精品 | 五月激情久久久 | 久久精品免费播放 | 欧洲精品码一区二区三区免费看 | 欧美成人播放 | 国产精品免费久久久久影院仙踪林 | 欧美二区视频 | 91网在线看 | 91精品网站 | 国产一级黄色片免费看 | 亚洲区精品视频 | www.久草视频 | 超碰公开97| 91.精品高清在线观看 | 日韩美女av在线 | 超碰97免费在线 | 最近中文字幕在线中文高清版 | 国产一区二区精品久久91 | 久久精品免费 | 最新成人av | 综合五月婷婷 | 亚洲精品大全 | 97超级碰碰碰碰久久久久 | 中文电影网 | 色婷婷在线播放 | 一区二区 不卡 | 黄色精品一区 | 天天干天天操天天干 | 黄av资源| 国外调教视频网站 | 久操97 | 黄色三级在线观看 | 中文字幕久久精品 | 天天操天天色天天射 | 五月宗合网| 久久视频一区 | 日韩在线观看精品 | av网站免费在线 | 国产一区私人高清影院 | 欧美日韩不卡一区二区三区 | 黄色毛片视频免费观看中文 | 久久手机视频 | 五月婷激情 | 永久免费精品视频网站 | 亚洲爽爽网 | 国产精品自拍av | 精品久久久久久久久久久久久 | 国产精品一区二区三区电影 | 久草在线视频中文 | 亚洲精品激情 | 99视频久 | 99精品热| 久久精品久久综合 | 天天射天天射 | 人人插人人射 | 麻豆影视在线播放 | 色婷婷婷 | 久久久久久久久福利 | 久久久精品久久日韩一区综合 | 97超碰人人爱 | 99草视频| 毛片无卡免费无播放器 | 日日爽夜夜操 | 成年人视频免费在线 | 欧美日韩高清一区二区 国产亚洲免费看 | 91视频链接 | 夜夜爽夜夜操 | 国产精品视频在线看 | 成人黄色在线电影 | 最新日本中文字幕 | 在线观看日本韩国电影 | 中文字幕色站 | 美女免费视频网站 | 亚洲激情网站免费观看 | 久久精品亚洲综合专区 | 国产精品成人一区 | 久青草国产在线 | 国产免费视频一区二区裸体 | 成人免费观看a | 久青草电影 | 91在线视频免费91 | 国产精品久久久亚洲 | 午夜久久成人 | 亚洲精品欧美精品 | 国产一区二区在线观看视频 | 日本精品视频在线 | 精品久久久久国产 | 波多野结衣在线播放一区 | 狠狠色丁香婷婷综合最新地址 | 91麻豆精品一区二区三区 | 国产精品免费麻豆入口 | 国产精品99久久久精品免费观看 | 精品国产乱码久久久久久久 | 黄色免费网站下载 | 色吊丝在线永久观看最新版本 | 黄色小网站在线观看 | 999国产精品视频 | 四虎成人精品 | 亚洲激情综合网 | 欧美成人在线免费观看 | 午夜久操 | 97视频在线观看成人 | 91视频在线观看大全 | 日韩精品一区二区三区第95 | 最新日韩在线观看视频 | 久久av电影| 久久精品国产亚洲a | 91污污视频在线观看 | 91中文字幕在线 | av高清免费在线 | 久久久久婷 | 日韩一级片网址 | 久久看片 | 国产精品久久久久免费观看 | 美州a亚洲一视本频v色道 | 日韩在线视频播放 | 国产精品第三页 | 国产裸体无遮挡 | 日韩一级黄色大片 | av成人在线电影 | 欧美aaa一级 | 亚洲专区欧美 | 免费国产黄线在线观看视频 | 91网站在线视频 | 怡红院av久久久久久久 | 婷婷中文字幕 | 午夜视频欧美 | 中文字幕在线视频一区二区三区 | 国产日韩在线一区 | 特级西西444www高清大视频 | 黄色成人av | 亚洲精品66 | 国内成人精品视频 | 99亚洲国产精品 | 久久精品国产成人 | 久久久私人影院 | 免费在线观看黄 | 一级免费观看 | 日韩三区在线观看 | 免费av免费观看 | 色就色,综合激情 | 国产视频一区二区在线播放 | 国产亲近乱来精品 | 国产精品美女久久久久久免费 | 免费网站看v片在线a | 欧美日韩另类视频 | 96看片| 欧美一级大片在线观看 | 国产四虎在线 | 最近高清中文在线字幕在线观看 | 成人网大片 | 亚洲一区二区高潮无套美女 | 狠狠操综合网 | 亚洲国产精品女人久久久 | 8090yy亚洲精品久久 | 欧美日韩在线视频一区 | 久草香蕉在线 | 在线看片91 | 最近高清中文在线字幕在线观看 | 激情婷婷色 | 99婷婷狠狠成为人免费视频 | 国产精品久久99精品毛片三a | 91在线网址 | 九月婷婷色 | 国产在线观 | 国产成人精品综合 | 成全免费观看视频 | 制服丝袜天堂 | 久久精品久久99 | 香蕉免费 | 亚洲成人家庭影院 | jizz18欧美18 | 亚洲精品美女久久久久网站 | 欧美影片| 日本在线观看一区二区 | 欧美专区日韩专区 | 丁香久久激情 | 欧洲精品视频一区 | 国产精品99久久久久久久久久久久 | 97人人精品 | 国产91精品看黄网站在线观看动漫 | 久久综合色天天久久综合图片 | 久操中文字幕在线观看 | 成年人国产视频 | 在线亚洲欧美日韩 | 国产精品久久久久一区 | 99热最新地址| 日韩av偷拍 | 一区二区三区在线视频观看58 | 亚洲国内精品视频 | 狠狠狠狠狠狠狠狠 | 国产精品国内免费一区二区三区 | 天天色天天 | 国产精品精品国产色婷婷 | 又黄又爽又色无遮挡免费 | 中文字幕一区二区三区在线观看 | 激情综合色播五月 | 国内精品久久久久影院优 | av免费线看| 日韩在线观看电影 | 国产精品女人久久久久久 | 久久夜色精品亚洲噜噜国4 午夜视频在线观看欧美 | 中文亚洲欧美日韩 | 中文字幕日韩av | 亚洲日日夜夜 | 中文av在线免费观看 | 亚洲最新视频在线播放 | 伊人天天狠天天添日日拍 | 四虎免费在线观看 | 天天干天天摸天天操 | 国内外激情视频 | 亚洲精品国产精品国自产 | 一区二区中文字幕在线播放 | 免费视频黄 | 国产 精品 资源 | 久精品在线观看 | 久久久久久久久久久久电影 | 在线综合色 | 欧美精品久久久久久久亚洲调教 | 久久综合给合久久狠狠色 | 有码中文字幕在线观看 | 久久久久久国产精品999 | 91干干干 | 亚洲涩涩涩涩涩涩 | 免费看污的网站 | 午夜私人影院久久久久 | 国产精品一区二区免费视频 | www.天天色.com | 美女黄久久 | 视频在线观看日韩 | 国产视频九色蝌蚪 | 久久精品视频99 | 极品久久久久 | 精品资源在线 | av亚洲产国偷v产偷v自拍小说 | 欧美综合在线视频 | 日韩欧美在线一区二区 | 在线日本v二区不卡 | 操操日日 | 日韩精品一区二 | av女优中文字幕在线观看 | 中文乱码视频在线观看 | 精品国产成人 | 日韩欧美精品一区二区三区经典 | 麻花天美星空视频 | 中文av字幕在线观看 | 成人高清av在线 | av电影在线观看完整版一区二区 | 中文字幕免费观看视频 | 丁香婷婷色综合亚洲电影 | 亚洲最大av网 | 亚洲综合在 | 丝袜美腿一区 | 少妇高潮流白浆在线观看 | 日韩在线视频网站 | 91高清视频在线 | 国产一区免费看 | 亚洲成av人片在线观看无 | 国产高清视频在线播放 | 色综合咪咪久久网 | 久久久99精品免费观看 | 成人不用播放器 | 91亚洲精品在线观看 | 美女在线观看av | 久久a级片 | 亚洲在线视频网站 | 亚洲国产欧洲综合997久久, | 99精品色 | 亚洲爱av| 波多野结衣视频一区二区三区 | 久久成人麻豆午夜电影 | 国产精品一区二 | 狠狠成人 | 成人在线观看免费视频 | 国产亚洲精品久久久久久 | 久章草在线 | 96国产精品视频 | 欧美二区视频 | 欧美视频在线观看免费网址 | 成人一区二区在线观看 | 美女视频久久黄 | 91精品免费在线 | 成人黄大片视频在线观看 | 免费黄色av电影 | 国产三级在线播放 | 91免费观看视频网站 | 丁香六月在线观看 | 天躁狠狠躁 | 欧美日韩久 | 久久久久久激情 | 国产成人福利在线 | 精品国产网址 | 亚洲人成影院在线 | 在线视频日韩欧美 | 日韩综合一区二区三区 | 一级片色播影院 | 91视频免费看网站 | 人人干在线 | 日韩激情一二三区 | 一区二区三区电影大全 | 免费日韩高清 | 999超碰 | 99精品久久久久久久久久综合 | ,午夜性刺激免费看视频 | 免费看的黄色网 | 欧美色婷 | a√天堂中文在线 | 97在线观看视频国产 | 丁香5月婷婷久久 | 成人免费观看大片 | 国产中文字幕网 | 99热国产在线 | 国产又粗又长的视频 | 2020天天干天天操 | 亚洲高清视频在线播放 | 亚洲精品视频在线观看视频 | 国产视频精品免费 | 国产成人在线观看免费 | 成人在线免费看视频 | 99热在线国产 | 国产精选在线观看 | 看片一区二区三区 | 国产精品毛片一区二区 | 97超碰在线视 | 国产精品一区一区三区 | 麻豆精品传媒视频 | 国产精品入口久久 | 亚洲视频久久久 | 中文字幕在线观看完整 | 免费观看v片在线观看 | 一区二区三区四区精品 | 五月天婷婷丁香花 | 国产精品久久久精品 | 日韩 国产| 成年人在线观看视频免费 | 成人网在线免费视频 | 99精品成人 | 欧美激情视频一区二区三区免费 | 亚洲成人中文在线 | 久久爽久久爽久久av东京爽 | 日韩电影中文字幕在线观看 | 激情网在线观看 | 国产精品高潮呻吟久久av无 | 日韩在线中文字幕 | 亚洲激精日韩激精欧美精品 | 欧美男男tv网站 | 国产精品久久久久久久久久ktv | 免费观看成人网 | 久久久黄色免费网站 | www.干| 欧美日韩大片在线观看 | 激情九九 | 麻豆视频国产 | 欧美大码xxxx | 一级性av| 在线欧美日韩 | 欧美精品xx| 国产午夜三级 | 国产精品 9999| 天天干天天操天天做 | 国产色久| 亚洲黄色av| 99视频精品 | 成人欧美日韩国产 | 五月天av在线 | 亚洲精品玖玖玖av在线看 | 久日视频| 福利视频导航网址 | 欧美精品一区在线 | 久久久久久久久久久综合 | 亚洲在线成人精品 | 久草在线中文视频 | 天天综合网久久 | 日韩精品中文字幕在线不卡尤物 | 日韩网站在线看片你懂的 | 午夜精品久久久久久中宇69 | 天天操夜夜操 | 国产精品免费在线视频 | 欧美精品久久久久久久久久白贞 | 国产综合在线视频 | 成人h视频在线播放 | 天天操天天艹 | 国产成人av电影 | 亚洲欧美日韩精品一区二区 | 在线激情网 | 国产精品久久久久久超碰 | 亚洲在线免费视频 | 91色一区二区三区 | 人人澡超碰碰97碰碰碰软件 | 亚洲精品www久久久久久 | 97视频久久久 | 国产在线精品二区 | 国产精品自产拍在线观看 | 国产成人精品一区二区三区在线观看 | 九九热在线观看视频 | 久久免费看毛片 | 日韩精品免费在线播放 | а中文在线天堂 | av一区二区三区在线播放 | 久久爽久久爽久久av东京爽 | 欧美一区二区在线看 | 精品久久免费 | 成人av免费播放 | 人人草在线视频 | 超碰免费观看 | 亚洲码国产日韩欧美高潮在线播放 | 日韩视频一区二区 | 亚洲欧美日韩在线一区二区 | www毛片com| 久久精品看 | 亚洲夜夜综合 | 人人爽人人射 | 国产高清专区 | 成人黄色电影视频 | 国产一区视频在线 | 国产网站在线免费观看 | 人人看人人| 久久久国产成人 | 日本精品视频免费 | 在线看av的网址 | 青春草免费视频 | 操操操日日 | 最近中文字幕在线播放 | 国产中文字幕一区二区三区 | 免费日韩一区二区三区 | 免费看黄网站在线 | 中文字幕精品在线 | 91亚洲永久精品 | 久9在线 | 亚洲高清在线视频 | 国产精品字幕 | 91xav| .国产精品成人自产拍在线观看6 | 手机av在线免费观看 | 国产成人一区在线 | 色综合久久久久久久久五月 | 国产成人一区二区三区电影 | 天天艹| av黄色免费看 | 久久露脸国产精品 | 91在线免费看片 | www.成人久久| 成人免费在线观看入口 | 91高清免费在线观看 | 日韩字幕 | 最近中文字幕高清字幕在线视频 | 亚洲三级在线 | 91视频午夜 | 国产精品不卡 | 亚洲专区 国产精品 | 成人毛片在线观看 | 国产中文伊人 | 国产日韩精品一区二区在线观看播放 | 国产色拍拍拍拍在线精品 | 中文字幕 第二区 | 麻豆精品视频 | 99精品美女 | 日韩精品你懂的 | 综合色站导航 | 色综合中文字幕 | 精品 激情| 欧美精品久久久久久久久久白贞 | 成人精品一区二区三区中文字幕 | 在线观看黄 | 国产精品第54页 | 永久免费的啪啪网站免费观看浪潮 | 国产亚洲婷婷免费 | 波多野结衣电影一区二区三区 | 欧美二区视频 | 97在线资源| 国产精品观看在线亚洲人成网 | 99久久久久免费精品国产 | 国产欧美综合在线观看 | 免费观看特级毛片 | 免费高清在线观看电视网站 | 欧美日韩性视频在线 | 黄色高清视频在线观看 | 99热只有精品在线观看 | 999久久国精品免费观看网站 | 波多野结衣精品在线 | 黄色视屏在线免费观看 | 欧美一级在线观看视频 | 久久精品99国产国产精 | 欧美日韩高清一区二区 | 久久视频热| av在线免费不卡 | 欧亚日韩精品一区二区在线 | 国产一二三四在线视频 | 亚洲欧美在线综合 | 九九激情视频 | 国产成人一区二区啪在线观看 | 精品久久久久久久久久久院品网 | 美女黄频在线观看 | 久久九精品 | 国产又粗又长的视频 | 成人av一区二区三区 | 91免费视频黄 | 天天插狠狠干 | 精品一区电影国产 | 日韩精品视频久久 | 91精品久久久久久久久久入口 | 国产午夜在线观看视频 | 精品婷婷| 看黄色.com | 中文字幕影视 | 免费碰碰 | 中国黄色一级大片 | 亚洲影院天堂 | 亚洲精品视频中文字幕 | 久久成人福利 | 久草| 69视频国产 | 色吊丝在线永久观看最新版本 | 日韩中文久久 | 91天天操 | 奇米影视四色8888 | 91av99 | 中文字幕精品一区 | 成人av片在线观看 | 日韩一区在线播放 | 在线观看mv的中文字幕网站 | 午夜成人免费电影 | 91国内在线 | 天天弄天天干 | 婷婷精品在线视频 | 国产黄色片免费看 | 天天操天天爱天天干 | 在线国产一区二区三区 | 亚洲小视频在线观看 | a视频在线播放 | 国产精品夜夜夜一区二区三区尤 | 亚洲精品永久免费视频 | 午夜资源站| 人人干免费 | 中文字幕在线视频国产 | 午夜精品久久久久久久99水蜜桃 | 亚洲成人av影片 | 久久av福利| 国产大尺度视频 | 国产精品久久久久三级 | 天天综合色天天综合 | 亚洲欧美日韩一级 | 久久99国产精品视频 | 日韩精品免费在线播放 | 五月婷婷视频在线 | 日韩中文字幕在线不卡 | 亚洲三级性片 | 国产综合激情 | 久色免费视频 | 超碰公开97| 日韩免费一级电影 | 亚洲成人av影片 | 免费观看国产精品 | 在线观看亚洲精品 | 日韩精品欧美一区 | 亚洲精品国产成人av在线 | 国产精品去看片 | 亚洲视频 视频在线 | 欧美日韩一区二区在线观看 | 婷婷在线免费视频 | 欧美日韩国产区 | 成人毛片久久 | 国产精品美女久久久久久2018 | 国内精品亚洲 | 999精品 | 日韩欧美在线高清 | 婷五月天激情 | 人成免费网站 | 成人久久| 狠狠色噜噜狠狠狠 | 日韩av看片| 欧美午夜视频在线 | 亚洲精品免费在线观看 | 中文在线字幕免费观 | 久久国产一区二区三区 | 中文字幕韩在线第一页 | 国产传媒一区在线 | 亚洲精品久久激情国产片 | 狠狠干婷婷 | 久久精品99久久 | 日韩三级免费 | 黄色午夜 | 91丨九色丨蝌蚪丰满 | 久久久精品福利视频 | 日韩免费视频线观看 | 久草在线久 | 人人看人人 | 色婷婷丁香 | 在线国产91 | 激情网色 | 激情综合婷婷 | 成人免费在线观看电影 | 婷婷亚洲五月 | 久久99精品国产麻豆宅宅 | 日本精a在线观看 | 久久久久中文 | 99精品视频免费全部在线 | 成 人 黄 色 视频免费播放 | 国产精品午夜在线 | 色偷偷网站视频 | 人人射人人射 | 久久精品视频免费观看 | 狠狠网亚洲精品 | 日本精品久久久久影院 | 久久久精品 | 999精品| 玖玖在线精品 | 麻豆精品视频在线 | 久久精品视频免费播放 | 亚洲黄色片一级 | 久草网在线 | www国产亚洲精品久久网站 | 日韩欧美在线一区二区 | 美女免费视频网站 | 狠狠干天天射 | 久久69精品久久久久久久电影好 | 日韩免费观看一区二区 | 在线欧美小视频 | 一级黄色片毛片 | 黄色aaa毛片 | 日韩免费视频线观看 | 国产精品国产三级国产aⅴ无密码 | 成人精品电影 | 97麻豆视频| 国产资源在线观看 | 欧美日韩一区二区三区免费视频 | 日韩91精品| 国产精品美女久久久久久久久久久 | 久草在线最新免费 | 中文字幕色在线视频 | 久草免费福利在线观看 | 激情久久久| 天天射射天天 | 中文字幕在线观看完整版 | 日韩视频欧美视频 | 久久久久久久电影 | 中文字幕影视 | 丰满少妇高潮在线观看 | 五月婷婷久久综合 | 久久久久成人精品 | 久久久亚洲影院 | 国产综合香蕉五月婷在线 | 97国产大学生情侣白嫩酒店 | 精品久久久久久国产 | 91麻豆精品国产91久久久无需广告 | 免费国产亚洲视频 | 日韩免费视频播放 | 密桃av在线 | 亚洲综合情 | 国产精品久久久久一区二区三区共 | 日本久久久久久科技有限公司 | 精品视频在线视频 | 91av片| 日韩一区精品 | 中文字幕日韩一区二区三区不卡 | 高清精品在线 | 国产精品va在线观看入 | 欧美日韩国产区 | 国产精品久久久久久吹潮天美传媒 | 一区二区精品国产 | 久久精品一二三 | 国产乱码精品一区二区蜜臀 | 国产亚洲亚洲 | 中文永久字幕 | 亚洲人成网站精品片在线观看 | 欧美性精品 | 亚洲伦理电影在线 | 天天躁日日躁狠狠躁av中文 | 91干干干 | 美腿丝袜一区二区三区 | 亚洲免费小视频 | 国产欧美在线一区 | 99高清视频有精品视频 | 日本九九视频 | 精品免费观看视频 | 99久久精品国产观看 | 黄色资源在线观看 | 久久综合九色综合久久久精品综合 | 亚洲成av人影院 | 精品久久福利 | 夜夜婷婷 | av中文字幕在线免费观看 | 中文字幕一区二区三区久久蜜桃 | 四虎国产精品免费观看视频优播 | 国产一级片视频 | 中文在线www | 欧美激情综合五月色丁香 | 国内精品视频在线 | 美女在线观看av | aa一级片| av字幕在线| 一区二区三区四区精品 | 久草网视频在线观看 | 婷婷成人亚洲综合国产xv88 | 欧美视频在线观看免费网址 | 中文字幕一区二区三区四区视频 | 91在线看黄 | 四虎国产精品免费 | 国产成人99久久亚洲综合精品 | 久久久久久久久久久黄色 | 最近日韩中文字幕中文 | av网在线观看 | 深爱激情五月网 | 日韩成人欧美 | 久久你懂的| 欧美一区在线看 | 久久99国产精品久久 | 91在线视频免费播放 | 亚洲免费在线视频 | 日韩网站在线观看 | 精品久久美女 | 91免费看片黄 | 国产高清视频在线观看 | 91人人爽人人爽人人精88v | www.xxxx变态.com | 国产精品大片 | 精品国产乱码久久久久久1区2匹 | 欧美aa级| 久久不见久久见免费影院 | av大全在线 | 久久久国产视频 | 91人人爽久久涩噜噜噜 | 亚洲一级黄色大片 | 国产免费二区 | 日韩中文字幕91 | 黄色h在线观看 | 99久热在线精品视频成人一区 | 国产日韩精品欧美 | 大荫蒂欧美视频另类xxxx | 91色在线观看 | 成人av手机在线 | 日韩有码中文字幕在线 | 天天视频亚洲 | 97碰碰碰 | 五月婷婷激情综合 | 日韩中文字幕第一页 | 国产一级一片免费播放放 | 久久这里只有精品视频首页 | 中文在线资源 | 国产 日韩 欧美 中文 在线播放 | 精品色综合| 美女黄视频免费 | 国产资源在线免费观看 | 日韩久久激情 | 在线观看成人国产 | aa一级片| www.久久久com | 国产色网 | 色黄www小说 | 欧美日本高清视频 | 伊人五月在线 | 日韩高清精品一区二区 | 日韩免费福利 | 久久精品资源 | 久久激情电影 | 99999精品视频 | 国产美女网站在线观看 | 91精品国产一区 | 亚洲日本韩国一区二区 | 视频一区在线播放 | 午夜精品久久久久99热app | av中文字幕在线播放 | 日产乱码一二三区别免费 | www.五月天婷婷 | 黄色毛片网站在线观看 | 国产亚洲精品久久19p | 欧美一级小视频 | 亚洲精品高清视频 | 免费福利在线视频 | 在线日韩一区 | 亚洲精品欧美专区 | 高清色免费| av免费在线看网站 | 天天草视频 | 最近高清中文字幕 | 精品久久久久久久久久久久久久久久 | 国产97视频 | 亚洲国产精品一区二区久久hs | 国产精品欧美久久久久三级 | 日本中文一区二区 | 国产在线a不卡 | 在线观看国产区 | 免费看搞黄视频网站 | 久久精品成人欧美大片古装 | 国产黄色免费观看 | 国产精品黄色影片导航在线观看 | 麻豆视频观看 | 国产精品福利在线观看 | 在线观看一 | 国产精品免费大片视频 | 免费欧美精品 | 最新免费中文字幕 | 免费av片在线 | 国产精品免费观看在线 | 国产一级在线看 | a级黄色片视频 | 97av在线| 午夜精品一区二区三区视频免费看 | 亚洲天堂香蕉 | 丝袜美腿一区 | 亚州日韩中文字幕 | 国产成人免费观看久久久 | 丁香 久久 综合 | 欧美日韩精 | 一级一片免费观看 | 狠狠色丁香九九婷婷综合五月 | 国产小视频福利在线 | 国产三级av在线 | 日韩av在线高清 | 精品亚洲一区二区 | 久草综合视频 | 午夜色影院 | 亚洲美女在线国产 | 中文字幕日韩精品有码视频 | 视频一区在线免费观看 | 干综合网 | 午夜色大片在线观看 | 黄色特级一级片 | 中文字幕在线久一本久 | 精品国产免费看 | 国产精品久久久久国产a级 激情综合中文娱乐网 | av在线激情 | 天天看天天干天天操 | 国产精品久久久久久久久久新婚 | 国产69久久精品成人看 | 免费久久精品视频 | av免费看av| 日韩在线观看a | 国产一级性生活 | 91av欧美 | 日韩毛片精品 | 91麻豆操 | 天天做日日做天天爽视频免费 | 国产在线91精品 | 激情电影在线观看 | 欧美一区成人 | 成人av资源在线 | 亚洲高清网站 | 97夜夜澡人人双人人人喊 | 日韩色高清 | 午夜视频亚洲 | 欧美成人手机版 | 手机看片 | 久久三级毛片 | 成人黄色电影在线观看 | 国产一区二区久久久久 | 日韩欧美在线综合网 | 综合五月| 免费在线观看午夜视频 | 五月天综合色激情 | 在线视频区 | 久久你懂的| 在线三级播放 | 97超视频在线观看 | 日韩视频一二三区 | 91夜夜夜 | 日本特黄一级 | 国产色女 | 国产高清不卡一区二区三区 | 中文字幕视频免费观看 | 91丨九色丨蝌蚪丨老版 | 97视频在线看 | 91传媒在线播放 | 久艹在线免费观看 | www.色婷婷| 一二三区av | 亚洲男男gaygay无套 | 天天草天天爽 | 欧美久久久久久久久久久 | 国产九色视频在线观看 | 国产黄色理论片 | 狠狠色香婷婷久久亚洲精品 | 国内久久精品 | 色综合久久久久 | 日日躁你夜夜躁你av蜜 | 午夜免费福利片 | 中文字幕在线影院 | 人人爽人人舔 | 日韩一区二区三区在线看 | 国产精品va在线观看入 | 免费观看的黄色 | 免费观看www视频 | 国产精品免费视频一区二区 | 97免费在线观看视频 | 婷婷色在线 |