PowerPak + Tetramino = sprite flicker

Discuss hardware-related topics, such as development cartridges, CopyNES, PowerPak, EPROMs, or whatever.

Moderator: Moderators

Drag
Posts: 1615
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Post by Drag »

So there is absolutely, positively no way to disable sprite rendering on a scanline that has sprites on it? I'm just looking at Bio Force Ape, and noticing that it disables screen rendering early. Does this exhibit the sprite glitch on real hardware?
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

At what (X, Y) does it disable rendering?
Drag
Posts: 1615
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Post by Drag »

X position, I don't know. I was scrolling the screen with a half cut-off sprite where the rendering was disabled, and the sprite seems to be able to display itself on all parts of the scanline, so it might be disabled in hblank.

Y position, I'm not good at counting blank scanlines, but it's definitely 16 or more scanlines before the natural end of the frame. Looks like maybe 24.
User avatar
qbradq
Posts: 972
Joined: Wed Oct 15, 2008 11:50 am

Post by qbradq »

You can set up a breakpoint for the PPU control registers in Nintendulator to see when it disables the rendering. Nintendulator has this nice PPU scanline and pixel counter when single-stepping.
Drag
Posts: 1615
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Post by Drag »

qbradq wrote:You can set up a breakpoint for the PPU control registers in Nintendulator to see when it disables the rendering. Nintendulator has this nice PPU scanline and pixel counter when single-stepping.
Good idea!

If I'm reading this correctly:

SLNum: 209
CPU Ticks: ranges from 306-317 / 102-105

So scanline 209, but I dunno what pixel that translates to. It's outside of the 64-255 range though.

(The breakpoint I set was on $E2BF, and I used fceux to find that address by looking for writes to $2001)
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

When things are in a 3:1 ratio like 306/102, it probably means the first is PPU cycles (i.e. dots) and the second is CPU cycles.
Drag
Posts: 1615
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Post by Drag »

tepples wrote:When things are in a 3:1 ratio like 306/102, it probably means the first is PPU cycles (i.e. dots) and the second is CPU cycles.
I'm aware of that, but I don't know which of the theoretical 341 pixels are the 256 that show the game screen. :P

So, after reading Brad Taylor's doc (which REALLY could use some visuals... this might be good for wikification), it seems that the screen rendering is turned off offscreen, during the time where the tile data for the next scanline's sprites is fetched. I'm assuming this is considered hblank, but I'm not sure.

Again, is this game susceptible to the sprite oam glitch by doing this?
Bananmos
Posts: 552
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: PowerPak + Tetramino = sprite flicker

Post by Bananmos »

Did anyone ever get around to testing this quirk for the situation where rendering is disabled for N number of scanlines, and then re-enabled, instead of just happening at the end of the frame?

I'm trying to have a black bar at the top instead of the bottom, and since I don't want the alternative dot crawl pattern of Battletoads, I have rendering enabled for 1 line just to prevent that. I wait for the previously set sprite#0 hit flag to clear to find end of vblank, delay N lines (normally one but about 20 in my current debug setting just to see what's going on) and then disable rendering in the "safe" area of 64-250.

But it doesn't seem to help, even when no sprites are intersecting. Or more specifically, it works fine for most reset states, but I can sometimes get it into a reset state where sprites get corrupted. And that seems to include sprite#0, which causes the "wait for end of vblank" sequence to fail miserably since sprite#0 doesn't get hit.

Based on the previous theories, is it even possible to do this? If the sprite evalution state machine will have been interrupted in a state of acessing secondary OAM, I guess secondary OAM should have the state from where it was turned off while scanning of primary OAM would depend on pixel location where screen was re-enabled again?

I'm also quite surprised why I never encountered this bug when making Years Behind, where I did the following seemingly more complicated sequences:
* Waiting for sprite#0 hit flag to get cleared to find end of vblank
* Enabling rendering
* Waiting for sprite#0 hit flag to get set
* Turning off rendering to re-write the palette for the status bar
* Turning on rendering
* Turning off rendering to restore the palette
* Turning on Rendering
* Finally, turning off rendering prematurely before the frame ends

...all without having any troubles of this kind as far as I can remember. Then again, did anyone ever verify that the PAL NES has the same problem? (I'm using an NTSC NES now while Years Behind was developed exclusively on PAL)
User avatar
Bregalad
Posts: 8056
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: PowerPak + Tetramino = sprite flicker

Post by Bregalad »

My bet is that this problem does not ever happens on PAL NES, but this would have to be confirmed. At least the DPCM-interferring-with-joypad-reads glitch does never happen on PAL NES.

You should also rememebr that the NTSC NES has 4 possible states possible at reset/power on while the PAL NES only have 1.
Last edited by Bregalad on Sun Jan 13, 2013 2:02 pm, edited 2 times in total.
Bananmos
Posts: 552
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: PowerPak + Tetramino = sprite flicker

Post by Bananmos »

You should also rememebr that the NTSC NES has 4 possible states possible at reset/power on while the PAL NES only have 1.
You've lost me there... didn't Blargg come to the opposite conclusion in this post, which explained how there are 8 different power-up states on PAL? And the readme.txt in Blargg's synchronization package also talk of how the exact position of the writes "will change randomly each time you press reset".

This sure isn't a totally scientific test... but I've now played around with my game on my PAL console and no matter where I disable/enable rendering and no matter where my metasprites go, I get no corrupted sprites. So I'm prepared to accept your hypothesis of this hardware bug being fixed in the PAL NES as fact. That makes one more aspect where the PAL NES is superior to the NTSC one.

I've also realized that this OAM corruption bug totally kills my plan to have a really cool water effect in my game by disabling the screen/switching on the monochrome bit and updating almost the entire palette to get a noisy white scanline followed by turning on rendering/switching off the monochrome bit and starting a wavy effect loop. Because it wouldn't be worth much if all water would need to be placed at a point where game characters can't pass through it :(

Or alternatively, I guess I could go with the previously made statement that sprite flickering "characterizes NES games", and just let NTSC users suffer a flicker-fest that PAL users are spared of whenever there's water on a screen.

Oh PAL-centric innonence of my nesdev youth, how I want thee back... never realized back then that I was spoiled with more simplicities than just long vblank times!
Bananmos
Posts: 552
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: PowerPak + Tetramino = sprite flicker

Post by Bananmos »

Hmm, I still wonder whether disabling/enabling rendering only during dot 320-340 could magically avoid the bug. With Blargg's synchronization libraries, it seems like it shouldn't be too difficult to make the 1-(CPU) cycle store fall within that window...
User avatar
Bregalad
Posts: 8056
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: PowerPak + Tetramino = sprite flicker

Post by Bregalad »

You've lost me there... didn't Blargg come to the opposite conclusion in this post, which explained how there are 8 different power-up states on PAL? And the readme.txt in Blargg's synchronization package also talk of how the exact position of the writes "will change randomly each time you press reset".
Oh I almost forgot about that. Blargg is probably right because he's way better than me at this kind of stuff. So yeah there is multiple alignments and I even proved it myself and I don't even remember it. Yeah. Just discard my post above.
I never really understood where those 8 alignments comes from.

PAL NES is technically superior, but unfortunately 99% of the game library was made for the NTSC NES which made their PAL version suck. Even European-developped games, such as Battletoads, runs better on NTSC because the music wasn't adapter to PAL properly.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: PowerPak + Tetramino = sprite flicker

Post by tokumaru »

Bananmos wrote:I'm trying to have a black bar at the top instead of the bottom, and since I don't want the alternative dot crawl pattern of Battletoads, I have rendering enabled for 1 line just to prevent that.
I had the exact same problem. I could never fix the sprite glitching, so now I keep only the background disabled, and to mask sprites I put 9 high priority transparent sprites at the very top of the screen. This completely hides sprites for the first 17 scanlines, and doesn't mess with the dot crawl pattern.

Yes, having to waste 9 sprites is far from optimal, but it's not so bad when you use 8x16 sprites (you can still have more "sprite pixels" onscreen than you can with all 64 8x8 sprites), and is also better than what Felix the Cat and Alfred Chicken do, which wastes nearly a whole column of sprites and effectively reduces the sprites-per-scanline limit to 7.
I wait for the previously set sprite#0 hit flag to clear to find end of vblank
With 9 sprites at the very top of the screen I can use the sprite overflow flag to detect the end of VBlank instead, since sprite 0 hits are harder to guarantee when you scroll both horizontally and vertically.

I'm sorry for not being able to help with the actual problem, but I wanted to share my experience with it. Since I couldn't solve the problem myself I just went with another solution that used more well documented behavior.
Bananmos
Posts: 552
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: PowerPak + Tetramino = sprite flicker

Post by Bananmos »

Thanks for the tip Tokumaru, but the main reason for my top black bar is not to hide sprites but to get some extra vblank time to do CHR animation. I guess the difficulty of this seriously makes me consider CHR-ROM instead though. But even with that my idea for the water effect still can't be done without turning screen off/on...

I realized my game's timing is a bit too unreliable to use Blarggs sync code at the moment, since some code takes more than a frame, which also means I can't always do DMA. Probably better to play around with Blarrg's example code instead, as this has already turned a seemingly simple task of adding more sprite animations to my game into a task of rewriting its code into a testbench...

Trying to move the point of disabling/enabling screen to always be around dot 330 did however show promises even without Blargg synchronization: Glitching is now totally independent of whether my metasprite intersects the black bar or not, and I get the following different glitch behaviors instead:

1: Sprites 2 and 3 have flickering chr patterns
2: Sprites 2 and 3 have flickering chr patterns, but less noticable than in case A
3: No sprite flickering, but palette color index $01 and $0E get changed in some frames
4: No sprite flickering, but palette color index $02 gets changed in some frames
5: No sprite flickering, but palette color index $0E gets changed in some frames

The glitch patterns I get seem to be a combination of reset state, and timing differences somehow trigerred by the "software reset" feature in my very simple in-game level editor in pause mode: Pressing SELECT turns screen off, copies a saved map in ROM to the normal RAM location and updates the PPU memory with it.

So at least I'm getting somewhere, as case 1 and 2 would actually be acceptable to have in a game - you would just have to make sure not to use those sprite indices. And with Blargg Synchronization it should probably be possible to squeeze the write into the "perfect" spot. I already have code to avoid using the first sprite index for any metasprites so changing that to start at index 4 is no biggie, even if it'd waste 4 sprites out of 64.

The other cases really confuse me though, as I don't understand how the palette entries could get corrupted unless written to? Seems to be yet another undocumented "feature" of the NES PPU... I have seen weird stuff like this happen if you write to $2007 while rendering is enabled, but I make sure to both lda $2002 to clear the latch, write #$08 to $2000 and #$00 to $2001 and double-write a constant chr pattern address to $2006 before doing any of the chr writes to $2007 in the black-bar area.

EDIT: I found the cause of the palette glitches. I had forgotten to set the scroll values before waiting for end of vblank, and since I write the palette in every vblank that happened to be what VADDR was pointing at in the first scanlines. As long as rendering is enabled, the PPU seems to read just the lower bits of the address and thus rendering a seemingly correct picture (albeit with shifted scroll values). But for some reason I do not yet understand it will corrupt the palette entries when you disable rendering and VADDR is pointing at the palette region.

After fixing that, only two reset states seem to exist: The one without any fliclkering, and the one where it only affects makes sprites 2 and 3 flicker. It might be possible to always get the first case deterministically by Blargg Synchronization, but it's probably not worth doing that for this alone. I'm happy to never use the first four sprites if it can let me freely do PPU updates anywhere in the screen. And it should allow me to do the planned water effect as well!

So from what I can tell so far it seems that the easier guidelines for avoiding this hardware quirk are: Make sure disabling/enabling the screen happens around dot 330, and avoid using sprites 2 and 3.
Last edited by Bananmos on Sun Jan 13, 2013 6:18 pm, edited 1 time in total.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: PowerPak + Tetramino = sprite flicker

Post by tokumaru »

Bananmos wrote:Thanks for the tip Tokumaru, but the main reason for my top black bar is not to hide sprites but to get some extra vblank time to do CHR animation. I guess the difficulty of this seriously makes me consider CHR-ROM instead though.
Yeah, my problem was EXACTLY the same as yours. My blank bar was meant for hiding scrolling glitches AND for extra VRAM updates, but it was so much trouble that I decided to cut back on the CHR animations (not as many tiles animate each frame). The possibility of using the MMC3 was indeed really tempting.
But even with that my idea for the water effect still can't be done without turning screen off/on...
Yeah, that's a tough one.
The other cases really confuse me though, as I don't understand how the palette entries could get corrupted unless written to?
I'm very surprised by this too! Never heard of this!
Post Reply