I've been working on improving transitions between various states in my game. Some states are so simple that I don't really need the "compute data," "upload to PPU" setup of more complicated states. So I attempt to wait for a vblank instead of use the nmi routine, and then do some work on the PPU. However, I still get some shearing when I switch graphics back on or off. I would have expected that "being inside vblank" would have been just as safe as execution within the nmi routine. To resolve the issue, I played around with some hard-coded CPU waits to move off the shearing to a frame boundary. This worked well but feels like a hack. What is the right way of doing it?
You shouldn't have problems if you wait for VBlank before disabling or enabling rendering, so that those things don't happen in the middle of a frame.
Still, that isn't what I'd call smooth anyway. For it to be smooth you should use fading.
I do have a fading transition for one of my states. I'm still interested in finding out what is really going on with the "hard cut" transitions, though. *edit* It is so strange. I'm playing around with it right now and I basically do things like:
;wait for vblank
;turn off PPU
;do a bunch of stuff
;wait for vblank
;turn on PPU (bg, sprites, etc).
What I'm seeing in a couple of these cases is shearing when I wait for vblank, then turn off rendering.
Gradualore wrote:
I'm still interested in finding out what is really going on with the "hard cut" transitions, though.
Do you wait for Vblank before disabling rendering
AND before enabling it back? If you do, maybe the shearing is caused by the emulator not being properly synchronized to your monitor's refresh rate, and has nothing to do with your program. Do you see any shearing when scrolling? Have you tried your program on a real NES?
Okay, I just tested on a real NES. The shearing happens in all four emulators I use, and on the NES. With my hack (just some hard coded loops to enforce a wait), *combined* with a vblank, the shearing goes away. It doesn't make any sense, because like I said I always wait for a vblank and then turn rendering on or off. Whenever rendering is OFF, I can do whatever I want...right?
For scrolling I have always had the correct setup of *calculate stuff in loop* *upload stuff in nmi*. The shearing I'm seeing are in very simple states where all I want to do is upload a bunch of static, non animated graphics to the PPU and then display it and have the "hard cut" transition not cause any shearing.
Gradualore wrote:
Whenever rendering is OFF, I can do whatever I want...right?
Sure... Only palette updates are kind of an exception, because when the VRAM address is pointing to bytes in the palette area these colors get rendered (the palette is still successfully updated though). To avoid these color glitches you should only update the palette during VBlank, even when rendering is off.
Anyway, I'm lost. I can't think of anything else based on the description of the problem. Can you make a video or take screenshots? Nintendulator lets you step frame by frame so it should be easy to capture the glitched frames. A ROM would be ideal to debug, of course, but I imagine this is not something you want to make public.
Ah! Thank you. I didn't know about palette writes being an exception. Turns out that's exactly what was wrong. Adding a vblank wait before the palette writes fixed the issue. Now I can get rid of my nasty hack (which I expect was inserting just enough cycles that the following palette writes just happened to land within a vblank =).
Gradualore wrote:
Ah! Thank you. I didn't know about palette writes being an exception. Turns out that's exactly what was wrong.
Heh, I'm glad I could help, even though I didn't expect this to be the problem! =)
tokumaru wrote:
To avoid these color glitches you should only update the palette during VBlank, even when rendering is off.
Can anyone living in PAL land tell me whether these glitches show up in the PAL NES's bigger border, or is the border actually blanked?
tepples wrote:
tokumaru wrote:
To avoid these color glitches you should only update the palette during VBlank, even when rendering is off.
Can anyone living in PAL land tell me whether these glitches show up in the PAL NES's bigger border, or is the border actually blanked?
Not really sure what you mean but if somebody writes a test ROM I can try it out.
I never noticed anything displayed in top and bottom borders, but I can't say anything unless you make a test ROM or something.