Zelda 2 rendering weirdness

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Zelda 2 rendering weirdness
by on (#100799)
So it looks like the Zelda 2 title screen is comprised of 2 nametables worth of data. When the title screen pops up it rapidly flips between the two images below (the actual title seems to flip between top and bottom of the screen):
ImageImage
I captured these by forcing nametable reads to logical tables 0 and 2.

It also happens in-game in Zelda 2 when you're in the side scrolling areas, Zelda 1 when scrolling from screen to screen (but not the equipment screen), Ninja Gaiden during sidescrolling gameplay, and on and on. Metroid, Mega Man 2, Bionic Commando and plenty of others work perfectly. Considering that only MMC1 games seem to see this and NROM/UNROM/CNROM games all run great without any hiccups at all I feel like I'm probably just missing some critical detail here.
Re: Zelda 2 rendering weirdness
by on (#100800)
You need to emulate Sprite Hit Zero flag in the $2002 register. Also you need to emulate atleast at a scanline level of accuracy because these games alter the rendering address at a specific time after the sprite zero hit flag is set. All 3 games you mentioned use Sprite Hit Zero. You may have the sprite hit implemented correctly but not render the screen in a way that supports mid frame scrolling changes.
Re: Zelda 2 rendering weirdness
by on (#100801)
Perhaps you have a problem with sprite 0 hit? There is a scroll split at the water line.

If your sprite 0 hit isn't working properly, maybe it's getting triggered at the next vblank somehow, leading you to alternate frames instead of splitting in the middle.
Re: Zelda 2 rendering weirdness
by on (#100802)
Well, Zelda II's title screen changes the scroll mid frame (creating a "split") in order to scroll text behind the scenery. How are you handling mid screen $2005/$2006 writes?
Re: Zelda 2 rendering weirdness
by on (#100803)
rainwarrior wrote:
Perhaps you have a problem with sprite 0 hit? There is a scroll split at the water line.

If your sprite 0 hit isn't working properly, maybe it's getting triggered at the next vblank somehow, leading you to alternate frames instead of splitting in the middle.

I do know that it's 1 scanline late, I've just been lazy about fixing it. I'll try that.
tokumaru wrote:
Well, Zelda II's title screen changes the scroll mid frame (creating a "split") in order to scroll text behind the scenery. How are you handling mid screen $2005/$2006 writes?

Nothing special happening there. I have the global latch for first/second writes, I'm not restricting it if rendering is disabled. Here they are:
Code:
// $2005
func (p *Ppu) WriteScroll(v Word) {
   if p.WriteLatch {
      p.VramLatch = p.VramLatch & 0x7FE0
      p.VramLatch = p.VramLatch | ((int(v) & 0xF8) >> 3)
      p.FineX = v & 0x07
   } else {
      p.VramLatch = p.VramLatch & 0xC1F
      p.VramLatch = p.VramLatch | (((int(v) & 0xF8) << 2) | ((int(v) & 0x07) << 12))
   }

   p.WriteLatch = !p.WriteLatch
}

// $2006
func (p *Ppu) WriteAddress(v Word) {
   if p.WriteLatch {
      p.VramLatch = p.VramLatch & 0xFF
      p.VramLatch = p.VramLatch | ((int(v) & 0x3F) << 8)
   } else {
      p.VramLatch = p.VramLatch & 0x7F00
      p.VramLatch = p.VramLatch | int(v)
      p.VramAddress = p.VramLatch
   }

   p.WriteLatch = !p.WriteLatch
}
Re: Zelda 2 rendering weirdness
by on (#100805)
Bah it was sprite 0. Some debugging code I did a month ago that was hanging around. Thanks guys!
Re: Zelda 2 rendering weirdness
by on (#100809)
It looks like sprite0 hit detection isn't working right for me in games with 8x16 sprites (that was the common factor in all of the broken games). Is there any gotchas to checking on an 8x16 sprite that I should keep in mind? I evaluate sprites as each scanline is rendered, and set the flag then.
Re: Zelda 2 rendering weirdness
by on (#100810)
I don't think there's any difference between 8x8 and 8x16 when it comes to sprite 0 hits. As for the timing of the hit, I imagine that the flag gets set when the first non transparent overlapping BG/SPR pixel is drawn, not when sprites are evaluated. Does anyone know if there's any delay for this flag being set?
Re: Zelda 2 rendering weirdness
by on (#100812)
tokumaru wrote:
I don't think there's any difference between 8x8 and 8x16 when it comes to sprite 0 hits. As for the timing of the hit, I imagine that the flag gets set when the first non transparent overlapping BG/SPR pixel is drawn, not when sprites are evaluated. Does anyone know if there's any delay for this flag being set?

I figured it out. My range when evaluating sprites was always assuming a height of 8 so a sprite0 hit that would occur in the lower region was getting ignored. Got it working now.