diff --git a/src/common/tv_filters/NTSCFilter.cxx b/src/common/tv_filters/NTSCFilter.cxx index 94e096458..f45c92125 100644 --- a/src/common/tv_filters/NTSCFilter.cxx +++ b/src/common/tv_filters/NTSCFilter.cxx @@ -30,8 +30,6 @@ #define FILTER_NTSC_FRINGING_MAX 1.0 #define FILTER_NTSC_BLEED_MIN -1.0 #define FILTER_NTSC_BLEED_MAX 1.0 -#define FILTER_NTSC_BURST_PHASE_MIN -1.0 -#define FILTER_NTSC_BURST_PHASE_MAX 1.0 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NTSCFilter::NTSCFilter() diff --git a/src/common/tv_filters/NTSCFilter.hxx b/src/common/tv_filters/NTSCFilter.hxx index c7553bd10..566c320e7 100644 --- a/src/common/tv_filters/NTSCFilter.hxx +++ b/src/common/tv_filters/NTSCFilter.hxx @@ -54,9 +54,8 @@ class NTSCFilter /* Normally used in conjunction with custom mode, contains all aspects currently adjustable in NTSC TV emulation. */ struct Adjustable { - double hue, saturation, contrast, brightness, gamma, - sharpness, resolution, artifacts, fringing, bleed, - burst_phase; + uInt32 hue, saturation, contrast, brightness, gamma, + sharpness, resolution, artifacts, fringing, bleed; }; public: @@ -73,8 +72,7 @@ class NTSCFilter // have changed) void updateFilter() { - mySetup.palette = myTIAPalette; - atari_ntsc_init(&myFilter, &mySetup); + atari_ntsc_init(&myFilter, &mySetup, myTIAPalette); } // Load and save NTSC-related settings diff --git a/src/common/tv_filters/atari_ntsc.c b/src/common/tv_filters/atari_ntsc.c index 70a81ef07..3c308be55 100644 --- a/src/common/tv_filters/atari_ntsc.c +++ b/src/common/tv_filters/atari_ntsc.c @@ -31,11 +31,10 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -atari_ntsc_setup_t const atari_ntsc_composite = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.15, 0.0, 0.0, 0.0, 0, 0, 0, 0 }; -atari_ntsc_setup_t const atari_ntsc_svideo = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.45, -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.2, 0.0, 0.70, -1.0, -1.0, -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, 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, 0.05, 0.7, -0.8, -0.7, 0, 0, 0, 0 }; +atari_ntsc_setup_t const atari_ntsc_composite = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.15, 0.0, 0.0, 0.0, 0 }; +atari_ntsc_setup_t const atari_ntsc_svideo = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.45, -1.0, -1.0, 0.0, 0 }; +atari_ntsc_setup_t const atari_ntsc_rgb = { 0.0, 0.0, 0.0, 0.0, 0.2, 0.0, 0.70, -1.0, -1.0, -1.0, 0 }; +atari_ntsc_setup_t const atari_ntsc_bad = { 0.1, -0.3, 0.3, 0.25, 0.2, 0.0, 0.1, 0.5, 0.5, 0.5, 0 }; #define alignment_count 2 #define burst_count 1 @@ -48,7 +47,6 @@ atari_ntsc_setup_t const atari_ntsc_horrible = { -0.1, -0.5, 0.6, 0.43, 0.4, 0. #define std_decoder_hue 0 #define gamma_size 256 -#define default_palette_contrast 1.0f #include "atari_ntsc_impl.h" @@ -70,9 +68,9 @@ static void correct_errors( atari_ntsc_rgb_t color, atari_ntsc_rgb_t* out ) } } -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_ntsc_in_t const* palette ) { - atari_ntsc_in_t* palette; int entry; init_t impl; if ( !setup ) @@ -80,11 +78,6 @@ void atari_ntsc_init( atari_ntsc_t* ntsc, atari_ntsc_setup_t const* setup ) init( &impl, setup ); // Palette stores R/G/B data for 'atari_ntsc_palette_size' entries - palette = (atari_ntsc_in_t*) setup->palette; - - // Burst-phase (TODO - how is this actually used?) -// float start_angle = - ((213.0f) * M_PI / 180.0f) - setup->burst_phase * M_PI; - for ( entry = 0; entry < atari_ntsc_palette_size; entry++ ) { float r = impl.to_float [*palette++]; @@ -95,7 +88,7 @@ void atari_ntsc_init( atari_ntsc_t* ntsc, atari_ntsc_setup_t const* setup ) // Generate kernel int ir, ig, ib = YIQ_TO_RGB( y, i, q, impl.to_rgb, int, ir, ig ); - atari_ntsc_rgb_t rgb = PACK_RGB( ir, ig, ib ); //(ib < 0x3E0 ? ib: 0x3E0) + atari_ntsc_rgb_t rgb = PACK_RGB( ir, ig, ib ); if ( ntsc ) { diff --git a/src/common/tv_filters/atari_ntsc.h b/src/common/tv_filters/atari_ntsc.h index a3e919863..4880aecea 100644 --- a/src/common/tv_filters/atari_ntsc.h +++ b/src/common/tv_filters/atari_ntsc.h @@ -48,29 +48,21 @@ typedef struct atari_ntsc_setup_t double fringing; /* color artifacts caused by brightness changes */ double bleed; /* color bleed (color resolution reduction) */ float const* decoder_matrix; /* optional RGB decoder matrix, 6 elements */ - - /* You can replace the standard TI color generation with an RGB palette. */ - unsigned char const* palette;/* optional RGB palette in, 3 bytes per color */ - unsigned char* palette_out; /* optional RGB palette out, 3 bytes per color */ - - /* Atari change: additional setup fields */ - double burst_phase; /* Phase at which colorburst signal is turned on; - this defines colors of artifacts. - In radians; -1.0 = -180 degrees, 1.0 = +180 degrees */ } atari_ntsc_setup_t; /* Video format presets */ 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_rgb; /* crisp image */ -extern atari_ntsc_setup_t const atari_ntsc_bad; +extern atari_ntsc_setup_t const atari_ntsc_bad; /* badly adjusted TV */ enum { atari_ntsc_palette_size = 128 }; /* Initializes and adjusts parameters. Can be called multiple times on the same atari_ntsc_t object. Can pass NULL for either parameter. */ 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, + atari_ntsc_in_t const* palette ); /* 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 diff --git a/src/common/tv_filters/atari_ntsc_impl.h b/src/common/tv_filters/atari_ntsc_impl.h index 5cfb9a6db..23dea1841 100644 --- a/src/common/tv_filters/atari_ntsc_impl.h +++ b/src/common/tv_filters/atari_ntsc_impl.h @@ -220,10 +220,6 @@ static void init( init_t* impl, atari_ntsc_setup_t const* setup ) { impl->brightness = (float) setup->brightness * (0.5f * rgb_unit) + rgb_offset; impl->contrast = (float) setup->contrast * (0.5f * rgb_unit) + rgb_unit; - #ifdef default_palette_contrast - if ( !setup->palette ) - impl->contrast *= default_palette_contrast; - #endif impl->artifacts = (float) setup->artifacts; if ( impl->artifacts > 0 ) @@ -251,20 +247,7 @@ static void init( init_t* impl, atari_ntsc_setup_t const* setup ) /* setup decoder matricies */ { -#if 0 // FIXME - research this - /* Atari change: - NTSC colorburst angle in YIQ colorspace. Colorburst is at - 180 degrees in YUV - that is, a gold color. In YIQ, gold is at - different angle. However, YIQ is actually YUV turned - 33 degrees. So by looking at screenshots at Wikipedia we can - conclude that the colorburst angle is 180+33 in YIQ. - (See http://en.wikipedia.org/wiki/YUV and - http://en.wikipedia.org/wiki/YIQ) */ - static float const colorburst_angle = (213.0f) * PI / 180.0f; - float hue = (float) setup->hue * PI + PI / 180 * ext_decoder_hue - PI * setup->burst_phase - colorburst_angle; -#else float hue = (float) setup->hue * PI + PI / 180 * ext_decoder_hue; -#endif float sat = (float) setup->saturation + 1; float const* decoder = setup->decoder_matrix; if ( !decoder ) diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 7d847e90f..9c3a382ef 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -40,7 +40,6 @@ Settings::Settings(OSystem* osystem) setInternal("video", "soft"); // OpenGL specific options - setInternal("gl_inter", "false"); setInternal("gl_aspectn", "90"); setInternal("gl_aspectp", "100"); setInternal("gl_fsscale", "false"); @@ -61,8 +60,19 @@ Settings::Settings(OSystem* osystem) // TV filtering options setInternal("tv_filter", "0"); - setInternal("tv_scanlines", "50"); + setInternal("tv_inter", "false"); + setInternal("tv_scanlines", "40"); setInternal("tv_scaninter", "true"); + // TV options when using 'custom' mode + setInternal("tv_sharpness", "0.0"); + setInternal("tv_resolution", "0.0"); + setInternal("tv_artifacts", "0.0"); + setInternal("tv_fringing", "0.0"); + setInternal("tv_bleed", "0.0"); + setInternal("tv_brightness", "0.0"); + setInternal("tv_contrast", "0.0"); + setInternal("tv_saturation", "0.0"); + setInternal("tv_gamma", "0.0"); // Sound options setInternal("sound", "true"); diff --git a/src/emucore/Settings.hxx b/src/emucore/Settings.hxx index 3a5835585..f1b177e0f 100644 --- a/src/emucore/Settings.hxx +++ b/src/emucore/Settings.hxx @@ -169,7 +169,7 @@ class Settings static string trim(string& str) { string::size_type first = str.find_first_not_of(' '); - return (first == string::npos) ? string() : + return (first == string::npos) ? EmptyString : str.substr(first, str.find_last_not_of(' ')-first+1); } diff --git a/src/gui/VideoDialog.cxx b/src/gui/VideoDialog.cxx index 8903e379c..c79dece55 100644 --- a/src/gui/VideoDialog.cxx +++ b/src/gui/VideoDialog.cxx @@ -37,6 +37,7 @@ #include "Widget.hxx" #include "TabWidget.hxx" #include "FrameBufferGL.hxx" +#include "NTSCFilter.hxx" #include "VideoDialog.hxx" @@ -237,17 +238,61 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent, // Add items for tab 0 addToFocusList(wid, tabID); -#if 0 ////////////////////////////////////////////////////////// // 2) TV effects options wid.clear(); tabID = myTab->addTab(" TV Effects "); - xpos = ypos = 8; - // TODO ... + xpos = ypos = 5; + + // TV Mode + items.clear(); + items.push_back("Disabled", BSPF_toString(NTSCFilter::PRESET_OFF)); + items.push_back("Composite", BSPF_toString(NTSCFilter::PRESET_COMPOSITE)); + items.push_back("S-Video", BSPF_toString(NTSCFilter::PRESET_SVIDEO)); + items.push_back("RGB", BSPF_toString(NTSCFilter::PRESET_RGB)); + items.push_back("Badly adjusted", BSPF_toString(NTSCFilter::PRESET_BAD)); + items.push_back("Custom", BSPF_toString(NTSCFilter::PRESET_CUSTOM)); + lwidth = font.getStringWidth("TV Mode: "); + pwidth = font.getStringWidth("Badly adjusted"), + myTVMode = + new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, + items, "TV Mode: ", lwidth, kTVModeChanged); + wid.push_back(myTVMode); + ypos += lineHeight + 4; + + // Custom adjustables (using macro voodoo) + xpos += 8; ypos += 4; + pwidth = lwidth; + lwidth = font.getStringWidth("Saturation: "); + +#define CREATE_CUSTOM_SLIDERS(obj, desc) \ + myTV ## obj = \ + new SliderWidget(myTab, font, xpos, ypos, pwidth, lineHeight, \ + desc, lwidth, kTV ## obj ##Changed); \ + myTV ## obj->setMinValue(0); myTV ## obj->setMaxValue(100); \ + wid.push_back(myTV ## obj); \ + myTV ## obj ## Label = \ + new StaticTextWidget(myTab, font, xpos+myTV ## obj->getWidth()+4, \ + ypos+1, fontWidth*3, fontHeight, "", kTextAlignLeft);\ + myTV ## obj->setFlags(WIDGET_CLEARBG); \ + ypos += lineHeight + 4 + + CREATE_CUSTOM_SLIDERS(Sharp, "Sharpness: "); + CREATE_CUSTOM_SLIDERS(Res, "Resolution: "); + CREATE_CUSTOM_SLIDERS(Artifacts, "Artifacts: "); + CREATE_CUSTOM_SLIDERS(Fringe, "Fringing: "); + CREATE_CUSTOM_SLIDERS(Blend, "Blending: "); + CREATE_CUSTOM_SLIDERS(Bright, "Brightness: "); + CREATE_CUSTOM_SLIDERS(Contrast, "Contrast: "); + CREATE_CUSTOM_SLIDERS(Satur, "Saturation: "); + CREATE_CUSTOM_SLIDERS(Gamma, "Gamma: "); + + + + // Add items for tab 2 addToFocusList(wid, tabID); -#endif // Activate the first tab myTab->setActiveTab(0); diff --git a/src/gui/VideoDialog.hxx b/src/gui/VideoDialog.hxx index 1963e93e3..225fba9d4 100644 --- a/src/gui/VideoDialog.hxx +++ b/src/gui/VideoDialog.hxx @@ -78,13 +78,43 @@ class VideoDialog : public Dialog CheckboxWidget* myFastSCBiosCheckbox; // TV effects options - // TODO ... + PopUpWidget* myTVMode; + SliderWidget* myTVSharp; + StaticTextWidget* myTVSharpLabel; + SliderWidget* myTVRes; + StaticTextWidget* myTVResLabel; + SliderWidget* myTVArtifacts; + StaticTextWidget* myTVArtifactsLabel; + SliderWidget* myTVFringe; + StaticTextWidget* myTVFringeLabel; + SliderWidget* myTVBlend; + StaticTextWidget* myTVBlendLabel; + SliderWidget* myTVBright; + StaticTextWidget* myTVBrightLabel; + SliderWidget* myTVContrast; + StaticTextWidget* myTVContrastLabel; + SliderWidget* myTVSatur; + StaticTextWidget* myTVSaturLabel; + SliderWidget* myTVGamma; + StaticTextWidget* myTVGammaLabel; enum { kNAspectRatioChanged = 'VDan', kPAspectRatioChanged = 'VDap', kFrameRateChanged = 'VDfr', - kFullScrChanged = 'VDfs' + kFullScrChanged = 'VDfs', + + kTVModeChanged = 'VDtv', + kTVSharpChanged = 'TVsh', + kTVResChanged = 'TVrs', + kTVArtifactsChanged = 'TVar', + kTVFringeChanged = 'TVfr', + kTVBlendChanged = 'TVbl', + kTVBrightChanged = 'TVbr', + kTVContrastChanged = 'TVct', + kTVSaturChanged = 'TVsa', + kTVGammaChanged = 'TVga', + kTVScanChanged = 'TVsc' }; };