SNES NTSC Composite Video Filter

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
blargg
Regular
Posts: 327
Joined: Thu Jun 30, 2005 1:54 pm
Location: USA
Contact:

SNES NTSC Composite Video Filter

Post by blargg »

I've written a blitter/filter for use in a Super NES emulator that simulates the NTSC composite video signal and TV's decoding of it. It's written in C and has a BSD-style license. It accepts 15-bit BGR SNES pixels and outputs to 16-bit RGB pixels. Here's its output expanded to 3x with scanline darkening added (75%, 100%, 50%):

Image

Raw performance when blitting a 256x223 15-bit BGR SNES source image to a 684x223 16-bit RGB memory buffer is 740 frames per second on an Athlon 3500+ at 2.0 GHz and 150 frames per second on a 10-year-old 400 MHz G3 PowerMac. Changing the image parameters like brightness and sharpness takes 1/16 second on the Athlon and 1/4 second on the G3. About 4.5 MB of RAM is needed to hold the data table. It supports low-res and high-res (512 pixels horizontally) SNES graphics modes.

snes_ntsc-0.1.0.zip

Feedback appreciated, since this has only been tested a bit by byuu in bsnes over the weekend (apparently there wasn't enough time to post a WIP build of it).

EDIT: Argh, a problem I thought I fixed has manifested again (faint patterns in solid colored areas). And I realized that the raw test image is in big-endian format, which will make it appear as junk on a little-endian machine. Working on fixes...

EDIT 2: OK, fixed two problems that were causing patterns in solid colored areas (rounding issues). Raw test image is now in little-endian format, so at least it'll work in the SDL demo on an x86 PC. Above archive has been updated; same filename.
Last edited by blargg on Mon Feb 27, 2006 11:58 pm, edited 2 times in total.
doktor_kris
Lurker
Posts: 102
Joined: Sat Feb 25, 2006 7:47 pm
Contact:

Post by doktor_kris »

Looks really nice judging from the posted picture. :)
byuu

Post by byuu »

Yeah, sorry. I didn't get much time to prepare a WIP release, and then my host started acting up. Giving all kinds of CGI errors, but I think I know what the problem is. If I get the hosting thing fixed, I'll try and get it out tonight.
ShadowFX
Regular
Posts: 265
Joined: Thu Jul 29, 2004 8:55 am
Location: The Netherlands

Post by ShadowFX »

Say, isn't a similar/same(?) filter used in the newest NEStopia? This is one the reasons I really like this emulator :)
blargg
Regular
Posts: 327
Joined: Thu Jun 30, 2005 1:54 pm
Location: USA
Contact:

Post by blargg »

Yes, it's based on the filter code I wrote for the NES, which the author of Nestopia used (with some minor modifications). The NES and SNES have the same pixel timing, so the code is very similar. It's had a couple of rewrites since the Nestopia version, converting it from floating-point to integer math, making it many times faster than it was then, and better quality too. I'll be releasing an updated NES version of this soon, which should find its way into Nestopia. It's more important on the NES, since it doesn't have an RGB color palette like the SNES, and pixel artifacts are more visible.
Sith
Lurker
Posts: 100
Joined: Tue Jul 19, 2005 12:32 pm
Location: Belgium

Post by Sith »

Looks really authentic Blargg, great job! :D
[url=http://zsnes.ipherswipsite.com/]Zsnes WIP[/url]
[url=http://byuu.cinnamonpirate.com/?page=bsnes]Bsnes[/url] by Byuu
[url=http://www.eidolons-inn.net/tiki-index.php?page=Kega]Kega Fusion[/url] by SteveSnake
[url=http://www.viceteam.org/]Vice[/url] by Viceteam
Aaron
Lurker
Posts: 157
Joined: Sat Dec 31, 2005 7:26 am

Post by Aaron »

blargg wrote:converting it from floating-point to integer math, making it many times faster than it was then, and better quality too.
Can you see from the changes that the Nestopia author made to apply it to your current filter?
blargg
Regular
Posts: 327
Joined: Thu Jun 30, 2005 1:54 pm
Location: USA
Contact:

Post by blargg »

Sorry, I meant that those were the changes I made to the algorithm, which are in the code above; Nestopia uses the old, slower algorithm. At this point, if someone's going to make it go faster, it'll be by rewriting the main blitter loop to use SIMD instructions (MMX/SSE/AltiVec/etc.). I'll gladly assist with that, though the blitter loop itself is very simple, just a big convolution (FIR filter) with clamping at the end.
pagefault
ZSNES Developer
ZSNES Developer
Posts: 812
Joined: Tue Aug 17, 2004 5:24 am
Location: In your garden

Post by pagefault »

Looks rather cool. I will play around with it later tonight and post an binary here for someone to try out.
byuu

Post by byuu »

Ok, I've released a beta of bsnes with NTSC filter support. Please read all of this to find out where to get it. Please post feedback / bug reports here.

Code: Select all

bsnes v0.015 rc1 readme
Release date: 02/28/2006
-----------------------
This is a beta release not intended for public use!
I released this beta so that blargg and I can get feedback
on his SNES NTSC composite video filter.

This release requires DirectX9, SSE2 support, and a
relatively decent video card. I don't want to hear about
why an SNES emulator needs any or all of these features.
This is a pre-release. The official releases may or may not
require these features.

No video output
---------------
If the video output is completely blank, then your video
card likely doesn't support D3D's StretchRects. You can
switch to the DirectDraw renderer by changing
video.renderer from "d3d" to "dd", however I forgot to
increase the size of the DD render surface before uploading
the RC, so the NTSC renderer won't work with DirectDraw
mode. Sorry about that.

Cards that don't support StretchRects include the S3
Savage, ATI Radeon 7500 and below, and plenty of others.
Supposely newer Radeon cards support StretchRects. Please
let me know how it goes if you use bsnes on one of these
cards.

You should be fine if you have an nVidia-based card.

NTSC filter
-----------
The most important thing about the NTSC filter is the merge
fields option. I have yet to add a way to toggle this
option inside of the GUI, therefore it is only accessible
via the config file entry "snes.ntsc_merge_fields".

To achieve the full effects of the NTSC filter, you must be
running at 60hz, have triple buffering enabled, have
frameskip set to 0 (disabled), and be maintaining a steady
60fps! If any of these are not true, you will get constant
flickering when merge fields is disabled.

Since I know only one in five people will read this, I've
reluctantly set merge fields to false by default.

The NTSC filter supports proper hires color blending,
therefore the internal mixer for hires has been disabled.
This means psuedo-hires effects with any filter besides
NTSC will look pretty bad. However, the effect is amazingly
accurate when the NTSC filter is enabled.

Lastly, the NTSC filter does not currently use the color
adjustment table, but instead calculates the RGB output
on its own. This means the slider adjustments in the filter
configuration screen will not work. I'll try and address
this issue before the next official release.

HQ2x filter
-----------
This filter is only partially implemented. Any game that
uses hires or interlace will probably crash the emulator.
Use it at your own risk.

Any other bugs
--------------
Please do not report other bugs. This release was only
intended for feedback on how the NTSC filter works.

If you are reporting a bug, please only use Zelda 3 US or
Super Mario World US. There are plenty of game-specific
bugs in out there, but these two are known to be pretty
near perfect, so this will rule out any issues here.

Where is the file?
------------------
Offsite linking is disabled. Please copy and paste the URL.
http://byuu.cinnamonpirate.com/files/bsnes_v015_rc1.zip
Thanks for reading this before downloading.

Where is the source code?
-------------------------
This file is being hosted on my own server. To save
bandwidth, I didn't include the source in this release.
If someone wishes to host a version with the source
code, that can be arranged.
In the mean time, if you really need the source, the file
name is bsnes_v015_rc1_src.zip. If you can't figure out
how to get it, then you probably won't have any use for it
anyway.

~byuu
pagefault, I hope you don't mind me linking to this thread via my website and zophar's board. I want to try and consolidate feedback on this to one place.
pagefault
ZSNES Developer
ZSNES Developer
Posts: 812
Joined: Tue Aug 17, 2004 5:24 am
Location: In your garden

Post by pagefault »

byuu wrote:pagefault, I hope you don't mind me linking to this thread via my website and zophar's board. I want to try and consolidate feedback on this to one place.
It's no problem :) No need to be worrying about it, you are very welcome to use these boards for anything you want.
Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

pagefault wrote:
byuu wrote:pagefault, I hope you don't mind me linking to this thread via my website and zophar's board. I want to try and consolidate feedback on this to one place.
It's no problem :) No need to be worrying about it, you are very welcome to use these boards for anything you want.
Anything you want within rules of course. SNES emulation talk is very welcome here.
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
Sith
Lurker
Posts: 100
Joined: Tue Jul 19, 2005 12:32 pm
Location: Belgium

Post by Sith »

Guess I am one of those 5 people, Byuu. :wink:
Downloading now...

Edit: WTF??? My browser is not finding the file? (I'm using IE6).
"IE can't open this website"

:(
[url=http://zsnes.ipherswipsite.com/]Zsnes WIP[/url]
[url=http://byuu.cinnamonpirate.com/?page=bsnes]Bsnes[/url] by Byuu
[url=http://www.eidolons-inn.net/tiki-index.php?page=Kega]Kega Fusion[/url] by SteveSnake
[url=http://www.viceteam.org/]Vice[/url] by Viceteam
pagefault
ZSNES Developer
ZSNES Developer
Posts: 812
Joined: Tue Aug 17, 2004 5:24 am
Location: In your garden

Post by pagefault »

A quick question about this filter. It can only read from a 15-bit buffer? ZSNES currently has a 16-bit buffer it renders to.
Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

pagefault wrote:A quick question about this filter. It can only read from a 15-bit buffer? ZSNES currently has a 16-bit buffer it renders to.
My movie dumping tests which I've been running for the past month show ZSNES only uses 15 of the 16 bits.

This is without filtering of course.
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
pagefault
ZSNES Developer
ZSNES Developer
Posts: 812
Joined: Tue Aug 17, 2004 5:24 am
Location: In your garden

Post by pagefault »

Ok. I have it almost ready. I am threaded it also to take advantage of dual core CPUs. While the image is filtered zsnes goes ahead to render the next frame.
FitzRoy
Veteran
Posts: 861
Joined: Wed Aug 04, 2004 5:43 pm
Location: Sloop

Post by FitzRoy »

Omg *loves the pixel filter*

Only issue I've run into that you might not already know about... when in a full screen video mode, I cannot access the filter options (possibly other windows too, I'm at work right now). It does create the window, but it creates it behind the main where you can't see it. And even if you go back out into windowed video modes, you have to move the main window completely out of the way. Clicking on it doesn't make it pop over.
www.zapatabase.com
blargg
Regular
Posts: 327
Joined: Thu Jun 30, 2005 1:54 pm
Location: USA
Contact:

Post by blargg »

A quick question about this filter. It can only read from a 15-bit buffer? ZSNES currently has a 16-bit buffer it renders to.
Apparently you solved this issue, but for reference, it can easily be modified to use a different input format (and for that matter, output format). It only uses 13 bits from the color anyway: 4 red, 5 green, and 4 blue. This is to reduce the memory usage from 18 to 4.5 MB (and reduce the cache load). See snes_ntsc.c line 394 for the macro that converts from the source index to the address of the entry (it's a bit optimized to help the compiler avoid an extra shift or multiply).
byuu

Post by byuu »

Hmm, no feedback whatsoever. Sorry blargg :(

FitzRoy: Known issues, thanks.
Ok. I have it almost ready. I am threaded it also to take advantage of dual core CPUs. While the image is filtered zsnes goes ahead to render the next frame.
Awesome! We're sure to get a lot more feedback when this is added to ZSNES. One thing though: please make sure the aspect ratio is corrected. 512x448 with the NTSC filter is just plain wrong :/
It really should be 582x448. Failing that, please at least verify that fullscreen 640x480 with screen stretch enabled will stretch from the internal 683(?)x448 to 640x480, and not 683(?)x448->512x448->640x480.

If you have any questions about the filter or want some help, I'll be on freenode some time tonight, or you can PM me and I'll be glad to assist.
pagefault
ZSNES Developer
ZSNES Developer
Posts: 812
Joined: Tue Aug 17, 2004 5:24 am
Location: In your garden

Post by pagefault »

Well we haven't fixed all issues. the filter is working... sort of. I am not sure if it doesn't like it's input buffer or there is a problem outputting it.

http://zsnes.game-host.org/~pagefault/ntsc.png

Suffice to say. It's very strange.
byuu

Post by byuu »

Are you sure the output buffer is big enough, and that you're providing the right pitch? It requires the pitch be sent in bytes-scanline, and not pixels-scanline.
pagefault
ZSNES Developer
ZSNES Developer
Posts: 812
Joined: Tue Aug 17, 2004 5:24 am
Location: In your garden

Post by pagefault »

Ok I have it working now but the image is off centered by it seems 32 pixels to the right. And the colours are wrong. I think this is because ZSNES uses a RGB buffer and not a BGR, so I will have to change some things to get this working.
blargg
Regular
Posts: 327
Joined: Thu Jun 30, 2005 1:54 pm
Location: USA
Contact:

Post by blargg »

Here is all you need to change to have it use source pixels in 15-bit RGB format instead of BGR:

Code: Select all

/* snes_ntsc.c line 341 */
/* Use SNES source pixels in 15-bit RGB format rather BGR */
int ir = entry >> 8 & 0x1E;
int ig = entry >> 4 & 0x1F;
int ib = entry << 1 & 0x1E;
Sith
Lurker
Posts: 100
Joined: Tue Jul 19, 2005 12:32 pm
Location: Belgium

Post by Sith »

Blargg, looks like your new filter is getting popular. :wink:
It will be in Zsnes, Bsnes and I informed SteveSnake (who writes Kega) and he's interested in it too.
Yeah, all my favourite emus will support your cool filter! :D
[url=http://zsnes.ipherswipsite.com/]Zsnes WIP[/url]
[url=http://byuu.cinnamonpirate.com/?page=bsnes]Bsnes[/url] by Byuu
[url=http://www.eidolons-inn.net/tiki-index.php?page=Kega]Kega Fusion[/url] by SteveSnake
[url=http://www.viceteam.org/]Vice[/url] by Viceteam
King Of Chaos
Trooper
Posts: 394
Joined: Mon Feb 20, 2006 3:11 am
Location: Space

Post by King Of Chaos »

Sith-Smasher wrote:Blargg, looks like your new filter is getting popular. :wink:
It will be in Zsnes, Bsnes and I informed SteveSnake (who writes Kega) and he's interested in it too.
Yeah, all my favourite emus will support your cool filter! :D
Accually Blargg (or anyone else) can just write a rendering plugin for Kega.

As for Bsnes, After several Direct3D9 errors at startup, I'll just wait for the next version. :)
Post Reply