Start the NES simulator and start our classic super Mario 1 again.
Choose tool> viewer> scroll viewer. The following window will appear this time.
650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131228/1614443Y9-0.png "title =" Capture. PNG "alt =" 141725196.png"/>
The response function is still
WNDCMD CMainFrame: OnViewCommand (wnd1_param)
This content is not mentioned in the previous section.
This is the second branch.
case ID_VIEW_NAMETABLE: if( !m_NameTableView.m_hWnd ) { m_NameTableView.Create( HWND_DESKTOP ); } ::SetWindowPos( m_NameTableView.m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); break;
This section describes the classes to which m_NameTableView belongs.
CNameTableView
File Source Files/NameTableView. cpp Header Files/NameTableView. h
We can see that both CNameTableView and CPatternView are similar in terms of both the composition of class members and member functions. Therefore, let's just pick a different one. If you have any questions, just take a look at the section.
Bitmap header:
m_BitmapHdr.bih.biSize = sizeof(BITMAPINFOHEADER);m_BitmapHdr.bih.biWidth = 512;m_BitmapHdr.bih.biHeight = -480;m_BitmapHdr.bih.biPlanes = 1;m_BitmapHdr.bih.biBitCount = 8;m_BitmapHdr.bih.biCompression = BI_RGB;m_BitmapHdr.bih.biClrUsed = 16;
The bitmap displayed in the window is 512 pixels in width and 480 pixels in height.
What is the special meaning of 512*480? Yes!
NES contains a combination of four named tables and attribute tables. One combination can display a picture on the screen.
Try dividing 512*480 by 4 to get 256*240. The resolution of the NES game screen is exactly 256*24032*30 tile, and the tile is 8*8 pixels ).
In this way, we can infer that four game backgrounds are displayed on the scroll viewer.
Why is there a combination of four named tables and attribute tables in NES? I don't need to study it in depth, but I still don't understand it ).
Next we will explain in depth the OnTimer function.
for( INT i = 0; i < 16; i++ ) { m_BitmapHdr.rgb[i] = m_Palette[BGPAL[i]]; }
Read the 16 colors of the background.
for( INT n = 0; n < 4; n++ ) { LPBYTE lpVRAM = PPU_MEM_BANK[8+n]; LPBYTE lpScnv = &m_lpPattern[(n>>1)*512*240+(n&1)*256]; for( INT y = 0; y < 30; y++ ) { for( INT x = 0; x < 32; x++ ) { INT tile = lpVRAM[x+y*32]*16+((PPUREG[0]&PPU_BGTBL_BIT)<<8); BYTE attr = ((lpVRAM[0x03C0+(x/4)+(y>>2)*8]>>((x&2)+(y&2)*2))&3)<<2; LPBYTE lpScn = &lpScnv[x*8+y*8*512]; LPBYTE lpPtn = &PPU_MEM_BANK[tile>>10][tile&0x03FF]; for( INT p = 0; p < 8; p++ ) { BYTE chr_l = lpPtn[p]; BYTE chr_h = lpPtn[p+8]; lpScn[0] = ((chr_h>>6)&2)|((chr_l>>7)&1)|attr; lpScn[4] = ((chr_h>>2)&2)|((chr_l>>3)&1)|attr; lpScn[1] = ((chr_h>>5)&2)|((chr_l>>6)&1)|attr; lpScn[5] = ((chr_h>>1)&2)|((chr_l>>2)&1)|attr; lpScn[2] = ((chr_h>>4)&2)|((chr_l>>5)&1)|attr; lpScn[6] = ((chr_h>>0)&2)|((chr_l>>1)&1)|attr; lpScn[3] = ((chr_h>>3)&2)|((chr_l>>4)&1)|attr; lpScn[7] = ((chr_h<<1)&2)|((chr_l>>0)&1)|attr; // Next line lpScn+=512; } } } }
Line 5 draws four game backgrounds from left to right.
The last four byte pointers of PPU_MEM_BANK are directed to four named tables and attribute tables. Therefore, lpVRAM points to the n-th naming table and the attribute table.
The first pixel address of the nth background in row 3rd.
Lines 5-6, 30, and 32 are no stranger to everyone. They are vertical and horizontal tile numbers.
Line 7-8 If PPU_MEM_BANK is regarded as a continuous space of 12*1 K in the real machine, that is, the address space of the FC household machine is continuous ), the result of this substatement is the tile address. However, the address space is divided into 12 parts, so the obtained value is 10 ~ The 13-bit is the subscript of the PPU_MEM_BANK array, 0 ~ 9-bit is the offset in 1 K space.
The meaning of each part.
LpVRAM [x + y * 32] is the tile number. A tile occupies 16 bytes in the pattern table. Therefore, lpVRAM [x + y * 32] * 16 is the offset address of the tile in the pattern table.
PPUREG [0] is an I/O port with a length of 16 bits. Each BITs has a specific meaning. What is the meaning of each digit? You only need to know the address of the currently used pattern table with 4th bits. This digit is 0 and 0 x is used. This digit is 1 and 0 x is used. (PPUREG [0] & PPU_BGTBL_BIT) <8 is used to obtain 0x0000 or 0x1000.
The rows 9-10 obtain the high two-digit data corresponding to each tile. Attr stores the obtained data at the second and second bits. The reason why the other bits are 0 is to facilitate subsequent computation ).
The Starting Screen Pointer of the tile of Row 3.
The second row reads the lowest two bits of all the pixels of one tile from the pattern table, with a total of 16 bytes.
The first row begins to draw tile, and each cycle draws one line.
Line 14-15 previously mentioned that two bytes, 1st bytes are The 0th bits of the pixel, and 2nd bytes are the 1st bits of the pixel.
Line 17-24 calculates each pixel. With the previous Foundation, these formulas should be easy to understand.
The starting position of row 26th pointing to the next row of tile.
This article from the "Three Take Tiger" blog, please be sure to keep this source http://darhx.blog.51cto.com/7920146/1303236