如何写一个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?一個字節
如果只是黑白點陣格式,圖中的2和3,只能是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模拟器(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 免费杀软佼佼者——小红伞Avira及去广
- 下一篇: 顺丰java_顺丰API调用java版