In this post, tepples wrote:
If you're willing to make your game loop look like this:
I don't like to discuss the same old thing again, but I have to point out that there is an obvious disadvantage to this method: IT WILL MISS VBLANKS. Maybe not for Pong, Tetris or a card game, because those are likely to always finish all their frame calculations before VBlank. However, once the games get more complex and they are not guaranteed to finish the calculations in time, the NMI will fire but the game logic will soon be running again like nothing happened.
I know that it's possible to detect missed VBlanks because you use a counter, but that will not solve all problems. In my game for example I keep rendering disabled for some extra scanlines because I need the extra time for video updates and to hide vertical scrolling glitches. The thing is that even during lag frames I must blank those lines, even if I'm not writing anything to VRAM, otherwise the screen would jump.
And I need to know exactly when the NMI fires for timing reasons, otherwise I wouldn't be able to blank a constant number of lines, which also would cause the screen to jump.
I don't mean to be rude tepples, really, but I have to ask you this: Why do you keep teaching people your method (I know you are proud of it) when you know it's flawed under certain circumstances? It can be slightly friendlier to newbies who are used to polling $2002, but in the long run everybody wants to expand their games, so why teach them something that could break the games once they reach a certain point of complexity?
Hopefully the coders will be able to figure out the problem by themselves when their projects are more complex, but still. Besides being slightly friendlier to newbies, the only advantage I see it that it makes easier to have different VBlank routines for the different parts of the game, but that could easily be solved with a pointer in RAM (that can be changed whenever the programmer wants to) that the NMI jumps to as soon as it fires.
Quote:
It doesn't modify anything but the flags, so it doesn't need to push anything else.
So does the one I posted in this very thread, and it doesn't choke on lag frames.
You seem to be very proud of your solution, but I guess I am of the one I'm using in my game as well. It's actually a hybrid of both methods, that allows you to wait for VBlank or use a custom NMI routine. Look at it, straight from my game:
Code:
;-- INTERRUPT ---------------------------------------------------
;DESCRIPTION:
; This routine is responsible for indicating that VBlank started
; or for calling a custom NMI routine in case one is defined.
;----------------------------------------------------------------
NMI:
;branch if the program was waiting for a regular interrupt
bit WaitingVBlank
bmi +FlipFlag
;branch if there is no custom interrupt routine defined
bit CustomNMI+1
bpl +Return
;transfer control to the the custom routine
jmp (CustomNMI)
+FlipFlag:
;indicate that the interrupt happened
inc WaitingVBlank
+Return:
;return from the interrupt
rti
;DESCRIPTION:
; This routine is responsible for indicating that VBlank started
; or for calling a custom NMI routine in case one is defined.
;----------------------------------------------------------------
NMI:
;branch if the program was waiting for a regular interrupt
bit WaitingVBlank
bmi +FlipFlag
;branch if there is no custom interrupt routine defined
bit CustomNMI+1
bpl +Return
;transfer control to the the custom routine
jmp (CustomNMI)
+FlipFlag:
;indicate that the interrupt happened
inc WaitingVBlank
+Return:
;return from the interrupt
rti
If the program was not waiting for VBlank and there isn't a custom NMI defined (I have one for each section of the game, except the simple ones that can work simply waiting for VBlank) the interrupt simply goes unnoticed, but if you wanted you could use the "counter approach" to detect missed frames.
Sorry if I seem "pissed off" or something in this post, it's not like that, and I don't have anything against you, it's just that whenever I see someone suggesting a solution that they know is not optimal I wonder why the hell they do that... Is it so the person that asked for help later comes back when the flawed solution breaks?