日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何写一个NES模拟器(一)

發布時間:2023/12/20 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何写一个NES模拟器(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.認識NES文件格式

偏移0-3? 字符串“NES^Z”用來識別.NES 文件
偏移4 16kB ROM 的數目
偏移5? 8kB VROM 的數目

(摘自《任天堂產品系統文件》)

NES文件的前16個字節是文件頭,前4個字節是NES^Z,文件標識。第5個字節是16K ROM的數量,第6個字節是8K VROM的數目。

ROM文件格式具體是這樣:16字節(文件頭)+16K x N(程序主體) + 8K x N(VROM),這就是一個完整的NES格式的ROM文件。其中8K VROM是點陣格式的字模文件,就是游戲中畫面的最小元素,如果你了解點陣格式的話,你知道A的點陣大約是

00010000 一個字節
00202000 一個字節
03000300 一個字節
20000020 一個字節
11111110 一個字節
20000020 一個字節
30000030?一個字節

如果只是黑白點陣格式,圖中的23,只能是1,因為2進制只有0和1,且每行一個字節,那么8個字節可以表示一個字母。任天堂使用2個點陣來表示一個點陣,其中前一個點陣(8字節)表示顏色的bit0位,后一個點陣(8字節)表示顏色的bit1位。

那么上圖就是把2個點陣疊加在一起。

? ? ?? 知道了這些內容后,我們寫一個讀取VROM的程序。

先讀取rom文件到buf中,這里我把文件指針直接移動到了字模處

liCurrentPosition.LowPart = neshreader->romnum * 16 * 1024;

SetFilePointerEx(hFile, liCurrentPosition,&liCurrentPosition,FILE_BEGIN);

ReadFile(hFile,(LPVOID)buf,8 * 1024,&readsize,NULL);

?

然后就是畫單個字模圖形函數。

根據上圖來繪制單個字模。

void Draw_Tile(int x,int y,unsigned char * p,unsigned char index,unsigned char high2bit,char flip,int type){int i,j,c = 0,d;unsigned char a,b,a1,b1;//繪制圖案for (j =0;j < 8;j++){//存儲8*8圖案一共需要16個字節,a1 = *p; //指向上圖的地址0b1 = *(p+8); //指向上圖的地址8 for (i = 0;i < 8; i++){ //從左至由繪制點 a = (a1 >> (7 - i) << 1 ) & 2; //a值=a1右移后再左移一位b = (b1 >> (7 - i)) & 1;//顏色索引,a和b組成低2位 (a or b)d = (unsigned char)(a | b); //如果低2位是1,2,3分別繪制不同的顏色 if(d == 1 ){draw_window_point(x * 8 + i,y * 8 + j,RGB(0,0,255),(UINT *)color,256);}else if(d == 2){draw_window_point(x * 8 + i,y * 8 + j,RGB(0,255,255),(UINT *)color,256);}else if(d == 3){draw_window_point(x * 8 + i,y * 8 + j,RGB(255,255,255),(UINT *)color,256);}}p++;}} --------------------

繪制所有圖形

void drawchr(void * buf){int i,j,x,y,c = 0,d;unsigned char a,b,a1,b1;//分配內存地址pScreenMem =(unsigned char *) malloc(256*128*4); //創建dib位圖CreateScreen(m_hWnd); //得到圖案表首地址 unsigned char * p = (unsigned char * )buf; //繪制16行 for (y = 0; y < 16;y++){ //每行繪制32個塊for(x = 0; x < 32; x++){Draw_Tile(x,y,p,0,0,0,0);p += 16;}}//得到窗口句柄HDC hDc = ::GetDC(m_hWnd);//開始顯示圖形LoadFrame(color,hDc);} ---------------------

附圖一張,接下來我們就可以繪制整個命名表了,接著就是精靈的繪制,我們還要模擬CPU,并在vblank中不斷的繪制圖形,形成游戲畫面了。Demo程序地址如下

鏈接:https://pan.baidu.com/s/1WdZx3T7HifTW75bcRYqhNQ?
提取碼:q8oq?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?


?

總結

以上是生活随笔為你收集整理的如何写一个NES模拟器(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。