PPU question for SNES emu authors

Strictly for discussing ZSNES development and for submitting code. You can also join us on IRC at irc.libera.chat in #zsnes.
Please, no requests here.

Moderator: ZSNES Mods

Post Reply
byuu

PPU question for SNES emu authors

Post by byuu »

I have a question for anyone who's implemented a PPU for an SNES emu...

I'd like to add filtering like hq2x or whatnot at some point to my emulator, but I don't know how it would be possible to do efficiently.

Basically, the standard SNES resolution is 256x224, which easily scales to 512x448. The problem is all the extra features of the SNES. Modes 5 and 6 push the horizontal resolution to 512x224, and interlace pushes that to 512x448. There's also pseudo-512 mode, which I still don't really understand despite it being explained repeatedly to me. I think that's a mode7 only effect, though. And, most importantly: sprite interlace.
I could get around the 512 width modes 5 and 6 and interlace flag by not filtering modes 5/6 ever, which has the potential to look bad if a game swaps between mode1 and 5/6 often. I could get around the pseudo-512 using the same technique. But the interlaced sprites are the real problem. Although I've only seen one cart ever use them (SNES Test Program), I want to emulate everything. Interlaced sprites work in all video modes, including mode 1, which is usually 256x224. The only way to draw an interlaced sprite properly, is to always use an internal buffer of 512x448. But if I do that, I won't be able to filter the image anymore unless I want to use 1024x896 or better, which is totally ridiculous.

How do other emulators get around these issues? I know ZSNES just doesn't support interlaced sprites at all, but I haven't tried other emulators.
Overload
Hazed
Posts: 70
Joined: Sat Sep 18, 2004 12:47 am
Location: Australia
Contact:

Post by Overload »

Blues Brothers is the only game i can recall that uses interlaced sprites (intro text). You should try Anomie's PPU Test program.

Super Sleuth supports interlaced sprites for all modes, however modes 5 & 6 are the only modes that render single scan. All other modes render dual scan and subsequently flicker a lot. All frames are rendered at 512 x 448 regardless of what mode is current.

I have no intention of ever adding filters so i can't help you out there.

Code: Select all

Chapter 9.	H-Pseudo 512

9.1	OUTLINE
In modes other than 5 and 6, this function provides gradation between 2 dots which are next to each other horizontally, which changes the color smoothly.

9.2	FUNCTION
This function utilizes screen addition/subtraction. The color constant addition/sub-traction can not be done at the same time that this function is performed.
Basically all even pixels are taken from the main screen and all odd pixels from the sub screen.
byuu

Post by byuu »

Blues Brothers is the only game i can recall that uses interlaced sprites (intro text).
Good to know another game uses it.
Edit: Holy crap! What in the heck was the guy on who wrote that game?! >_<
Super Sleuth supports interlaced sprites for all modes, however modes 5 & 6 are the only modes that render single scan. All other modes render dual scan and subsequently flicker a lot.
I tried the effect out on my copier, and it doesn't appear to flicker. Either it's the TV hiding the flickering really well, or it being virtually unnoticeable that half the lines in the sprite are missing.
The 16x16 interlaced sprite I used looked exactly the same in 512x448 mode5 as it did in 256x224 non-interlace mode0. It could just be my eyes that are deceiving me, though. I don't understand how the screen can be rendered non-interlace, and the sprite as interlaced.
All frames are rendered at 512 x 448 regardless of what mode is current. I have no intention of ever adding filters so i can't help you out there.
Neat that you always use 512x448 also and still maintain a decent framerate. There's something in my PPU that's just murdering performance...
Interesting stance on not adding filters... maybe I'll just end up doing the same thing, as I don't see an easy solution to interlaced sprites anyway.

Thanks for the feedback.
Basically all even pixels are taken from the main screen and all odd pixels from the sub screen.
Ok, so you would basically split a 512x224 image in half, even vertical lines in one image, odd vertical lines in the other. Then you would put the first image in BG1 and enable BG1 as a mainscreen, and then put the second image in BG2 and enable that as a subscreen, and the result would be the full 512x224 image? That in and of itself should be simple enough to implement, what's going to be fun is all the crazy combinations like mosaic, EXTBG mode7, color add/sub being on and off during the frame, windowing, and all the other fun registers that interact with it.
anomie
Lurker
Posts: 151
Joined: Tue Dec 07, 2004 1:40 am

Post by anomie »

byuusan wrote:I don't understand how the screen can be rendered non-interlace, and the sprite as interlaced.
IIRC we tested this in the other thread. Recall that the SNES normally outputs only one field constantly. Interlace must be enabled on BGs as well as OBJ to properly render 'interlaced' even-and-odd with both fields output. Otherwise you just get the even OBJ lines drawn one frame and the odd OBJ lines drawn the next, but both output on the one field.
Ok, so you would basically split a 512x224 image in half, even vertical lines in one image, odd vertical lines in the other. Then you would put the first image in BG1 and enable BG1 as a mainscreen, and then put the second image in BG2 and enable that as a subscreen, and the result would be the full 512x224 image?
Sounds about right to me. Note that on the TV screen each one of those 512 dots is only ~1/3 of a single NTSC color subcarrier cycle, so fine details tend to blend together. If BG1 is solid green and BG2 is solid red, your NTSC TV will just show a solid yellow. And I suspect PAL won't be much better.
That in and of itself should be simple enough to implement, what's going to be fun is all the crazy combinations like mosaic, EXTBG mode7, color add/sub being on and off during the frame, windowing, and all the other fun registers that interact with it.
Particularly the color math.
byuu

Post by byuu »

anomie wrote:IIRC we tested this in the other thread. Recall that the SNES normally outputs only one field constantly. Interlace must be enabled on BGs as well as OBJ to properly render 'interlaced' even-and-odd with both fields output. Otherwise you just get the even OBJ lines drawn one frame and the odd OBJ lines drawn the next, but both output on the one field.
The interesting thing was that I tested in Mode1 with interlace disabled and sprite interlacing enabled. I noticed absolutely no flickering that would be apparent if this were the case. I'll make a better test to confirm, though. I'll make every even horizontal line red, and every odd one green, and see how it gets colored on the screen.
Sounds about right to me. Note that on the TV screen each one of those 512 dots is only ~1/3 of a single NTSC color subcarrier cycle, so fine details tend to blend together. If BG1 is solid green and BG2 is solid red, your NTSC TV will just show a solid yellow. And I suspect PAL won't be much better.
1/3?? Weird. I would've guessed 1/2. Otherwise, wouldn't 256x224 only show 2/3rds color per pixel? I would imagine that would result in terrible color bleeding making most images look terrible.
You also bring up a good point. Should we be trying to emulate the NTSC color better? Obviously if we render 512x224 with your example, we'd have red and green bars that are clearly each well defined. But the developer/artist could have intended us to see yellow there instead...
I definately have reservations about the aspect ratio differences between a TV and a monitor. The effect is extremely apparent in Der Langrisser. The character portraits are 40x48, and they look crushed in emulators, but they widen out to be perfect squares on the TV.
anomie
Lurker
Posts: 151
Joined: Tue Dec 07, 2004 1:40 am

Post by anomie »

byuusan wrote:The interesting thing was that I tested in Mode1 with interlace disabled and sprite interlacing enabled. I noticed absolutely no flickering that would be apparent if this were the case. I'll make a better test to confirm, though. I'll make every even horizontal line red, and every odd one green, and see how it gets colored on the screen.
Do a comparison between that and with both interlacings enabled too. When i did something similar, I noticed a difference.
1/3?? Weird. I would've guessed 1/2. Otherwise, wouldn't 256x224 only show 2/3rds color per pixel? I would imagine that would result in terrible color bleeding making most images look terrible.
The SNES master clock is 6 times the NTSC color subcarrier frequency, but the SNES spits out a non-hires dot every 4 master cycles. IIRC, that's why the missing dot every other frame, to change the phase of the subcarrier in relation to the dots.

Mostly, it's just the fine (1-pixel-wide) detail that gets lost, and sharp edges get a bit fuzzy. The same thing happens to regular TV though.
You also bring up a good point. Should we be trying to emulate the NTSC color better? Obviously if we render 512x224 with your example, we'd have red and green bars that are clearly each well defined. But the developer/artist could have intended us to see yellow there instead...
snes9x used to (well, the released versions still do) try to blend the pseudo-hires to make yellow from red+green. And it does look kind of bad if you scale the screen to something that's not a multiple of 512 (at least without good scalers). But we decided with snes9x that if it's that important to somene they can write a NTSC filter mode.
I definately have reservations about the aspect ratio differences between a TV and a monitor. The effect is extremely apparent in Der Langrisser. The character portraits are 40x48, and they look crushed in emulators, but they widen out to be perfect squares on the TV.
OTOH, you could take care of that easily enough with a good scaler and set it to scale to 341x224, 683x448, or whatever gives the right aspect ratio. A bad scaler will probably look worse than the crushed squares, just doubling every 3rd column or something.
Post Reply