Quote:
The PPU is the master timebase for video; the TV locks on to its timing. This way the PPU can just output the signal and not need anything back from the TV.
The game writes to PPU memory, and then the PPU reads this when it's generating the video frame signal output. Even if the game doesn't touch the PPU for a while, the PPU is still regularly generating video frames for the TV on its own.
Games can't generally write to PPU memory while the PPU is reading, which is does for most of the frame. Since the TV needs time to move its electron gun back to the top of the screen, there is a blanking period (VBL). This is also a time the PPU isn't reading from any memory, so the game writes during this period. The NMI occurs when this blanking begins, so most games update sprites and background in NMI.
This is a good explanation, so I think that i get it now.
Quote:
You will see that the object's coordinates have changed if you look at specific bytes in RAM, but you will not be able to see it on the screen because the picture will only be rendered after the states of all the objects have been updated.
Right, I understand that now.
Quote:
As for music, sound is usually updated after "writePictureToTV", because execution time varies less in the VBlank handler than in the main loop, and you want the time between calls to "updateMusic" to be as constant as possible, otherwise there will be noticeable sound distortion.
Ah, that makes sense, to reduce distortion.
Quote:
Yeah, kinda. There are some things missing, such as "updateCamera", and enemies are hardly hardcoded like that, iterating over an array of enemies would make more sense. Also, it usually isn't while(true) (infinite loop), because the program must be able to run other loops. Games often have different loops for different parts (title screens, menus, cutscenes, main engine, etc.), because different tasks must be performed for each of them. A "game over" for example should break that main game loop.
Okay, so it'd be more like this:
Code:
main() {
if(state == isTitleScreen) {
...
} else if(state == isInStage) {
updateMario();
updateEnemies();
updateCamera();
waitForVBlank();
resetVBlankCounter();
copyValuesToPPU();
updateMusic();
} else if(state == isEndScreen) [
...
} else if(state == ...) {
...
}
}
Quote:
Kinda. The PPU renders images to the screen (60 or 50 of them per second) automatically, but you have to manually set some parameters to tell the PPU what to draw. During VBlank (meaning that the point when you called "writePictureToTV" is correct) is the only time the CPU can freely set these PPU parameters: things like the positions of the sprites and the tiles and palettes they use, the tiles that form the background, and so on. The PPU will render a picture whether you change these parameters or not (if you don't, it will just render the same picture again).
Okay, so the name that I gave to writePictureToTV() should actually be something like copyValuesToPPU(), because the PPU is not acually writing then, because the electron gun is scrolling back up. The PPU is actually writing to the screen when the CPU is computing updateMario(), updateEnemies(), updateCamera(), right?