ti_ntsc 0.1.0: TI 99/4A 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 ti_ntsc_t object
and call ti_ntsc_init(), then call ti_ntsc_blit() to perform
filtering. You can call ti_ntsc_init() at any time to change image
parameters.

ti_ntsc_blit() reads TI pixels and writes RGB pixels (16-bit by
default). The TI pixels are raw palette values (0 to 15). Edit
ti_ntsc_config.h to change this. If your emulator outputs RGB pixels
and can't easily be made to output raw TI palette indicies, use my
sms_ntsc library instead, which accepts 16-bit RGB pixels and will
produce the same result as this library.


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

A custom source RGB palette can also be used to replace the standard TI
color generation hardware. See the palette members of ti_ntsc_setup_t
in ti_ntsc.h for more.


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 eliminates them. (Color) bleed
affects how much colors blend together and the artifact colors at the
edges of pixels surrounded by black. (Color) fringing affects how much
color fringing occurs around the edges of bright objects, especially
white text on a black background.

When using custom settings, initialize your ti_ntsc_setup_t using one
of the standard setups before customizing it. This will ensure that all
fields are properly initialized, including any added in future releases
of the library that your current code can't even know about.

	ti_ntsc_setup_t setup;
	setup = ti_ntsc_composite; /* do this first */
	setup.sharpness = custom_sharpness;
	ti_ntsc_init( ntsc, &setup );


Image Size
----------
For proper aspect ratio, the image generated by the library must be
doubled vertically.

Use the TI_NTSC_OUT_WIDTH() and TI_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 TI_NTSC_OUT_WIDTH( 256 )
to find out how many output pixels are written per row. Another example,
use TI_NTSC_IN_WIDTH( 640 ) to find how many input pixels will fit
within 640 output pixels. The blitter rounds the input width down in
some cases, so the requested width might not be possible. Use
TI_NTSC_IN_WIDTH( TI_NTSC_OUT_WIDTH( in_width ) ) to find what a given
in_width would be rounded down to.


Custom Blitter
--------------
You can write your own blitter, allowing customization of how input
pixels are obtained, 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 ti_ntsc.h for writing your blitter so that your
code can be carried over without changes to improved versions of the
library. The default blitter at the end of ti_ntsc.c shows how to use
the macros. Contact me for further assistance.

The TI_NTSC_BEGIN_ROW macro allows starting up to three pixels. The
first pixel is cut off; its use is in specifying a background color
other than black for the sliver on the left edge. The next two pixels
can be used to handle the extra one or two pixels not handled by the
main chunks of three pixels. For example if you want to blit 257 input
pixels on a row (for whatever odd reason), you would start the first two
with TI_NTSC_BEGIN_ROW( ... ti_ntsc_black, line_in [0], line_in [1] ),
then do the remaining 255 in chunks of three (255 is divisible by 3).


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 source 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 and explanations of NTSC,
which was a starting point for me learning about NTSC video and
decoding. Thanks to the Nesdev forum for feedback and encouragement.
Thanks to Martin Freij (Nestopia author) and Charles MacDonald (SMS Plus
author) for significant ongoing testing and feedback as the library has
improved. Thanks to byuu (bsnes author) and pagefault (ZSNES team) for
feedback about the SNES version.

-- 
Shay Green <gblargg@gmail.com>
