Need help with PPU transparency bug [SOLVED]

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Need help with PPU transparency bug [SOLVED]
by on (#64390)
Hello all. I've been working on ironing out some bugs in my CPU implementation. I've still got a bit more work to do in that dept but I've become side-tracked because there is this one particular bug (among many) in my PPU that is bugging the crap outta me. I think it's a transparency algorithm bug but I could be completely wrong - it's been a long time since I looked at the PPU core but I think it's about time this got fixed. I have posted a flash video of the problem. The quality is pretty low but I wanted to keep the file small. If someone tells me the quality is too low to even be useful I can upload a better version - just say the word.

http://www.youtube.com/watch?v=TZqRwS_TZH8

Description of bug: In the video, when Mario becomes invincible and hits enemies you can see a bounding box around his character. It's most noticeable when he hits the coin boxes and the last few enemies. Does anyone have any ideas of what might be causing this? I see this bug in many (all?) other games as well. I've looked at my transparency implementation and it seems to match Brad Taylor's 2C02 tech ref (although that doc does have a lot of errors in it). Does this seem like some kind of transparency bug? Or is it likely something else? Any tips appreciated. :)

Thanks!

EDIT: I uploaded a slightly higher quality version with more examples of the bug.

by on (#64392)
SMB1 does draw transparent boxes on top of all characters. Looks like you are drawing the transparent sprite (with a lower ID) first instead of the other sprites there.
Check if you're treating palettes other than #0 as nontransparent. Don't feel bad, FCUEX also made the same mistake a few months ago when doing sprite collision for the NEW PPU.

Colors 0,4,8,12 are transparent, not just 0.

by on (#64393)
Hmmm...well I checked my algo. All I do is check to see if the least 2 sig bits [1:0] of the palette index are '00'. If they are, then I force the palette index to 0 (transparency). Otherwise, I use the original index value. Ensuring that the least 2 sig bits are 00 will cause the transparency color to be used for any index value that is a multiple of 4 - which is what you are describing.

I think that's correct yes?

Dwedit wrote:
Looks like you are drawing the transparent sprite (with a lower ID) first instead of the other sprites there.

What you are talking about is also sometimes referred to as the "sprite multiplexer" yes? Forgive the dumb question, like I said, it's been a loooooooong time since I've worked on my PPU core. Is there good documentation on how this is supposed to work (besides Brad's doc)? I think this may be where I'm going wrong...maybe.

Thanks!

by on (#64397)
The effective result is that it should draw the sprites on top of each other, with lowest index having the highest priority.

One way to do it is to draw the lowest index first, and once a non-transparent pixel has been drawn, prevent that pixel from being drawn again by another sprite. That should also handle the case where you use the "I'm behind the background" bit to mask other sprites, you just set those pixels as "a sprite has been drawn here, don't draw anything else", but you don't draw the sprite image.
SWEET!!
by on (#64399)
I fixed it! I can't even begin to tell you how excited I am about this! It was in fact a bug in my sprite multiplexer. This bug has existed in my PPU since my initial revision (almost 2 years ago) and it's _finally_ corrected. Thanks so much Dwedit!! =D

by on (#64401)
The 8 2-bit wide sprite shift reg outputs are fed into 8 2-input OR gates, which are fed into a priority encoder (along with the background shift reg + OR gate), fed into a multiplexer selecting the sprite/background. If the sprite's priority bit is set to background and the background bits aren't 0, it forces background.

Edit: doh,too late

by on (#64407)
kyuusaku wrote:
Edit: doh,too late

Don't even worry about it bro. I appreciate the info and you taking the time to help even though I had already fixed the problem. You're explanation is still very useful. So thanks! :)