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; //指向上图的地址0
b1 = *(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