sms_ntsc 0.2.2: Sega Master System NTSC Video Filter
----------------------------------------------------
Author  : Shay Green <gblargg@gmail.com>
Website : http://www.slack.net/~ant/
Forum   : http://groups.google.com/group/blargg-sound-libs
License : GNU Lesser General Public License (LGPL)
Language: C or C++


Overview
--------
To perform NTSC filtering, first allocate memory for a sms_ntsc_t object
and call sms_ntsc_init(), then call sms_ntsc_blit() to perform
filtering. By default, sms_ntsc_blit() reads and writes pixels in 16-bit
RGB. You can call sms_ntsc_init() at any time to change image
parameters.


RGB Palette Generation
----------------------
A 4096-color RGB palette can be generated for use in a normal blitter.
In your sms_ntsc_setup_t structure, point palette_out to a 12288-byte
(4096 * 3) buffer to hold the palette, then call sms_ntsc_init(). If you
only need the palette and aren't going to be using the NTSC blitter,
pass 0 for the first parameter.


Image Parameters
----------------
Many image parameters can be adjusted and presets are provided for
composite video, S-video, RGB, and monochrome. Most are floating-point
values with a general range of -1.0 to 1.0, where 0 is normal. The
ranges are adjusted so that one parameter at an extreme (-1 or +1) and
the rest at zero shouldn't result in any internal overflow (garbage
pixels). Setting multiple parameters to their extreme can produce
garbage. Put another way, the state space defined by all parameters
within the range -1 to +1 is not fully usable, but some extreme corners
are very useful so I don't want to reduce the parameter ranges.

The sharpness and resolution parameters have similar effects. Resolution
affects how crisp pixels are. Sharpness merely enhances the edges by
increasing contrast, which makes things brighter at the edges. Artifacts
sets how much "junk" is around the edges where colors and brightness
change in the image, where -1 completely eliminats them. Bleed affects
how much colors blend together and the artifact colors at the edges of
pixels surrounded by black.


Image Size
----------
Use the SMS_NTSC_OUT_WIDTH() and SMS_NTSC_IN_WIDTH() macros to convert
between input and output widths that the blitter uses. For example, if
you are blitting an image 256 pixels wide, use SMS_NTSC_OUT_WIDTH( 256 )
to find out how many output pixels are written per row. Another example,
use SMS_NTSC_IN_WIDTH( 640 ) to find how many input pixels will fit
within 640 output pixels.

For proper aspect ratio, the image generated by the library must be
doubled vertically by the caller. This can be done in software, as the
demo does, done in a custom blitter for more efficiency (see below), or
using a modern video card's hardware rescaling. On a TV pixels never
have crisp edges, so simply doubling scanlines doesn't give a very
authentic image. I've found reducing the doubled scanline's brightness
to 75% looks significantly better without darkening the image much. To
drop brightness to 75%, calculate 25% brightness using simple bit
shifting and masking, then subtract this from the original.


Pixel Format
------------
The input and output pixel formats can be set by defining macros either
in the compiler's command-line options

	-DSMS_NTSC_FOO=BAR

or by wrapping sms_ntsc.c with your own source file and using this in
place of it:

	/* my_sms_ntsc.c */
	#define SMS_NTSC_FOO BAR
	#include "sms_ntsc.c"

The input format is set by SMS_NTSC_IN_FORMAT. Use one of the following
(or equivalent) to change it:

	#define SMS_NTSC_IN_FORMAT SMS_NTSC_RGB16 /* 16-bit RGB (default) */
	#define SMS_NTSC_IN_FORMAT SMS_NTSC_BGR12 /* 12-bit BGR */

The output RGB bit depth is set by SMS_NTSC_OUT_DEPTH. Use one of the
following:

	#define SMS_NTSC_OUT_DEPTH 16 /* 16-bit RGB (default) */
	#define SMS_NTSC_OUT_DEPTH 24 /* 24-bit RGB */
	#define SMS_NTSC_OUT_DEPTH 32 /* 24-bit RGB (same as 24) */
	#define SMS_NTSC_OUT_DEPTH 15 /* 15-bit RGB (same as 24) */


Custom Blitter
--------------
You can write your own blitter, allowing customization of how SMS pixels
are obtained (you might want to run through a palette first), the format
of output pixels (15, 16, or 32-bit RGB), optimizations for your
platform, and additional effects like efficient scanline doubling during
blitting.

Macros are included in sms_ntsc.h for writing your blitter so that your
code can be carried over without changes to improved versions of the
library. The default blitters at the end of sms_ntsc.c show how to use
the macros. In your custom blitter's source file you must #define
SMS_NTSC_IN_FORMAT to the your input format (see above) before using the
macros. For an example of a flexible blitter written in C++ and
optimized for the x86 architecture, refer to Nestopia 1.28's
NstVideoFilterNtsc.hpp (uses sms_ntsc, which is very similar).


Limitations
-----------
The library's horizontal rescaling is too wide by about 3% in order to
allow a much more optimal implementation. This means that a 248 pixel
wide SMS image should appear as 563 output pixels, but with this library
appears as 581 output pixels. TV aspect ratios probably vary by this
much anyway. If you really need unscaled output, contact me and I'll see
about adding it.


Thanks
------
Thanks to NewRisingSun for his original code, which was a starting point
for me learning about NTSC video and decoding. Thanks to the Nesdev
forum for feedback and encouragement. Thanks to byuu (bsnes author) and
pagefault (ZSNES team) for integrating a SNES version of this in their
emulators. Thanks to Martin Freij (Nestopia author) for using an earlier
development version in Nestopia and for feedback about the custom
blitter interface. Thanks to Charles MacDonald for feedback on the SMS
version's interface.

-- 
Shay Green <gblargg@gmail.com>
