I agree with Blargg. waitvblank() should wait for the start of vblank. If you're already in vblank it should wait until the start of the next vblank, rather than return immediately.
The programmer will wait for VBlank for two reasons:
1) It regulates the logic flow of the game. Since VBlank comes 60 times a second, you do one logic step -- then wait for another frame (vblank), then do another logic step, then wait for a frame, etc. This produces a steady gameflow.
One problem with waitvblank returning immediately is -- what if the game doesn't have very much logic to do? Say for example the game is waiting for user input before continuing. Like at a title screen or something where it's waiting for the Start button to be pressed. And for kicks, say there's a little sprite that animates on the screen.
Code might look something like:
Code:
while(!start_button_pressed)
{
rNES_waitvblank();
animate_and_draw_sprite();
update_joy();
}
This is very practical (and typical in a game). The game would expect animate_and_draw_sprite to be called once per frame, which would result in a steady animation framerate of 60 FPS. If it's called more often than that, the animation would be faster than expected.
So what happens if animate_and_draw_sprite() and update_joy() are shorter than the VBlank period? This would result in rNES_waitvblank returning immediately rather than waiting for the next frame, which would disrupt the 60 FPS animation speed.
2) The other reason to wait for VBlank is to wait for a time where you can draw stuff to the screen. This is the reason blargg was talking about.
Once VBlank happens, you know you have X amount of time to get drawing done.
Code:
rNES_waitvblank();
DoABunchOfDrawing();
DoABunchOfDrawing might assume that it has X time to get all its drawing done -- however if rNES_waitvblank returns immediately (in the middle of or near the end of vblank), you'll be hosed... since you don't have the expected X time to finish drawing -- you have much less. As a result, drawing code might spill outside of vblank, resulting in all kinds of horrible graphic glitches.
Quote:
For those people who actually made or are making some game for NES, do you usually wait for vblank doing nothing, or use that time to do something else?
The whole point of calling a wait() funciton is that you have nothing else to do. You can't do something else while waiting.. or else you're not waiting.
That said -- there are times you might want NMI/Vblank to interrupt code that's running. For example, if an NMI occurs while you're updating game logic, you'll know your code is running long and you have to do some kind of slowdown to keep up.
Therefore games might be interested in VBlank notification outside of waiting for vblank. However they would not use a wait() function for this.