Data to pull for drawing pixels

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Data to pull for drawing pixels
by on (#147242)
I'm writing an NES emulator and I'm trying to figure out where to pull the data from drawing pixels. Is there something out there as an example that shows what needs to be accessed on the PPU memory for pulling the color for a particular pixel?

For example, to draw pixel 0:

I look at 0x0000 and 0x0008 to get the least significant bits of the color for pixel 0.
Re: Data to pull for drawing pixels
by on (#147249)
DarylTechNES wrote:
I'm writing an NES emulator

Have you tried joining an existing open-source emulator project?

I'm of the opinion that everyone who wants to make an NES emulator should program at least "hello world" as an NES homebrew ROM before making an NES emulator. That way, you can at least make test ROMs that exercise the subset of functionality that you have implemented.
Re: Data to pull for drawing pixels
by on (#147254)
DarylTechNES wrote:
Is there something out there as an example that shows what needs to be accessed on the PPU memory for pulling the color for a particular pixel?

The wiki has tons of information about rendering:

http://wiki.nesdev.com/w/index.php/PPU_rendering
http://wiki.nesdev.com/w/index.php/PPU_nametables
http://wiki.nesdev.com/w/index.php/PPU_attribute_tables
http://wiki.nesdev.com/w/index.php/PPU_scrolling
http://wiki.nesdev.com/w/index.php/Mirroring
http://wiki.nesdev.com/w/index.php/PPU_ ... evaluation
http://wiki.nesdev.com/w/index.php/PPU_sprite_priority

Quote:
For example, to draw pixel 0:

I look at 0x0000 and 0x0008 to get the least significant bits of the color for pixel 0.

You'll not find answers as simple as this. The information for each pixel will not come from fixed memory positions, since scrolling allows the background to be moved around. Each pixel is a combination of pattern table bits (located through the scrolling position and name table data) and palette bits (loaded from the attribute table), overlaid with sprite pixels (calculated from data in the OAM and pattern tables). I couldn't possibly summarize the whole process in a single forum post, so please take a look at what the wiki has to say and ask here about the parts that aren't clear.
Re: Data to pull for drawing pixels
by on (#147703)
DarylTechNES wrote:
For example, to draw pixel 0:
I look at 0x0000 and 0x0008 to get the least significant bits of the color for pixel 0.


Yes, that's for pixel 0 of tile 0 of a given pattern table.
Then you have to look up the nametable entries or sprites that use that tile, figure out which palette they use from the attribute table in case of background tiles, then figure out the position of the sprite or the tile based on scroll registers, and then you get where in the screen the pixel shows up.
As it's been said before, you'd better read the wikis and other documentation from nesdev.com to form a basic picture of how the NES architecture is laid out.
Re: Data to pull for drawing pixels
by on (#147708)
Oh, I forgot to suggest something I always do when people are not familiar with the PPU, no matter if they are programming emulators or games: load several different games in FCEUX (and/or other emulators with similar debugging tools) and abuse the hell out of the PPU debugging tools. Look at the palettes, pattern tables, name tables, sprites, etc. as you observe the resulting picture in the main emulator window. That should help you piece everything together.

Once you understand the basic concept (which memory is used for what purpose), you'll have a high-level understanding of how NES graphics work. That should be enough to get some simple games working, but anything that interacts with the PPU while the screen is rendering will fail. To properly emulate those you'll have to understand the actual order in which the NES does things, and try to emulate that as best as you can.
Re: Data to pull for drawing pixels
by on (#147728)
You can also edit PPU memory on the fly in the hex editor and see how it affects things. Might help you more easily draw connections between debugger windows, memory maps, and format documentation.