More updates to Blargg filtering. The current code now corresponds to

the patches I received in the past, but also includes stuff from newer
versions.  It compiles correctly; now I just have to activate it and
pass it a framebuffer and see what happens ...


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2454 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2012-04-30 20:12:43 +00:00
parent 3ec9fe888d
commit bace21c40b
5 changed files with 196 additions and 448 deletions

View File

@ -83,6 +83,7 @@ void NTSCFilter::updateFilter()
void NTSCFilter::restoreDefaults() void NTSCFilter::restoreDefaults()
{ {
mySetup = atari_ntsc_composite; mySetup = atari_ntsc_composite;
updateFilter();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -250,8 +251,8 @@ int NTSCFilter::FILTER_NTSC_Initialise(int *argc, char *argv[])
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void NTSCFilter::updateYIQTable(double yiq_table[384], double start_angle) void NTSCFilter::updateYIQTable(double yiq_table[384], double start_angle)
{ {
const double start_saturation = 0.0; // calculated internally // FIXME - const double start_saturation = 0.0; // calculated internally
const double gamma = 1; // 1 - COLOURS_NTSC_setup.gamma / 2.0; // FIXME - const double gamma = 1; // 1 - COLOURS_NTSC_setup.gamma / 2.0;
uInt8* ext_ptr = myTIAPalette; uInt8* ext_ptr = myTIAPalette;
int n; int n;
@ -295,7 +296,9 @@ atari_ntsc_setup_t const * const NTSCFilter::presets[NTSCFilter::PRESET_SIZE] =
&atari_ntsc_composite, &atari_ntsc_composite,
&atari_ntsc_svideo, &atari_ntsc_svideo,
&atari_ntsc_rgb, &atari_ntsc_rgb,
&atari_ntsc_monochrome &atari_ntsc_monochrome,
&atari_ntsc_bad,
&atari_ntsc_horrible
}; };
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -303,5 +306,7 @@ static char const * const preset_cfg_strings[NTSCFilter::PRESET_SIZE] = {
"COMPOSITE", "COMPOSITE",
"SVIDEO", "SVIDEO",
"RGB", "RGB",
"MONOCHROME" "MONOCHROME",
"BAD",
"HORRIBLE"
}; };

View File

@ -59,6 +59,8 @@ class NTSCFilter
PRESET_SVIDEO, PRESET_SVIDEO,
PRESET_RGB, PRESET_RGB,
PRESET_MONOCHROME, PRESET_MONOCHROME,
PRESET_BAD,
PRESET_HORRIBLE,
PRESET_CUSTOM, PRESET_CUSTOM,
/* Number of "normal" (not including CUSTOM) values in enumerator */ /* Number of "normal" (not including CUSTOM) values in enumerator */
PRESET_SIZE = PRESET_CUSTOM PRESET_SIZE = PRESET_CUSTOM

View File

@ -17,103 +17,79 @@
// $Id$ // $Id$
//============================================================================ //============================================================================
/* Based on nes_ntsc 0.2.2. http://www.slack.net/~ant/ */
#include "atari_ntsc.h" #include "atari_ntsc.h"
/* Copyright (C) 2006-2007 Shay Green. This module is free software; you /* Copyright (C) 2006-2009 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This version 2.1 of the License, or (at your option) any later version. This
module is distributed in the hope that it will be useful, but WITHOUT ANY module is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details. You should have received a copy of the GNU Lesser General Public details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation, License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Atari change: removal and addition of structure fields. /* Atari change: removal and addition of structure fields.
Values of resolution and sharpness adjusted to make NTSC artifacts look better. */ Values of resolution and sharpness adjusted to make NTSC artifacts look better. */
atari_ntsc_setup_t const atari_ntsc_monochrome = { 0, -1, 0, 0, -.3, .3, .2, -.2, -.2, -1, 0, 0, 0, 0. }; atari_ntsc_setup_t const atari_ntsc_composite =
atari_ntsc_setup_t const atari_ntsc_composite = { 0, 0, 0, 0, -.5, .3, -.1, 0, 0, 0, 0, 0, 0, 0. }; { 0.0, 0.0, 0.0, 0.0 , -0.5, .3, -0.1 , 0.0, 0.0, 0.0, 0, 0, 0, 0. };
atari_ntsc_setup_t const atari_ntsc_svideo = { 0, 0, 0, 0, -.3, .3, .2, -1, -1, 0, 0, 0, 0, 0. }; atari_ntsc_setup_t const atari_ntsc_svideo =
atari_ntsc_setup_t const atari_ntsc_rgb = { 0, 0, 0, 0, -.3, .3, .7, -1, -1, -1, 0, 0, 0, 0. }; { 0.0, 0.0, 0.0, 0.0 , -0.3, .3, 0.2 , -1.0, -1.0, 0.0, 0, 0, 0, 0. };
atari_ntsc_setup_t const atari_ntsc_rgb =
{ 0.0, 0.0, 0.0, 0.0 , -0.3, .3, 0.7 , -1.0, -1.0, -1.0, 0, 0, 0, 0. };
atari_ntsc_setup_t const atari_ntsc_monochrome =
{ 0.0, -1.0, 0.0, 0.0 , -0.3, .3, 0.2 , -0.2, -0.2, -1.0, 0, 0, 0, 0. };
atari_ntsc_setup_t const atari_ntsc_bad =
{ 0.1, -0.3, 0.3, 0.25, 0.2, 0, 0.1 , 0.5, 0.5, 0.5, 0, 0, 0, 0. };
atari_ntsc_setup_t const atari_ntsc_horrible =
{ -0.1, -0.5, 0.6, 0.43, 0.4, 0, 0.05, 0.7, -0.8, -0.7, 0, 0, 0, 0. };
#define alignment_count 4 #define alignment_count 2
#define burst_count 1 #define burst_count 1
#define rescale_in 8 #define rescale_in 8
#define rescale_out 7 #define rescale_out 7
#define artifacts_mid 1.0f #define artifacts_mid 1.0f
#define fringing_mid 1.0f #define fringing_mid 1.0f
/* Atari change: default palette is already at correct hue.
#define std_decoder_hue -15 */
#define std_decoder_hue 0 #define std_decoder_hue 0
/* Atari change: only one palette - remove base_palete field. */
#define STD_HUE_CONDITION( setup ) !(setup->palette)
#include "atari_ntsc_impl.h" #include "atari_ntsc_impl.h"
/* Atari change: adapted to 4/7 pixel ratio. */ /* 2 input pixels -> 8 composite samples */
/* 4 input pixels -> 8 composite samples */
pixel_info_t const atari_ntsc_pixels [alignment_count] = { pixel_info_t const atari_ntsc_pixels [alignment_count] = {
{ PIXEL_OFFSET( -6, -6 ), { 0, 0, 1, 1 } }, { PIXEL_OFFSET( -4, -9 ), { 1, 1, 1, 1 } },
{ PIXEL_OFFSET( -4, -4 ), { 0, 0, 1, 1 } }, { PIXEL_OFFSET( 0, -5 ), { 1, 1, 1, 1 } },
{ PIXEL_OFFSET( -2, -2 ), { 0, 0, 1, 1 } },
{ PIXEL_OFFSET( 0, 0 ), { 0, 0, 1, 1 } },
}; };
/* Atari change: no alternating burst phases - removed merge_kernel_fields function. */
static void correct_errors( atari_ntsc_rgb_t color, atari_ntsc_rgb_t* out ) static void correct_errors( atari_ntsc_rgb_t color, atari_ntsc_rgb_t* out )
{ {
int n;
for ( n = burst_count; n; --n )
{
unsigned i; unsigned i;
for ( i = 0; i < rgb_kernel_size / 2; i++ ) for ( i = 0; i < rgb_kernel_size / 2; i++ )
{ {
/* Atari change: adapted to 4/7 pixel ratio */
atari_ntsc_rgb_t error = color - atari_ntsc_rgb_t error = color -
out [i ] - out [(i+12)%14+14] - out [(i+10)%14+28] - out[(i+8)%14+42] - out [i ] - out [(i+10)%14+14] -
out [i + 7] - out [i + 5 +14] - out [i + 3 +28] - out [ i+1 +42]; out [i + 7] - out [i + 3 +14];
DISTRIBUTE_ERROR( i+1+42, i+3+28, i+5+14, i+7 ); CORRECT_ERROR( i + 3 + 14 );
}
out += alignment_count * rgb_kernel_size;
} }
} }
void atari_ntsc_init( atari_ntsc_t* ntsc, atari_ntsc_setup_t const* setup ) void atari_ntsc_init( atari_ntsc_t* ntsc, atari_ntsc_setup_t const* setup )
{ {
/* Atari change: no alternating burst phases - remove merge_fields variable. */
int entry;
init_t impl; init_t impl;
/* Atari change: NES palette generation and reading removed.
Atari palette generation is located in colours_ntsc.c, and colours are read
from setup->yiq_palette. */
if ( !setup ) if ( !setup )
setup = &atari_ntsc_composite; setup = &atari_ntsc_composite;
init( &impl, setup ); init( &impl, setup );
/* Atari change: no alternating burst phases - remove code for merge_fields. */ /* Atari change: no alternating burst phases - remove code for merge_fields. */
for ( entry = 0; entry < atari_ntsc_palette_size; entry++ ) for (int entry = 0; entry < atari_ntsc_palette_size; entry++ )
{ {
/* Atari change: Instead of palette generation, load colours double* yiq_ptr = setup->yiq_palette + 3 * entry;
from setup->yiq_palette. */ double y = *yiq_ptr++;
double y; double i = *yiq_ptr++;
double i; double q = *yiq_ptr++;
double q;
{
double *yiq_ptr = setup->yiq_palette + 3 * entry;
y = *yiq_ptr++;
i = *yiq_ptr++;
q = *yiq_ptr++;
}
i *= rgb_unit; i *= rgb_unit;
q *= rgb_unit; q *= rgb_unit;
@ -121,7 +97,6 @@ void atari_ntsc_init( atari_ntsc_t* ntsc, atari_ntsc_setup_t const* setup )
y += rgb_offset; y += rgb_offset;
/* Generate kernel */ /* Generate kernel */
{
int r, g, b = YIQ_TO_RGB( y, i, q, impl.to_rgb, int, r, g ); int r, g, b = YIQ_TO_RGB( y, i, q, impl.to_rgb, int, r, g );
/* blue tends to overflow, so clamp it */ /* blue tends to overflow, so clamp it */
atari_ntsc_rgb_t rgb = PACK_RGB( r, g, (b < 0x3E0 ? b: 0x3E0) ); atari_ntsc_rgb_t rgb = PACK_RGB( r, g, (b < 0x3E0 ? b: 0x3E0) );
@ -137,257 +112,100 @@ void atari_ntsc_init( atari_ntsc_t* ntsc, atari_ntsc_setup_t const* setup )
correct_errors( rgb, kernel ); correct_errors( rgb, kernel );
} }
} }
}
} }
#ifndef ATARI_NTSC_NO_BLITTERS void atari_ntsc_blit_rgb16( atari_ntsc_t const* ntsc, ATARI_NTSC_IN_T const* atari_in,
long in_row_width, int in_width, int in_height,
/* Atari change: no alternating burst phases - remove burst_phase parameter. void* rgb_out, long out_pitch )
Also removed the atari_ntsc_blit function and added specific blitters for various
pixel formats. */
#include <limits.h>
#if USHRT_MAX == 0xFFFF
typedef unsigned short atari_ntsc_out16_t;
#else
#error "Need 16-bit int type"
#endif
#if UINT_MAX == 0xFFFFFFFF
typedef unsigned int atari_ntsc_out32_t;
#elif ULONG_MAX == 0xFFFFFFFF
typedef unsigned long atari_ntsc_out32_t;
#else
#error "Need 32-bit int type"
#endif
void atari_ntsc_blit_rgb16( atari_ntsc_t const* ntsc, ATARI_NTSC_IN_T const* input, long in_row_width,
int in_width, int in_height, void* rgb_out, long out_pitch )
{ {
int chunk_count = (in_width - 1) / atari_ntsc_in_chunk; int const chunk_count = (in_width - 1) / atari_ntsc_in_chunk;
for ( ; in_height; --in_height ) while ( in_height-- )
{ {
ATARI_NTSC_IN_T const* line_in = input; ATARI_NTSC_IN_T const* line_in = atari_in;
/* Atari change: no alternating burst phases - remove burst_phase parameter; adjust to 4/7 pixel ratio. */ ATARI_NTSC_BEGIN_ROW( ntsc, atari_ntsc_black, ATARI_NTSC_ADJ_IN( *(line_in[0]) ) );
ATARI_NTSC_BEGIN_ROW( ntsc, atari_ntsc_out_t* restrict line_out = (atari_ntsc_out_t*) rgb_out;
atari_ntsc_black, atari_ntsc_black, atari_ntsc_black, ATARI_NTSC_ADJ_IN( *line_in ) );
atari_ntsc_out16_t* restrict line_out = (atari_ntsc_out16_t*) rgb_out;
int n; int n;
++line_in; ++line_in;
for ( n = chunk_count; n; --n ) for ( n = chunk_count; n; --n )
{ {
/* order of input and output pixels must not be altered */ /* order of input and output pixels must not be altered */
ATARI_NTSC_COLOR_IN( 0, ATARI_NTSC_ADJ_IN( line_in [0] ) ); ATARI_NTSC_COLOR_IN( 0, ntsc, ATARI_NTSC_ADJ_IN( *(line_in [0]) ) ); //CHANGED TO DEREFERENCE POINTER
ATARI_NTSC_RGB_OUT( 0, line_out [0], ATARI_NTSC_RGB_FORMAT_RGB16 ); ATARI_NTSC_RGB_OUT_RGB16( 0, line_out [0] );
ATARI_NTSC_RGB_OUT( 1, line_out [1], ATARI_NTSC_RGB_FORMAT_RGB16 ); ATARI_NTSC_RGB_OUT_RGB16( 1, line_out [1] );
ATARI_NTSC_RGB_OUT_RGB16( 2, line_out [2] );
ATARI_NTSC_RGB_OUT_RGB16( 3, line_out [3] );
ATARI_NTSC_COLOR_IN( 1, ATARI_NTSC_ADJ_IN( line_in [1] ) ); ATARI_NTSC_COLOR_IN( 1, ntsc, ATARI_NTSC_ADJ_IN( *(line_in [1]) ) ); //CHANGED TO DEREFERENCE POINTER
ATARI_NTSC_RGB_OUT( 2, line_out [2], ATARI_NTSC_RGB_FORMAT_RGB16 ); ATARI_NTSC_RGB_OUT_RGB16( 4, line_out [4] );
ATARI_NTSC_RGB_OUT( 3, line_out [3], ATARI_NTSC_RGB_FORMAT_RGB16 ); ATARI_NTSC_RGB_OUT_RGB16( 5, line_out [5] );
ATARI_NTSC_RGB_OUT_RGB16( 6, line_out [6] );
ATARI_NTSC_COLOR_IN( 2, ATARI_NTSC_ADJ_IN( line_in [2] ) ); line_in += 2;
ATARI_NTSC_RGB_OUT( 4, line_out [4], ATARI_NTSC_RGB_FORMAT_RGB16 );
ATARI_NTSC_RGB_OUT( 5, line_out [5], ATARI_NTSC_RGB_FORMAT_RGB16 );
ATARI_NTSC_COLOR_IN( 3, ATARI_NTSC_ADJ_IN( line_in [3] ) );
ATARI_NTSC_RGB_OUT( 6, line_out [6], ATARI_NTSC_RGB_FORMAT_RGB16 );
line_in += 4;
line_out += 7; line_out += 7;
} }
/* finish final pixels */ /* finish final pixels */
ATARI_NTSC_COLOR_IN( 0, atari_ntsc_black ); ATARI_NTSC_COLOR_IN( 0, ntsc, atari_ntsc_black );
ATARI_NTSC_RGB_OUT( 0, line_out [0], ATARI_NTSC_RGB_FORMAT_RGB16 ); ATARI_NTSC_RGB_OUT_RGB16( 0, line_out [0] );
ATARI_NTSC_RGB_OUT( 1, line_out [1], ATARI_NTSC_RGB_FORMAT_RGB16 ); ATARI_NTSC_RGB_OUT_RGB16( 1, line_out [1] );
ATARI_NTSC_RGB_OUT_RGB16( 2, line_out [2] );
ATARI_NTSC_RGB_OUT_RGB16( 3, line_out [3] );
ATARI_NTSC_COLOR_IN( 1, atari_ntsc_black ); ATARI_NTSC_COLOR_IN( 1, ntsc, atari_ntsc_black );
ATARI_NTSC_RGB_OUT( 2, line_out [2], ATARI_NTSC_RGB_FORMAT_RGB16 ); ATARI_NTSC_RGB_OUT_RGB16( 4, line_out [4] );
ATARI_NTSC_RGB_OUT( 3, line_out [3], ATARI_NTSC_RGB_FORMAT_RGB16 ); ATARI_NTSC_RGB_OUT_RGB16( 5, line_out [5] );
ATARI_NTSC_RGB_OUT_RGB16( 6, line_out [6] );
ATARI_NTSC_COLOR_IN( 2, atari_ntsc_black ); atari_in += in_row_width;
ATARI_NTSC_RGB_OUT( 4, line_out [4], ATARI_NTSC_RGB_FORMAT_RGB16 );
ATARI_NTSC_RGB_OUT( 5, line_out [5], ATARI_NTSC_RGB_FORMAT_RGB16 );
ATARI_NTSC_COLOR_IN( 3, atari_ntsc_black );
ATARI_NTSC_RGB_OUT( 6, line_out [6], ATARI_NTSC_RGB_FORMAT_RGB16 );
input += in_row_width;
rgb_out = (char*) rgb_out + out_pitch; rgb_out = (char*) rgb_out + out_pitch;
} }
} }
void atari_ntsc_blit_bgr16( atari_ntsc_t const* ntsc, ATARI_NTSC_IN_T const* input, long in_row_width, void atari_ntsc_blit_bgr16( atari_ntsc_t const* ntsc, ATARI_NTSC_IN_T const* atari_in,
int in_width, int in_height, void* rgb_out, long out_pitch ) long in_row_width, int in_width, int in_height,
void* rgb_out, long out_pitch )
{ {
int chunk_count = (in_width - 1) / atari_ntsc_in_chunk; int const chunk_count = (in_width - 1) / atari_ntsc_in_chunk;
for ( ; in_height; --in_height ) while ( in_height-- )
{ {
ATARI_NTSC_IN_T const* line_in = input; ATARI_NTSC_IN_T const* line_in = atari_in;
/* Atari change: no alternating burst phases - remove burst_phase parameter; adjust to 4/7 pixel ratio. */ ATARI_NTSC_BEGIN_ROW( ntsc, atari_ntsc_black, ATARI_NTSC_ADJ_IN( *(line_in[0]) ) );
ATARI_NTSC_BEGIN_ROW( ntsc, atari_ntsc_out_t* restrict line_out = (atari_ntsc_out_t*) rgb_out;
atari_ntsc_black, atari_ntsc_black, atari_ntsc_black, ATARI_NTSC_ADJ_IN( *line_in ) );
atari_ntsc_out16_t* restrict line_out = (atari_ntsc_out16_t*) rgb_out;
int n; int n;
++line_in; ++line_in;
for ( n = chunk_count; n; --n ) for ( n = chunk_count; n; --n )
{ {
/* order of input and output pixels must not be altered */ /* order of input and output pixels must not be altered */
ATARI_NTSC_COLOR_IN( 0, ATARI_NTSC_ADJ_IN( line_in [0] ) ); ATARI_NTSC_COLOR_IN( 0, ntsc, ATARI_NTSC_ADJ_IN( *(line_in [0]) ) ); //CHANGED TO DEREFERENCE POINTER
ATARI_NTSC_RGB_OUT( 0, line_out [0], ATARI_NTSC_RGB_FORMAT_BGR16 ); ATARI_NTSC_RGB_OUT_BGR16( 0, line_out [0] );
ATARI_NTSC_RGB_OUT( 1, line_out [1], ATARI_NTSC_RGB_FORMAT_BGR16 ); ATARI_NTSC_RGB_OUT_BGR16( 1, line_out [1] );
ATARI_NTSC_RGB_OUT_BGR16( 2, line_out [2] );
ATARI_NTSC_RGB_OUT_BGR16( 3, line_out [3] );
ATARI_NTSC_COLOR_IN( 1, ATARI_NTSC_ADJ_IN( line_in [1] ) ); ATARI_NTSC_COLOR_IN( 1, ntsc, ATARI_NTSC_ADJ_IN( *(line_in [1]) ) ); //CHANGED TO DEREFERENCE POINTER
ATARI_NTSC_RGB_OUT( 2, line_out [2], ATARI_NTSC_RGB_FORMAT_BGR16 ); ATARI_NTSC_RGB_OUT_BGR16( 4, line_out [4] );
ATARI_NTSC_RGB_OUT( 3, line_out [3], ATARI_NTSC_RGB_FORMAT_BGR16 ); ATARI_NTSC_RGB_OUT_BGR16( 5, line_out [5] );
ATARI_NTSC_RGB_OUT_BGR16( 6, line_out [6] );
ATARI_NTSC_COLOR_IN( 2, ATARI_NTSC_ADJ_IN( line_in [2] ) ); line_in += 2;
ATARI_NTSC_RGB_OUT( 4, line_out [4], ATARI_NTSC_RGB_FORMAT_BGR16 );
ATARI_NTSC_RGB_OUT( 5, line_out [5], ATARI_NTSC_RGB_FORMAT_BGR16 );
ATARI_NTSC_COLOR_IN( 3, ATARI_NTSC_ADJ_IN( line_in [3] ) );
ATARI_NTSC_RGB_OUT( 6, line_out [6], ATARI_NTSC_RGB_FORMAT_BGR16 );
line_in += 4;
line_out += 7; line_out += 7;
} }
/* finish final pixels */ /* finish final pixels */
ATARI_NTSC_COLOR_IN( 0, atari_ntsc_black ); ATARI_NTSC_COLOR_IN( 0, ntsc, atari_ntsc_black );
ATARI_NTSC_RGB_OUT( 0, line_out [0], ATARI_NTSC_RGB_FORMAT_BGR16 ); ATARI_NTSC_RGB_OUT_BGR16( 0, line_out [0] );
ATARI_NTSC_RGB_OUT( 1, line_out [1], ATARI_NTSC_RGB_FORMAT_BGR16 ); ATARI_NTSC_RGB_OUT_BGR16( 1, line_out [1] );
ATARI_NTSC_RGB_OUT_BGR16( 2, line_out [2] );
ATARI_NTSC_RGB_OUT_BGR16( 3, line_out [3] );
ATARI_NTSC_COLOR_IN( 1, atari_ntsc_black ); ATARI_NTSC_COLOR_IN( 1, ntsc, atari_ntsc_black );
ATARI_NTSC_RGB_OUT( 2, line_out [2], ATARI_NTSC_RGB_FORMAT_BGR16 ); ATARI_NTSC_RGB_OUT_BGR16( 4, line_out [4] );
ATARI_NTSC_RGB_OUT( 3, line_out [3], ATARI_NTSC_RGB_FORMAT_BGR16 ); ATARI_NTSC_RGB_OUT_BGR16( 5, line_out [5] );
ATARI_NTSC_RGB_OUT_BGR16( 6, line_out [6] );
ATARI_NTSC_COLOR_IN( 2, atari_ntsc_black ); atari_in += in_row_width;
ATARI_NTSC_RGB_OUT( 4, line_out [4], ATARI_NTSC_RGB_FORMAT_BGR16 );
ATARI_NTSC_RGB_OUT( 5, line_out [5], ATARI_NTSC_RGB_FORMAT_BGR16 );
ATARI_NTSC_COLOR_IN( 3, atari_ntsc_black );
ATARI_NTSC_RGB_OUT( 6, line_out [6], ATARI_NTSC_RGB_FORMAT_BGR16 );
input += in_row_width;
rgb_out = (char*) rgb_out + out_pitch; rgb_out = (char*) rgb_out + out_pitch;
} }
} }
void atari_ntsc_blit_argb32( atari_ntsc_t const* ntsc, ATARI_NTSC_IN_T const* input, long in_row_width,
int in_width, int in_height, void* rgb_out, long out_pitch )
{
int chunk_count = (in_width - 1) / atari_ntsc_in_chunk;
for ( ; in_height; --in_height )
{
ATARI_NTSC_IN_T const* line_in = input;
/* Atari change: no alternating burst phases - remove burst_phase parameter; adjust to 4/7 pixel ratio. */
ATARI_NTSC_BEGIN_ROW( ntsc,
atari_ntsc_black, atari_ntsc_black, atari_ntsc_black, ATARI_NTSC_ADJ_IN( *line_in ) );
atari_ntsc_out32_t* restrict line_out = (atari_ntsc_out32_t*) rgb_out;
int n;
++line_in;
for ( n = chunk_count; n; --n )
{
/* order of input and output pixels must not be altered */
ATARI_NTSC_COLOR_IN( 0, ATARI_NTSC_ADJ_IN( line_in [0] ) );
ATARI_NTSC_RGB_OUT( 0, line_out [0], ATARI_NTSC_RGB_FORMAT_ARGB32 );
ATARI_NTSC_RGB_OUT( 1, line_out [1], ATARI_NTSC_RGB_FORMAT_ARGB32 );
ATARI_NTSC_COLOR_IN( 1, ATARI_NTSC_ADJ_IN( line_in [1] ) );
ATARI_NTSC_RGB_OUT( 2, line_out [2], ATARI_NTSC_RGB_FORMAT_ARGB32 );
ATARI_NTSC_RGB_OUT( 3, line_out [3], ATARI_NTSC_RGB_FORMAT_ARGB32 );
ATARI_NTSC_COLOR_IN( 2, ATARI_NTSC_ADJ_IN( line_in [2] ) );
ATARI_NTSC_RGB_OUT( 4, line_out [4], ATARI_NTSC_RGB_FORMAT_ARGB32 );
ATARI_NTSC_RGB_OUT( 5, line_out [5], ATARI_NTSC_RGB_FORMAT_ARGB32 );
ATARI_NTSC_COLOR_IN( 3, ATARI_NTSC_ADJ_IN( line_in [3] ) );
ATARI_NTSC_RGB_OUT( 6, line_out [6], ATARI_NTSC_RGB_FORMAT_ARGB32 );
line_in += 4;
line_out += 7;
}
/* finish final pixels */
ATARI_NTSC_COLOR_IN( 0, atari_ntsc_black );
ATARI_NTSC_RGB_OUT( 0, line_out [0], ATARI_NTSC_RGB_FORMAT_ARGB32 );
ATARI_NTSC_RGB_OUT( 1, line_out [1], ATARI_NTSC_RGB_FORMAT_ARGB32 );
ATARI_NTSC_COLOR_IN( 1, atari_ntsc_black );
ATARI_NTSC_RGB_OUT( 2, line_out [2], ATARI_NTSC_RGB_FORMAT_ARGB32 );
ATARI_NTSC_RGB_OUT( 3, line_out [3], ATARI_NTSC_RGB_FORMAT_ARGB32 );
ATARI_NTSC_COLOR_IN( 2, atari_ntsc_black );
ATARI_NTSC_RGB_OUT( 4, line_out [4], ATARI_NTSC_RGB_FORMAT_ARGB32 );
ATARI_NTSC_RGB_OUT( 5, line_out [5], ATARI_NTSC_RGB_FORMAT_ARGB32 );
ATARI_NTSC_COLOR_IN( 3, atari_ntsc_black );
ATARI_NTSC_RGB_OUT( 6, line_out [6], ATARI_NTSC_RGB_FORMAT_ARGB32 );
input += in_row_width;
rgb_out = (char*) rgb_out + out_pitch;
}
}
void atari_ntsc_blit_bgra32( atari_ntsc_t const* ntsc, ATARI_NTSC_IN_T const* input, long in_row_width,
int in_width, int in_height, void* rgb_out, long out_pitch )
{
int chunk_count = (in_width - 1) / atari_ntsc_in_chunk;
for ( ; in_height; --in_height )
{
ATARI_NTSC_IN_T const* line_in = input;
/* Atari change: no alternating burst phases - remove burst_phase parameter; adjust to 4/7 pixel ratio. */
ATARI_NTSC_BEGIN_ROW( ntsc,
atari_ntsc_black, atari_ntsc_black, atari_ntsc_black, ATARI_NTSC_ADJ_IN( *line_in ) );
atari_ntsc_out32_t* restrict line_out = (atari_ntsc_out32_t*) rgb_out;
int n;
++line_in;
for ( n = chunk_count; n; --n )
{
/* order of input and output pixels must not be altered */
ATARI_NTSC_COLOR_IN( 0, ATARI_NTSC_ADJ_IN( line_in [0] ) );
ATARI_NTSC_RGB_OUT( 0, line_out [0], ATARI_NTSC_RGB_FORMAT_BGRA32 );
ATARI_NTSC_RGB_OUT( 1, line_out [1], ATARI_NTSC_RGB_FORMAT_BGRA32 );
ATARI_NTSC_COLOR_IN( 1, ATARI_NTSC_ADJ_IN( line_in [1] ) );
ATARI_NTSC_RGB_OUT( 2, line_out [2], ATARI_NTSC_RGB_FORMAT_BGRA32 );
ATARI_NTSC_RGB_OUT( 3, line_out [3], ATARI_NTSC_RGB_FORMAT_BGRA32 );
ATARI_NTSC_COLOR_IN( 2, ATARI_NTSC_ADJ_IN( line_in [2] ) );
ATARI_NTSC_RGB_OUT( 4, line_out [4], ATARI_NTSC_RGB_FORMAT_BGRA32 );
ATARI_NTSC_RGB_OUT( 5, line_out [5], ATARI_NTSC_RGB_FORMAT_BGRA32 );
ATARI_NTSC_COLOR_IN( 3, ATARI_NTSC_ADJ_IN( line_in [3] ) );
ATARI_NTSC_RGB_OUT( 6, line_out [6], ATARI_NTSC_RGB_FORMAT_BGRA32 );
line_in += 4;
line_out += 7;
}
/* finish final pixels */
ATARI_NTSC_COLOR_IN( 0, atari_ntsc_black );
ATARI_NTSC_RGB_OUT( 0, line_out [0], ATARI_NTSC_RGB_FORMAT_BGRA32 );
ATARI_NTSC_RGB_OUT( 1, line_out [1], ATARI_NTSC_RGB_FORMAT_BGRA32 );
ATARI_NTSC_COLOR_IN( 1, atari_ntsc_black );
ATARI_NTSC_RGB_OUT( 2, line_out [2], ATARI_NTSC_RGB_FORMAT_BGRA32 );
ATARI_NTSC_RGB_OUT( 3, line_out [3], ATARI_NTSC_RGB_FORMAT_BGRA32 );
ATARI_NTSC_COLOR_IN( 2, atari_ntsc_black );
ATARI_NTSC_RGB_OUT( 4, line_out [4], ATARI_NTSC_RGB_FORMAT_BGRA32 );
ATARI_NTSC_RGB_OUT( 5, line_out [5], ATARI_NTSC_RGB_FORMAT_BGRA32 );
ATARI_NTSC_COLOR_IN( 3, atari_ntsc_black );
ATARI_NTSC_RGB_OUT( 6, line_out [6], ATARI_NTSC_RGB_FORMAT_BGRA32 );
input += in_row_width;
rgb_out = (char*) rgb_out + out_pitch;
}
}
#endif

View File

@ -19,34 +19,23 @@
/* Atari TIA, CTIA, GTIA and MARIA NTSC video filter */ /* Atari TIA, CTIA, GTIA and MARIA NTSC video filter */
/* based on nes_ntsc 0.2.2 */
#ifndef ATARI_NTSC_H #ifndef ATARI_NTSC_H
#define ATARI_NTSC_H #define ATARI_NTSC_H
// The following come from "atari_ntsc_config.h", but since we'll eventually
// be using a custom blitter, most of the items will be redundant
//////////////////////////////////////////////////////////////////////////////
/* The following affect the built-in blitter only; a custom blitter can
handle things however it wants. */
/* Bits per pixel of output. Can be 15, 16, 32, or 24 (same as 32). */
#define ATARI_NTSC_OUT_DEPTH 16
/* Type of input pixel values. You'll probably use unsigned short
if you enable emphasis above. */
#define ATARI_NTSC_IN_T unsigned char
/* Each raw pixel input value is passed through this. You might want to mask
the pixel index if you use the high bits as flags, etc. */
#define ATARI_NTSC_ADJ_IN( in ) in
//////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* Type of input pixel values. You'll probably use unsigned short
if you enable emphasis above. */
#define ATARI_NTSC_IN_T unsigned char *
/* Each raw pixel input value is passed through this. You might want to mask
the pixel index if you use the high bits as flags, etc. */
#define ATARI_NTSC_ADJ_IN( in ) in
/* Image parameters, ranging from -1.0 to 1.0. Actual internal values shown /* Image parameters, ranging from -1.0 to 1.0. Actual internal values shown
in parenthesis and should remain fairly stable in future versions. */ in parenthesis and should remain fairly stable in future versions. */
typedef struct atari_ntsc_setup_t typedef struct atari_ntsc_setup_t
{ {
/* Basic parameters */ /* Basic parameters */
@ -72,45 +61,38 @@ typedef struct atari_ntsc_setup_t
double burst_phase; /* Phase at which colorburst signal is turned on; double burst_phase; /* Phase at which colorburst signal is turned on;
this defines colors of artifacts. this defines colors of artifacts.
In radians; -1.0 = -180 degrees, 1.0 = +180 degrees */ In radians; -1.0 = -180 degrees, 1.0 = +180 degrees */
double *yiq_palette; double* yiq_palette;
} atari_ntsc_setup_t; } atari_ntsc_setup_t;
/* Video format presets */ /* Video format presets */
extern atari_ntsc_setup_t const atari_ntsc_monochrome;/* desaturated + artifacts */
extern atari_ntsc_setup_t const atari_ntsc_composite; /* color bleeding + artifacts */ extern atari_ntsc_setup_t const atari_ntsc_composite; /* color bleeding + artifacts */
extern atari_ntsc_setup_t const atari_ntsc_svideo; /* color bleeding only */ extern atari_ntsc_setup_t const atari_ntsc_svideo; /* color bleeding only */
extern atari_ntsc_setup_t const atari_ntsc_rgb; /* crisp image */ extern atari_ntsc_setup_t const atari_ntsc_rgb; /* crisp image */
extern atari_ntsc_setup_t const atari_ntsc_monochrome;/* desaturated + artifacts */ extern atari_ntsc_setup_t const atari_ntsc_bad;
extern atari_ntsc_setup_t const atari_ntsc_horrible; /* desaturated + artifacts */
enum { atari_ntsc_palette_size = 128 }; enum { atari_ntsc_palette_size = 128 };
/* Initializes and adjusts parameters. Can be called multiple times on the same /* Initializes and adjusts parameters. Can be called multiple times on the same
atari_ntsc_t object. Can pass NULL for either parameter. */ atari_ntsc_t object. Can pass NULL for either parameter. */
typedef struct atari_ntsc_t atari_ntsc_t; typedef struct atari_ntsc_t atari_ntsc_t;
void atari_ntsc_init( atari_ntsc_t* ntsc, atari_ntsc_setup_t const* setup ); void atari_ntsc_init( atari_ntsc_t* ntsc, atari_ntsc_setup_t const* setup );
/* Filters one or more rows of pixels. Input pixels are 8-bit Atari palette colors. /* Filters one or more rows of pixels. Input pixels are 8-bit Atari palette colors.
In_row_width is the number of pixels to get to the next input row. Out_pitch In_row_width is the number of pixels to get to the next input row. Out_pitch
is the number of *bytes* to get to the next output row. Output pixel format is the number of *bytes* to get to the next output row. Output pixel format
is set by ATARI_NTSC_OUT_DEPTH (defaults to 16-bit RGB). */ is set by ATARI_NTSC_OUT_DEPTH (defaults to 16-bit RGB). */
/* Atari change: no alternating burst phases - remove burst_phase parameter.
Also removed the atari_ntsc_blit function and added specific blitters for various
pixel formats. */
void atari_ntsc_blit_rgb16( atari_ntsc_t const* ntsc, ATARI_NTSC_IN_T const* atari_in, void atari_ntsc_blit_rgb16( atari_ntsc_t const* ntsc, ATARI_NTSC_IN_T const* atari_in,
long in_row_width, int in_width, int in_height, long in_row_width, int in_width, int in_height,
void* rgb_out, long out_pitch ); void* rgb_out, long out_pitch );
void atari_ntsc_blit_bgr16( atari_ntsc_t const* ntsc, ATARI_NTSC_IN_T const* atari_in, void atari_ntsc_blit_bgr16( atari_ntsc_t const* ntsc, ATARI_NTSC_IN_T const* atari_in,
long in_row_width, int in_width, int in_height, long in_row_width, int in_width, int in_height,
void* rgb_out, long out_pitch ); void* rgb_out, long out_pitch );
void atari_ntsc_blit_argb32( atari_ntsc_t const* ntsc, ATARI_NTSC_IN_T const* atari_in,
long in_row_width, int in_width, int in_height,
void* rgb_out, long out_pitch );
void atari_ntsc_blit_bgra32( atari_ntsc_t const* ntsc, ATARI_NTSC_IN_T const* atari_in,
long in_row_width, int in_width, int in_height,
void* rgb_out, long out_pitch );
/* Number of output pixels written by blitter for given input width. Width might /* Number of output pixels written by blitter for given input width. Width might
be rounded down slightly; use ATARI_NTSC_IN_WIDTH() on result to find rounded be rounded down slightly; use ATARI_NTSC_IN_WIDTH() on result to find rounded
value. Guaranteed not to round 160 down at all. */ value. Guaranteed not to round 160 down at all. */
#define ATARI_NTSC_OUT_WIDTH( in_width ) \ #define ATARI_NTSC_OUT_WIDTH( in_width ) \
((((in_width) - 1) / atari_ntsc_in_chunk + 1)* atari_ntsc_out_chunk) ((((in_width) - 1) / atari_ntsc_in_chunk + 1)* atari_ntsc_out_chunk)
@ -126,85 +108,50 @@ value. */
enum { atari_ntsc_in_chunk = 2 }; /* number of input pixels read per chunk */ enum { atari_ntsc_in_chunk = 2 }; /* number of input pixels read per chunk */
enum { atari_ntsc_out_chunk = 7 }; /* number of output pixels generated per chunk */ enum { atari_ntsc_out_chunk = 7 }; /* number of output pixels generated per chunk */
enum { atari_ntsc_black = 0 }; /* palette index for black */ enum { atari_ntsc_black = 0 }; /* palette index for black */
enum { atari_ntsc_burst_count = 1 }; /* burst phase cycles through 0, 1, and 2 */
/* Begins outputting row and starts two pixels. First pixel will be cut off a bit. /* Begins outputting row and starts two pixels. First pixel will be cut off a bit.
Use atari_ntsc_black for unused pixels. Declares variables, so must be before first Use atari_ntsc_black for unused pixels. Declares variables, so must be before first
statement in a block (unless you're using C++). */ statement in a block (unless you're using C++). */
/* Atari change: no alternating burst phases; adapted to 4/7 pixel ratio. */ #define ATARI_NTSC_BEGIN_ROW( ntsc, pixel0, pixel1 ) \
#define ATARI_NTSC_BEGIN_ROW( ntsc, pixel0, pixel1, pixel2, pixel3 ) \ ATARI_NTSC_BEGIN_ROW_6_( pixel0, pixel1, ATARI_NTSC_ENTRY_, ntsc )
char const* const ktable = \
(char const*) (ntsc)->table [0];\
ATARI_NTSC_BEGIN_ROW_8_( pixel0, pixel1, pixel2, pixel3, ATARI_NTSC_ENTRY_, ktable )
/* Begins input pixel */ /* Begins input pixel */
#define ATARI_NTSC_COLOR_IN( in_index, color_in ) \ #define ATARI_NTSC_COLOR_IN( in_index, ntsc, color_in ) \
ATARI_NTSC_COLOR_IN_( in_index, color_in, ATARI_NTSC_ENTRY_, ktable ) ATARI_NTSC_COLOR_IN_( in_index, color_in, ATARI_NTSC_ENTRY_, ntsc )
/* Generates output pixel. Bits can be 24, 16, 15, 32 (treated as 24), or 0:
24: RRRRRRRR GGGGGGGG BBBBBBBB (8-8-8 RGB)
16: RRRRRGGG GGGBBBBB (5-6-5 RGB)
15: RRRRRGG GGGBBBBB (5-5-5 RGB)
0: xxxRRRRR RRRxxGGG GGGGGxxB BBBBBBBx (native internal format; x = junk bits) */
#define ATARI_NTSC_RGB_OUT( index, rgb_out, bits ) \
ATARI_NTSC_RGB_OUT_14_( index, rgb_out, bits, 0 )
/* Generates output pixel. Bits can be RGB16 or BGR16 */
#define ATARI_NTSC_RGB_OUT_RGB16( index, rgb_out ) {\
atari_ntsc_rgb_t raw_ =\
kernel0 [index ] + kernel1 [(index+10)%7+14] +\
kernelx0 [(index+7)%14] + kernelx1 [(index+ 3)%7+14+7];\
ATARI_NTSC_CLAMP_( raw_, 0 );\
rgb_out = (raw_>>(13)& 0xF800)|(raw_>>(8)&0x07E0)|(raw_>>(4)&0x001F);\
}
#define ATARI_NTSC_RGB_OUT_BGR16( index, rgb_out ) {\
atari_ntsc_rgb_t raw_ =\
kernel0 [index ] + kernel1 [(index+10)%7+14] +\
kernelx0 [(index+7)%14] + kernelx1 [(index+ 3)%7+14+7];\
ATARI_NTSC_CLAMP_( raw_, 0 );\
rgb_out = (raw_>>(13)& 0xF800)|(raw_>>(8)&0x07E0)|(raw_>>(4)&0x001F);\
}
/* private */ /* private */
enum { atari_ntsc_entry_size = 2 * 14 /* 56 */}; enum { atari_ntsc_entry_size = 2 * 14 };
typedef unsigned long atari_ntsc_rgb_t; typedef unsigned long atari_ntsc_rgb_t;
struct atari_ntsc_t { struct atari_ntsc_t {
atari_ntsc_rgb_t table [atari_ntsc_palette_size] [atari_ntsc_entry_size]; atari_ntsc_rgb_t table [atari_ntsc_palette_size] [atari_ntsc_entry_size];
}; };
enum { atari_ntsc_burst_size = atari_ntsc_entry_size / atari_ntsc_burst_count };
#define ATARI_NTSC_ENTRY_( ktable, n ) \ #define ATARI_NTSC_ENTRY_( ntsc, n ) (ntsc)->table [n >> 1 & 0x7F]
(atari_ntsc_rgb_t const*) (ktable + (n) * (atari_ntsc_entry_size * sizeof (atari_ntsc_rgb_t)))
/* deprecated */ /* common 3->7 ntsc macros */
#define ATARI_NTSC_RGB24_OUT( x, out ) ATARI_NTSC_RGB_OUT( x, out, 24 ) #define ATARI_NTSC_BEGIN_ROW_6_( pixel0, pixel1, ENTRY, table ) \
#define ATARI_NTSC_RGB16_OUT( x, out ) ATARI_NTSC_RGB_OUT( x, out, 16 )
#define ATARI_NTSC_RGB15_OUT( x, out ) ATARI_NTSC_RGB_OUT( x, out, 15 )
#define ATARI_NTSC_RAW_OUT( x, out ) ATARI_NTSC_RGB_OUT( x, out, 0 )
enum { atari_ntsc_min_in_width = 320 }; /* minimum width that doesn't cut off active area */
enum { atari_ntsc_min_out_width = ATARI_NTSC_OUT_WIDTH( atari_ntsc_min_in_width ) };
enum { atari_ntsc_640_in_width = 336 }; /* room for 8-pixel left & right overscan borders */
enum { atari_ntsc_640_out_width = ATARI_NTSC_OUT_WIDTH( atari_ntsc_640_in_width ) };
enum { atari_ntsc_640_overscan_left = 8 };
enum { atari_ntsc_640_overscan_right = atari_ntsc_640_in_width - atari_ntsc_min_in_width - atari_ntsc_640_overscan_left };
enum { atari_ntsc_full_in_width = 384 }; /* room for full overscan */
enum { atari_ntsc_full_out_width = ATARI_NTSC_OUT_WIDTH( atari_ntsc_full_in_width ) };
enum { atari_ntsc_full_overscan_left = 32 };
enum { atari_ntsc_full_overscan_right = atari_ntsc_full_in_width - atari_ntsc_min_in_width - atari_ntsc_full_overscan_left };
/* common 4->7 ntsc macros */
/* Atari change: adapted to 4/7 pixel ratio. */
#define ATARI_NTSC_BEGIN_ROW_8_( pixel0, pixel1, pixel2, pixel3, ENTRY, table ) \
unsigned const atari_ntsc_pixel0_ = (pixel0);\ unsigned const atari_ntsc_pixel0_ = (pixel0);\
atari_ntsc_rgb_t const* kernel0 = ENTRY( table, atari_ntsc_pixel0_ );\ atari_ntsc_rgb_t const* kernel0 = ENTRY( table, atari_ntsc_pixel0_ );\
unsigned const atari_ntsc_pixel1_ = (pixel1);\ unsigned const atari_ntsc_pixel1_ = (pixel1);\
atari_ntsc_rgb_t const* kernel1 = ENTRY( table, atari_ntsc_pixel1_ );\ atari_ntsc_rgb_t const* kernel1 = ENTRY( table, atari_ntsc_pixel1_ );\
unsigned const atari_ntsc_pixel2_ = (pixel2);\
atari_ntsc_rgb_t const* kernel2 = ENTRY( table, atari_ntsc_pixel2_ );\
unsigned const atari_ntsc_pixel3_ = (pixel3);\
atari_ntsc_rgb_t const* kernel3 = ENTRY( table, atari_ntsc_pixel3_ );\
atari_ntsc_rgb_t const* kernelx0;\ atari_ntsc_rgb_t const* kernelx0;\
atari_ntsc_rgb_t const* kernelx1 = kernel0;\ atari_ntsc_rgb_t const* kernelx1 = kernel0
atari_ntsc_rgb_t const* kernelx2 = kernel0;\
atari_ntsc_rgb_t const* kernelx3 = kernel0
/* Atari change: adapted to 4/7 pixel ratio. */
#define ATARI_NTSC_RGB_OUT_14_( x, rgb_out, bits, shift ) {\
atari_ntsc_rgb_t raw_ =\
kernel0 [x ] + kernel1 [(x+5)%7+14] + kernel2 [(x+3)%7+28] + kernel3 [(x+1)%7+42] +\
kernelx0 [(x+7)%14] + kernelx1 [(x+5)%7+21] + kernelx2 [(x+3)%7+35] + kernelx3 [(x+1)%7+49];\
ATARI_NTSC_CLAMP_( raw_, shift );\
ATARI_NTSC_RGB_OUT_( rgb_out, bits, shift );\
}
/* common ntsc macros */ /* common ntsc macros */
#define atari_ntsc_rgb_builder ((1L << 21) | (1 << 11) | (1 << 1)) #define atari_ntsc_rgb_builder ((1L << 21) | (1 << 11) | (1 << 1))
@ -224,34 +171,6 @@ enum { atari_ntsc_full_overscan_right = atari_ntsc_full_in_width - atari_ntsc_mi
kernel##index = (color_ = (color), ENTRY( table, color_ ));\ kernel##index = (color_ = (color), ENTRY( table, color_ ));\
} }
/* Atari change: modified ATARI_NTSC_RGB_OUT_ so its BITS parameter is
no longer a straight number of bits, but an enumerated value. Then
added a few additional bit formats. Also added the ATARI_NTSC_RGB_FORMAT
enumerated values. */
enum {
ATARI_NTSC_RGB_FORMAT_RGB16,
ATARI_NTSC_RGB_FORMAT_BGR16,
ATARI_NTSC_RGB_FORMAT_ARGB32,
ATARI_NTSC_RGB_FORMAT_BGRA32,
ATARI_NTSC_RGB_FORMAT_RGB15
};
/* x is always zero except in snes_ntsc library */
#define ATARI_NTSC_RGB_OUT_( rgb_out, bits, x ) {\
if ( bits == ATARI_NTSC_RGB_FORMAT_RGB16 )\
rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\
else if ( bits == ATARI_NTSC_RGB_FORMAT_BGR16 )\
rgb_out = (raw_>>(24-x)& 0x001F)|(raw_>>(8-x)&0x07E0)|(raw_<<(7+x)&0xF800);\
else if ( bits == ATARI_NTSC_RGB_FORMAT_ARGB32 )\
rgb_out = (raw_>>(5-x)&0xFF0000)|(raw_>>(3-x)&0xFF00)|(raw_>>(1-x)&0xFF) | 0xFF000000;\
else if ( bits == ATARI_NTSC_RGB_FORMAT_BGRA32 )\
rgb_out = (raw_>>(13-x)&0xFF00)|(raw_<<(5+x)&0xFF0000)|(raw_<<(23+x)&0xFF000000) | 0xFF;\
else if ( bits == ATARI_NTSC_RGB_FORMAT_RGB15 )\
rgb_out = (raw_>>(14-x)& 0x7C00)|(raw_>>(9-x)&0x03E0)|(raw_>>(4-x)&0x001F);\
else if ( bits == 0 )\
rgb_out = raw_ << x;\
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -26,7 +26,7 @@
#include "bspf.hxx" #include "bspf.hxx"
/* Copyright (C) 2006 Shay Green. This module is free software; you /* Copyright (C) 2006-2009 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This version 2.1 of the License, or (at your option) any later version. This
@ -37,7 +37,9 @@ details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation, License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#define DISABLE_CORRECTION 0 #ifndef DISABLE_CORRECTION
#define DISABLE_CORRECTION 0
#endif
#undef PI #undef PI
#define PI 3.14159265358979323846f #define PI 3.14159265358979323846f
@ -316,7 +318,9 @@ static void init( init_t* impl, atari_ntsc_setup_t const* setup )
(type) (y + to_rgb [4] * i + to_rgb [5] * q)\ (type) (y + to_rgb [4] * i + to_rgb [5] * q)\
) )
#define PACK_RGB( r, g, b ) ((r) << 21 | (g) << 11 | (b) << 1) #ifndef PACK_RGB
#define PACK_RGB( r, g, b ) ((r) << 21 | (g) << 11 | (b) << 1)
#endif
enum { rgb_kernel_size = burst_size / alignment_count }; enum { rgb_kernel_size = burst_size / alignment_count };
enum { rgb_bias = rgb_unit * 2 * atari_ntsc_rgb_builder }; enum { rgb_bias = rgb_unit * 2 * atari_ntsc_rgb_builder };