First pass at converting Blarrg code to proper C++. This mostly involves getting rid of macros.

This commit is contained in:
Stephen Anthony 2019-12-25 20:39:04 -03:30
parent 9813173841
commit e09634cb56
4 changed files with 114 additions and 106 deletions

View File

@ -43,14 +43,13 @@ void AtariNTSC::initializePalette(const uInt8* palette)
// Palette stores R/G/B data for 'palette_size' entries // Palette stores R/G/B data for 'palette_size' entries
for ( uInt32 entry = 0; entry < palette_size; ++entry ) for ( uInt32 entry = 0; entry < palette_size; ++entry )
{ {
float r = myImpl.to_float [*palette++]; float r = myImpl.to_float [*palette++],
float g = myImpl.to_float [*palette++]; g = myImpl.to_float [*palette++],
float b = myImpl.to_float [*palette++]; b = myImpl.to_float [*palette++];
float y, i, q; RGB_TO_YIQ( r, g, b, y, i, q );
float y, i, q = RGB_TO_YIQ( r, g, b, y, i );
// Generate kernel // Generate kernel
int ir, ig, ib = YIQ_TO_RGB( y, i, q, myImpl.to_rgb, int, ir, ig ); int ir, ig, ib; YIQ_TO_RGB( y, i, q, myImpl.to_rgb.data(), ir, ig, ib );
uInt32 rgb = PACK_RGB( ir, ig, ib ); uInt32 rgb = PACK_RGB( ir, ig, ib );
uInt32* kernel = myColorTable[entry]; uInt32* kernel = myColorTable[entry];
@ -77,7 +76,7 @@ void AtariNTSC::enableThreading(bool enable)
} }
else else
{ {
systemThreads = std::max(1u, std::min(4u, systemThreads - 1)); systemThreads = std::max<uInt32>(1, std::min<uInt32>(4, systemThreads - 1));
myWorkerThreads = systemThreads - 1; myWorkerThreads = systemThreads - 1;
myTotalThreads = systemThreads; myTotalThreads = systemThreads;
@ -306,15 +305,14 @@ void AtariNTSC::renderWithPhosphorThread(const uInt8* atari_in, const uInt32 in_
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inline uInt32 AtariNTSC::getRGBPhosphor(const uInt32 c, const uInt32 p) const inline uInt32 AtariNTSC::getRGBPhosphor(const uInt32 c, const uInt32 p) const
{ {
#define TO_RGB(color, red, green, blue) \
const uInt8 red = uInt8(color >> 16); \
const uInt8 green = uInt8(color >> 8);\
const uInt8 blue = uInt8(color);
TO_RGB(c, rc, gc, bc)
TO_RGB(p, rp, gp, bp)
// Mix current calculated frame with previous displayed frame // Mix current calculated frame with previous displayed frame
const uInt8 rc = uInt8(c >> 16);
const uInt8 gc = uInt8(c >> 8);
const uInt8 bc = uInt8(c);
const uInt8 rp = uInt8(p >> 16);
const uInt8 gp = uInt8(p >> 8);
const uInt8 bp = uInt8(p);
const uInt8 rn = myPhosphorPalette[rc][rp]; const uInt8 rn = myPhosphorPalette[rc][rp];
const uInt8 gn = myPhosphorPalette[gc][gp]; const uInt8 gn = myPhosphorPalette[gc][gp];
const uInt8 bn = myPhosphorPalette[bc][bp]; const uInt8 bn = myPhosphorPalette[bc][bp];
@ -325,8 +323,8 @@ inline uInt32 AtariNTSC::getRGBPhosphor(const uInt32 c, const uInt32 p) const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AtariNTSC::init(init_t& impl, const Setup& setup) void AtariNTSC::init(init_t& impl, const Setup& setup)
{ {
impl.brightness = setup.brightness * (0.5f * rgb_unit) + rgb_offset; impl.brightness = setup.brightness * (0.5F * rgb_unit) + rgb_offset;
impl.contrast = setup.contrast * (0.5f * rgb_unit) + rgb_unit; impl.contrast = setup.contrast * (0.5F * rgb_unit) + rgb_unit;
impl.artifacts = setup.artifacts; impl.artifacts = setup.artifacts;
if ( impl.artifacts > 0 ) if ( impl.artifacts > 0 )
@ -343,8 +341,8 @@ void AtariNTSC::init(init_t& impl, const Setup& setup)
/* generate gamma table */ /* generate gamma table */
if (true) /* was (gamma_size > 1) */ if (true) /* was (gamma_size > 1) */
{ {
float const to_float = 1.0f / (gamma_size - 1/*(gamma_size > 1)*/); float const to_float = 1.F / (gamma_size - 1/*(gamma_size > 1)*/);
float const gamma = 1.1333f - setup.gamma * 0.5f; float const gamma = 1.1333F - setup.gamma * 0.5F;
/* match common PC's 2.2 gamma to TV's 2.65 gamma */ /* match common PC's 2.2 gamma to TV's 2.65 gamma */
int i; int i;
for ( i = 0; i < gamma_size; i++ ) for ( i = 0; i < gamma_size; i++ )
@ -360,13 +358,13 @@ void AtariNTSC::init(init_t& impl, const Setup& setup)
float s = sinf( hue ) * sat; float s = sinf( hue ) * sat;
float c = cosf( hue ) * sat; float c = cosf( hue ) * sat;
float* out = impl.to_rgb; float* out = impl.to_rgb.data();
int n; int n;
n = burst_count; n = burst_count;
do do
{ {
float const* in = default_decoder; float const* in = default_decoder.data();
int n2 = 3; int n2 = 3;
do do
{ {
@ -378,7 +376,7 @@ void AtariNTSC::init(init_t& impl, const Setup& setup)
while ( --n2 ); while ( --n2 );
#if 0 // burst_count is always 0 #if 0 // burst_count is always 0
if ( burst_count > 1 ) if ( burst_count > 1 )
ROTATE_IQ( s, c, 0.866025f, -0.5f ); /* +120 degrees */ ROTATE_IQ( s, c, 0.866025F, -0.5F ); /* +120 degrees */
#endif #endif
} }
while ( --n ); while ( --n );
@ -388,18 +386,18 @@ void AtariNTSC::init(init_t& impl, const Setup& setup)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AtariNTSC::initFilters(init_t& impl, const Setup& setup) void AtariNTSC::initFilters(init_t& impl, const Setup& setup)
{ {
float kernels [kernel_size * 2]; std::array<float, kernel_size * 2> kernels;
/* generate luma (y) filter using sinc kernel */ /* generate luma (y) filter using sinc kernel */
{ {
/* sinc with rolloff (dsf) */ /* sinc with rolloff (dsf) */
float const rolloff = 1 + setup.sharpness * 0.032f; float const rolloff = 1 + setup.sharpness * 0.032F;
constexpr float maxh = 32; constexpr float maxh = 32;
float const pow_a_n = powf( rolloff, maxh ); float const pow_a_n = powf( rolloff, maxh );
float sum; float sum;
/* quadratic mapping to reduce negative (blurring) range */ /* quadratic mapping to reduce negative (blurring) range */
float to_angle = setup.resolution + 1; float to_angle = setup.resolution + 1;
to_angle = BSPF::PI_f / maxh * LUMA_CUTOFF * (to_angle * to_angle + 1.f); to_angle = BSPF::PI_f / maxh * luma_cutoff * (to_angle * to_angle + 1.f);
kernels [kernel_size * 3 / 2] = maxh; /* default center value */ kernels [kernel_size * 3 / 2] = maxh; /* default center value */
for ( int i = 0; i < kernel_half * 2 + 1; i++ ) for ( int i = 0; i < kernel_half * 2 + 1; i++ )
@ -407,7 +405,7 @@ void AtariNTSC::initFilters(init_t& impl, const Setup& setup)
int x = i - kernel_half; int x = i - kernel_half;
float angle = x * to_angle; float angle = x * to_angle;
/* instability occurs at center point with rolloff very close to 1.0 */ /* instability occurs at center point with rolloff very close to 1.0 */
if ( x || pow_a_n > 1.056f || pow_a_n < 0.981f ) if ( x || pow_a_n > 1.056F || pow_a_n < 0.981F )
{ {
float rolloff_cos_a = rolloff * cosf( angle ); float rolloff_cos_a = rolloff * cosf( angle );
float num = 1 - rolloff_cos_a - float num = 1 - rolloff_cos_a -
@ -415,7 +413,7 @@ void AtariNTSC::initFilters(init_t& impl, const Setup& setup)
pow_a_n * rolloff * cosf( (maxh - 1) * angle ); pow_a_n * rolloff * cosf( (maxh - 1) * angle );
float den = 1 - rolloff_cos_a - rolloff_cos_a + rolloff * rolloff; float den = 1 - rolloff_cos_a - rolloff_cos_a + rolloff * rolloff;
float dsf = num / den; float dsf = num / den;
kernels [kernel_size * 3 / 2 - kernel_half + i] = dsf - 0.5f; kernels [kernel_size * 3 / 2 - kernel_half + i] = dsf - 0.5F;
} }
} }
@ -424,12 +422,12 @@ void AtariNTSC::initFilters(init_t& impl, const Setup& setup)
for ( int i = 0; i < kernel_half * 2 + 1; i++ ) for ( int i = 0; i < kernel_half * 2 + 1; i++ )
{ {
float x = BSPF::PI_f * 2 / (kernel_half * 2) * i; float x = BSPF::PI_f * 2 / (kernel_half * 2) * i;
float blackman = 0.42f - 0.5f * cosf( x ) + 0.08f * cosf( x * 2 ); float blackman = 0.42F - 0.5F * cosf( x ) + 0.08F * cosf( x * 2 );
sum += (kernels [kernel_size * 3 / 2 - kernel_half + i] *= blackman); sum += (kernels [kernel_size * 3 / 2 - kernel_half + i] *= blackman);
} }
/* normalize kernel */ /* normalize kernel */
sum = 1.0f / sum; sum = 1.0F / sum;
for ( int i = 0; i < kernel_half * 2 + 1; i++ ) for ( int i = 0; i < kernel_half * 2 + 1; i++ )
{ {
int x = kernel_size * 3 / 2 - kernel_half + i; int x = kernel_size * 3 / 2 - kernel_half + i;
@ -439,7 +437,7 @@ void AtariNTSC::initFilters(init_t& impl, const Setup& setup)
/* generate chroma (iq) filter using gaussian kernel */ /* generate chroma (iq) filter using gaussian kernel */
{ {
constexpr float cutoff_factor = -0.03125f; constexpr float cutoff_factor = -0.03125F;
float cutoff = setup.bleed; float cutoff = setup.bleed;
if ( cutoff < 0 ) if ( cutoff < 0 )
@ -448,9 +446,9 @@ void AtariNTSC::initFilters(init_t& impl, const Setup& setup)
cutoff *= cutoff; cutoff *= cutoff;
cutoff *= cutoff; cutoff *= cutoff;
cutoff *= cutoff; cutoff *= cutoff;
cutoff *= -30.0f / 0.65f; cutoff *= -30.0F / 0.65F;
} }
cutoff = cutoff_factor - 0.65f * cutoff_factor * cutoff; cutoff = cutoff_factor - 0.65F * cutoff_factor * cutoff;
for ( int i = -kernel_half; i <= kernel_half; i++ ) for ( int i = -kernel_half; i <= kernel_half; i++ )
kernels [kernel_size / 2 + i] = expf( i * i * cutoff ); kernels [kernel_size / 2 + i] = expf( i * i * cutoff );
@ -463,7 +461,7 @@ void AtariNTSC::initFilters(init_t& impl, const Setup& setup)
for ( x = i; x < kernel_size; x += 2 ) for ( x = i; x < kernel_size; x += 2 )
sum += kernels [x]; sum += kernels [x];
sum = 1.0f / sum; sum = 1.0F / sum;
for ( x = i; x < kernel_size; x += 2 ) for ( x = i; x < kernel_size; x += 2 )
{ {
kernels [x] *= sum; kernels [x] *= sum;
@ -472,13 +470,13 @@ void AtariNTSC::initFilters(init_t& impl, const Setup& setup)
} }
/* generate linear rescale kernels */ /* generate linear rescale kernels */
float weight = 1.0f; float weight = 1.0F;
float* out = impl.kernel; float* out = impl.kernel.data();
int n = rescale_out; int n = rescale_out;
do do
{ {
float remain = 0; float remain = 0;
weight -= 1.0f / rescale_in; weight -= 1.0F / rescale_in;
for ( int i = 0; i < kernel_size * 2; i++ ) for ( int i = 0; i < kernel_size * 2; i++ )
{ {
float cur = kernels [i]; float cur = kernels [i];
@ -495,7 +493,7 @@ void AtariNTSC::initFilters(init_t& impl, const Setup& setup)
void AtariNTSC::genKernel(init_t& impl, float y, float i, float q, uInt32* out) void AtariNTSC::genKernel(init_t& impl, float y, float i, float q, uInt32* out)
{ {
/* generate for each scanline burst phase */ /* generate for each scanline burst phase */
float const* to_rgb = impl.to_rgb; float const* to_rgb = impl.to_rgb.data();
int burst_remain = burst_count; int burst_remain = burst_count;
y -= rgb_offset; y -= rgb_offset;
do do
@ -504,7 +502,7 @@ void AtariNTSC::genKernel(init_t& impl, float y, float i, float q, uInt32* out)
Convolve these with kernels which: filter respective components, apply Convolve these with kernels which: filter respective components, apply
sharpening, and rescale horizontally. Convert resulting yiq to rgb and pack sharpening, and rescale horizontally. Convert resulting yiq to rgb and pack
into integer. Based on algorithm by NewRisingSun. */ into integer. Based on algorithm by NewRisingSun. */
pixel_info_t const* pixel = atari_ntsc_pixels; pixel_info_t const* pixel = atari_ntsc_pixels.data();
int alignment_remain = alignment_count; int alignment_remain = alignment_count;
do do
{ {
@ -538,7 +536,7 @@ void AtariNTSC::genKernel(init_t& impl, float y, float i, float q, uInt32* out)
else else
k -= kernel_size * 2 * (rescale_out - 1) + 2; k -= kernel_size * 2 * (rescale_out - 1) + 2;
{ {
int r, g, b = YIQ_TO_RGB( fy, fi, fq, to_rgb, int, r, g ); int r, g, b; YIQ_TO_RGB( fy, fi, fq, to_rgb, r, g, b );
*out++ = PACK_RGB( r, g, b ) - rgb_bias; *out++ = PACK_RGB( r, g, b ) - rgb_bias;
} }
} }
@ -550,24 +548,26 @@ void AtariNTSC::genKernel(init_t& impl, float y, float i, float q, uInt32* out)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const AtariNTSC::Setup AtariNTSC::TV_Composite = { const AtariNTSC::Setup AtariNTSC::TV_Composite = {
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.15f, 0.0f, 0.0f, 0.0f 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.15F, 0.0F, 0.0F, 0.0F
}; };
const AtariNTSC::Setup AtariNTSC::TV_SVideo = { const AtariNTSC::Setup AtariNTSC::TV_SVideo = {
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.45f, -1.0f, -1.0f, 0.0f 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.45F, -1.0F, -1.0F, 0.0F
}; };
const AtariNTSC::Setup AtariNTSC::TV_RGB = { const AtariNTSC::Setup AtariNTSC::TV_RGB = {
0.0f, 0.0f, 0.0f, 0.0f, 0.2f, 0.0f, 0.70f, -1.0f, -1.0f, -1.0f 0.0F, 0.0F, 0.0F, 0.0F, 0.2F, 0.0F, 0.70F, -1.0F, -1.0F, -1.0F
}; };
const AtariNTSC::Setup AtariNTSC::TV_Bad = { const AtariNTSC::Setup AtariNTSC::TV_Bad = {
0.1f, -0.3f, 0.3f, 0.25f, 0.2f, 0.0f, 0.1f, 0.5f, 0.5f, 0.5f 0.1F, -0.3F, 0.3F, 0.25F, 0.2F, 0.0F, 0.1F, 0.5F, 0.5F, 0.5F
}; };
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const AtariNTSC::pixel_info_t AtariNTSC::atari_ntsc_pixels[alignment_count] = { const std::array<AtariNTSC::pixel_info_t, AtariNTSC::alignment_count>
{ PIXEL_OFFSET( -4, -9 ), { 1, 1, 1, 1 } }, AtariNTSC::atari_ntsc_pixels = { {
{ PIXEL_OFFSET( 0, -5 ), { 1, 1, 1, 1 } }, { PIXEL_OFFSET1(-4, -9), PIXEL_OFFSET2(-4), { 1, 1, 1, 1 } },
}; { PIXEL_OFFSET1( 0, -5), PIXEL_OFFSET2( 0), { 1, 1, 1, 1 } }
} };
const float AtariNTSC::default_decoder[6] = { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0.9563f, 0.6210f, -0.2721f, -0.6474f, -1.1070f, 1.7046f const std::array<float, 6> AtariNTSC::default_decoder = {
0.9563F, 0.6210F, -0.2721F, -0.6474F, -1.1070F, 1.7046F
}; };

View File

@ -151,16 +151,20 @@ class AtariNTSC
rgb_bias = rgb_unit * 2 * rgb_builder, rgb_bias = rgb_unit * 2 * rgb_builder,
std_decoder_hue = 0, std_decoder_hue = 0,
ext_decoder_hue = std_decoder_hue + 15 ext_decoder_hue = std_decoder_hue + 15,
atari_ntsc_clamp_mask = rgb_builder * 3 / 2,
atari_ntsc_clamp_add = rgb_builder * 0x101
; ;
#define artifacts_mid 1.5f static constexpr float
#define artifacts_max 2.5f artifacts_mid = 1.5F,
#define fringing_mid 1.0f artifacts_max = 2.5F,
#define fringing_max 2.0f fringing_mid = 1.0F,
#define rgb_offset (rgb_unit * 2 + 0.5f) fringing_max = 2.0F,
rgb_offset = (rgb_unit * 2 + 0.5F),
#define LUMA_CUTOFF 0.20f luma_cutoff = 0.20F
;
uInt32 myColorTable[palette_size][entry_size]; uInt32 myColorTable[palette_size][entry_size];
uInt8 myPhosphorPalette[256][256]; uInt8 myPhosphorPalette[256][256];
@ -172,18 +176,18 @@ class AtariNTSC
struct init_t struct init_t
{ {
float to_rgb [burst_count * 6]; std::array<float, burst_count * 6> to_rgb;
float to_float [gamma_size]; std::array<float, gamma_size> to_float;
float contrast; float contrast;
float brightness; float brightness;
float artifacts; float artifacts;
float fringing; float fringing;
float kernel [rescale_out * kernel_size * 2]; std::array<float, rescale_out * kernel_size * 2> kernel;
init_t() : contrast(0.0), brightness(0.0), artifacts(0.0), fringing(0.0) { init_t() : contrast(0.0), brightness(0.0), artifacts(0.0), fringing(0.0) {
std::fill(to_rgb, to_rgb + burst_count * 6, 0.0); to_rgb.fill(0.0);
std::fill(to_float, to_float + gamma_size, 0.0); to_float.fill(0.0);
std::fill(kernel, kernel + rescale_out * kernel_size * 2, 0.0); kernel.fill(0.0);
} }
}; };
init_t myImpl; init_t myImpl;
@ -192,11 +196,11 @@ class AtariNTSC
{ {
int offset; int offset;
float negate; float negate;
float kernel [4]; std::array<float, 4> kernel;
}; };
static const pixel_info_t atari_ntsc_pixels[alignment_count]; static const std::array<pixel_info_t, alignment_count> atari_ntsc_pixels;
static const float default_decoder[6]; static const std::array<float, 6> default_decoder;
void init(init_t& impl, const Setup& setup); void init(init_t& impl, const Setup& setup);
void initFilters(init_t& impl, const Setup& setup); void initFilters(init_t& impl, const Setup& setup);
@ -220,57 +224,60 @@ class AtariNTSC
kernel##index = (color_ = (color), myColorTable[color_]);\ kernel##index = (color_ = (color), myColorTable[color_]);\
} }
// Generates output in the specified 32-bit format (x = junk bits). // Generates output in the specified 32-bit format.
// native: xxxRRRRR RRRxxGGG GGGGGxxB BBBBBBBx (native internal format)
// 8888: 00000000 RRRRRRRR GGGGGGGG BBBBBBBB (8-8-8-8 32-bit ARGB) // 8888: 00000000 RRRRRRRR GGGGGGGG BBBBBBBB (8-8-8-8 32-bit ARGB)
#define ATARI_NTSC_RGB_OUT_8888( index, rgb_out ) {\ #define ATARI_NTSC_RGB_OUT_8888( index, rgb_out ) {\
uInt32 raw_ =\ uInt32 raw_ =\
kernel0 [index ] + kernel1 [(index+10)%7+14] +\ kernel0 [index ] + kernel1 [(index+10)%7+14] +\
kernelx0 [(index+7)%14] + kernelx1 [(index+ 3)%7+14+7];\ kernelx0 [(index+7)%14] + kernelx1 [(index+ 3)%7+14+7];\
ATARI_NTSC_CLAMP_( raw_, 0 );\ ATARI_NTSC_CLAMP( raw_, 0 );\
rgb_out = (raw_>>5 & 0x00FF0000)|(raw_>>3 & 0x0000FF00)|(raw_>>1 & 0x000000FF);\ rgb_out = (raw_>>5 & 0x00FF0000)|(raw_>>3 & 0x0000FF00)|(raw_>>1 & 0x000000FF);\
} }
// Common ntsc macros // Common ntsc macros
#define atari_ntsc_clamp_mask (rgb_builder * 3 / 2) static inline constexpr void ATARI_NTSC_CLAMP( uInt32& io, uInt32 shift ) {
#define atari_ntsc_clamp_add (rgb_builder * 0x101) uInt32 sub = io >> (9-(shift)) & atari_ntsc_clamp_mask;
#define ATARI_NTSC_CLAMP_( io, shift ) {\ uInt32 clamp = atari_ntsc_clamp_add - sub;
uInt32 sub = (io) >> (9-(shift)) & atari_ntsc_clamp_mask;\ io |= clamp;
uInt32 clamp = atari_ntsc_clamp_add - sub;\ clamp -= sub;
io |= clamp;\ io &= clamp;
clamp -= sub;\
io &= clamp;\
} }
// Kernel generation static inline constexpr void RGB_TO_YIQ(float r, float g, float b,
float& y, float& i, float& q) {
y = r * 0.299F + g * 0.587F + b * 0.114F;
i = r * 0.595716F - g * 0.274453F - b * 0.321263F;
q = r * 0.211456F - g * 0.522591F + b * 0.311135F;
}
static inline constexpr void YIQ_TO_RGB(float y, float i, float q,
const float* to_rgb, int& ir, int& ig, int& ib) {
ir = static_cast<int>(y + to_rgb[0] * i + to_rgb[1] * q);
ig = static_cast<int>(y + to_rgb[2] * i + to_rgb[3] * q);
ib = static_cast<int>(y + to_rgb[4] * i + to_rgb[5] * q);
}
static inline constexpr uInt32 PACK_RGB( int r, int g, int b ) {
return r << 21 | g << 11 | b << 1;
}
// Converted from C-style macros; I don't even pretend to understand the logic here :)
static inline constexpr int PIXEL_OFFSET1( int ntsc, int scaled ) {
return (kernel_size / 2 + ((ntsc) - (scaled) / rescale_out * rescale_in) +
((((scaled) + rescale_out * 10) % rescale_out) != 0) +
(rescale_out - (((scaled) + rescale_out * 10) % rescale_out)) % rescale_out +
(kernel_size * 2 * (((scaled) + rescale_out * 10) % rescale_out)));
}
static inline constexpr int PIXEL_OFFSET2( int ntsc ) {
return 1.0F - (((ntsc) + 100) & 2);
}
#if 0 // DEAD CODE
#define ROTATE_IQ( i, q, sin_b, cos_b ) {\ #define ROTATE_IQ( i, q, sin_b, cos_b ) {\
float t;\ float t;\
t = i * cos_b - q * sin_b;\ t = i * cos_b - q * sin_b;\
q = i * sin_b + q * cos_b;\ q = i * sin_b + q * cos_b;\
i = t;\ i = t;\
} }
#define RGB_TO_YIQ( r, g, b, y, i ) (\
(y = (r) * 0.299f + (g) * 0.587f + (b) * 0.114f),\
(i = (r) * 0.595716f - (g) * 0.274453f - (b) * 0.321263f),\
((r) * 0.211456f - (g) * 0.522591f + (b) * 0.311135f)\
)
#define YIQ_TO_RGB( y, i, q, to_rgb, type, r, g ) (\
r = type(y + to_rgb [0] * i + to_rgb [1] * q),\
g = type(y + to_rgb [2] * i + to_rgb [3] * q),\
type(y + to_rgb [4] * i + to_rgb [5] * q)\
)
#ifndef PACK_RGB
#define PACK_RGB( r, g, b ) ((r) << 21 | (g) << 11 | (b) << 1)
#endif
#define PIXEL_OFFSET_( ntsc, scaled ) \
(kernel_size / 2 + ntsc + (scaled != 0) + (rescale_out - scaled) % rescale_out + \
(kernel_size * 2 * scaled))
#define PIXEL_OFFSET( ntsc, scaled ) \
PIXEL_OFFSET_( ((ntsc) - (scaled) / rescale_out * rescale_in),\
(((scaled) + rescale_out * 10) % rescale_out) ),\
(1.0f - (((ntsc) + 100) & 2))
#define DISTRIBUTE_ERROR( a, b, c ) {\ #define DISTRIBUTE_ERROR( a, b, c ) {\
uInt32 fourth = (error + 2 * rgb_builder) >> 2;\ uInt32 fourth = (error + 2 * rgb_builder) >> 2;\
@ -285,11 +292,12 @@ class AtariNTSC
#define RGB_PALETTE_OUT( rgb, out_ ) {\ #define RGB_PALETTE_OUT( rgb, out_ ) {\
unsigned char* out = (out_);\ unsigned char* out = (out_);\
uInt32 clamped = (rgb);\ uInt32 clamped = (rgb);\
ATARI_NTSC_CLAMP_( clamped, (8 - rgb_bits) );\ ATARI_NTSC_CLAMP( clamped, (8 - rgb_bits) );\
out [0] = (unsigned char) (clamped >> 21);\ out [0] = (unsigned char) (clamped >> 21);\
out [1] = (unsigned char) (clamped >> 11);\ out [1] = (unsigned char) (clamped >> 11);\
out [2] = (unsigned char) (clamped >> 1);\ out [2] = (unsigned char) (clamped >> 1);\
} }
#endif
}; };
#endif #endif

View File

@ -232,7 +232,7 @@ void NTSCFilter::convertToAdjustable(Adjustable& adjustable,
AtariNTSC::Setup NTSCFilter::myCustomSetup = AtariNTSC::TV_Composite; AtariNTSC::Setup NTSCFilter::myCustomSetup = AtariNTSC::TV_Composite;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const NTSCFilter::AdjustableTag NTSCFilter::ourCustomAdjustables[10] = { const std::array<NTSCFilter::AdjustableTag, 10> NTSCFilter::ourCustomAdjustables = { {
{ "contrast", &myCustomSetup.contrast }, { "contrast", &myCustomSetup.contrast },
{ "brightness", &myCustomSetup.brightness }, { "brightness", &myCustomSetup.brightness },
{ "hue", &myCustomSetup.hue }, { "hue", &myCustomSetup.hue },
@ -243,4 +243,4 @@ const NTSCFilter::AdjustableTag NTSCFilter::ourCustomAdjustables[10] = {
{ "artifacts", &myCustomSetup.artifacts }, { "artifacts", &myCustomSetup.artifacts },
{ "fringing", &myCustomSetup.fringing }, { "fringing", &myCustomSetup.fringing },
{ "bleeding", &myCustomSetup.bleed } { "bleeding", &myCustomSetup.bleed }
}; } };

View File

@ -109,12 +109,12 @@ class NTSCFilter
// Perform Blargg filtering on input buffer, place results in // Perform Blargg filtering on input buffer, place results in
// output buffer // output buffer
inline void render(uInt8* src_buf, uInt32 src_width, uInt32 src_height, inline void render(const uInt8* src_buf, uInt32 src_width, uInt32 src_height,
uInt32* dest_buf, uInt32 dest_pitch) uInt32* dest_buf, uInt32 dest_pitch)
{ {
myNTSC.render(src_buf, src_width, src_height, dest_buf, dest_pitch); myNTSC.render(src_buf, src_width, src_height, dest_buf, dest_pitch);
} }
inline void render(uInt8* src_buf, uInt32 src_width, uInt32 src_height, inline void render(const uInt8* src_buf, uInt32 src_width, uInt32 src_height,
uInt32* dest_buf, uInt32 dest_pitch, uInt32* prev_buf) uInt32* dest_buf, uInt32 dest_pitch, uInt32* prev_buf)
{ {
myNTSC.render(src_buf, src_width, src_height, dest_buf, dest_pitch, prev_buf); myNTSC.render(src_buf, src_width, src_height, dest_buf, dest_pitch, prev_buf);
@ -156,7 +156,7 @@ class NTSCFilter
float* value; float* value;
}; };
uInt32 myCurrentAdjustable; uInt32 myCurrentAdjustable;
static const AdjustableTag ourCustomAdjustables[10]; static const std::array<AdjustableTag, 10> ourCustomAdjustables;
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported