To sum up:
Should I switch to a per pixel or per scanline technique instead to avoid problems down the road?
Thanks!
EDIT: Removed last comment because it sounded snotty. SORRY!
Moderator: Moderators
I am going to switch over to a per pixel method this weekend. I'd rather not take shortcuts and regret it in the end. Plus, the code I have in place for per-frame rendering shouldn't be too difficult to change into per pixel. Let's hope it's as easy as I'm thinking it will be.MottZilla wrote:It would be recommended to atleast do per scanline. The state of things at the end of rendering which is likely when you draw the frame now is not enough to fully emulate the PPU. Graphics banks can change, scrolling and nametable registers change, etc.
The easiest for coding point of view is to emulate per pixel. Meaning run one CPU opcode. Then run 3 PPU cycles for every 1 CPU cycle you executed. This will keep the PPU and CPU roughly in sync. To be even more accurate you would need to actually break down CPU opcodes into their cycles and execute 1 CPU cycle and then 3 PPU cycles.
But as far as running most games, you can do a per scanline rendering. You can do hacky things. It can work if you want it to.
And alternative to the per pixel and per scanline is to do the "catch up" method. You execute CPU cycles until an event happens that needs the PPU to catch up, at which point you execute your PPU emulation to run PPU cycles until it catches up to the CPU. In the end it's up to you to decide what works best for you.
Catch-up is a threading method, thus it's orthogonal to PPU emulation granularity. You can do per-frame, scanline, pixel with catch-up, green threads, etc.MottZilla wrote:[An] alternative to the per pixel and per scanline is to do the "catch up" method. You execute CPU cycles until an event happens that needs the PPU to catch up, at which point you execute your PPU emulation to run PPU cycles until it catches up to the CPU. In the end it's up to you to decide what works best for you.
That's called "timestamping", and in theory, it can handle even mid-scanline changes. You just have to be extra careful with code that checks for a sprite 0 hit or mappers that assert an IRQ on PPU memory reads, because PPU register writes above them can affect the result.Petruza wrote:if your emu does per-frame rendering BUT records in which scanline(s) the scroll registers were modified, then, you can still make up your frame only once at the beggining of vblank and still fully support the partial screen scrolling.