mvdnes / rboy

A Gameboy Emulator in Rust
MIT License
594 stars 38 forks source link

Question about renderscan implementation #8

Closed ablakey closed 4 years ago

ablakey commented 4 years ago

I've been using your emulator as a reference while learning how to write an emulator. Thanks for sharing it!

I had a question about how you implement the GPU's cycle.

In do_cycle https://github.com/mvdnes/rboy/blob/master/src/gpu.rs#L110 it seems like you're emulating the advancement of the GPU's timing fairly accurately. I was expecting to see a mechanism for incrementally drawing graphics into a buffer (later to be output to the host's screen), pixel by pixel. But instead, it seems like you just draw it all at once at the beginning of switching to mode 1, calling self.renderscan() once.

Could you confirm that is indeed what you're doing, and if you had any feedback on it? Was that for performance reasons? Is it because it doesn't affect some, most, or all games? My sense is that some games might want to do clever things depending on what column you're currently drawing to, but that's not possible if you draw it all in one shot and then emulate no-op cycles past that.

Thank you!

mvdnes commented 4 years ago

The screen is drawn line-by-line. The self.renderscan() function is called at the h-blank period of each line, and it modifies pixels of the current line only (as can be seen by the usage of self.line).

This is accurate enough for all games I have tried. It can be justified by the fact that not all video memory is accessible (in the actual hardware) during the drawing of pixels. Games are supposed to only modify video contents during h-blank and v-blank periods.

ablakey commented 4 years ago

Thank you. Makes perfect sense.