diff --git a/Changes.txt b/Changes.txt
index a3f595894..38b0e0106 100644
--- a/Changes.txt
+++ b/Changes.txt
@@ -24,11 +24,13 @@
choice of 'red', 'orange', 'yellow', 'green', 'blue' and 'purple'.
This is accessible through the new 'tia.dbgcolors' commandline
argument.
- - ...
+ - The defaul
* Implemented new phosphor emulation mode, which is much closer to real
- TV output. Special thanks to Thomas Jentzsch for the idea and
- implementation.
+ TV output. Related to this, added ability to change the default
+ phosphor blend level in the UI and through the new 'tv.phosphor'
+ commandline argument. Special thanks to Thomas Jentzsch for the idea
+ and implementation.
* Much improved RIOT timer emulation never before seen in any emulator.
Special thanks to DirtyHairy for the implementation, and alex_79 for
diff --git a/docs/index.html b/docs/index.html
index 059a2defe..4303154a7 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -1865,6 +1865,23 @@
(vs. an integral stretch which won't necessarily completely fill the screen).
+
-tv.jitter <1|0> |
Enable TV jitter/roll effect, when there are too many or too few scanlines
diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx
index a83bcb49f..dcf8624f3 100644
--- a/src/emucore/EventHandler.cxx
+++ b/src/emucore/EventHandler.cxx
@@ -103,6 +103,10 @@ void EventHandler::initialize()
// Integer to string conversions (for HEX) use upper or lower-case
Common::Base::setHexUppercase(myOSystem.settings().getBool("dbg.uhex"));
+
+ // Default phosphor blend
+ Properties::setDefault(Display_PPBlend,
+ myOSystem.settings().getString("tv.phosphor"));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/emucore/Props.cxx b/src/emucore/Props.cxx
index 59b24b3e3..a9bba8039 100644
--- a/src/emucore/Props.cxx
+++ b/src/emucore/Props.cxx
@@ -63,13 +63,11 @@ void Properties::set(PropertyType key, const string& value)
break;
}
- case Display_PPBlend: // FIXME - handle global default
+ case Display_PPBlend:
{
int blend = atoi(myProperties[key].c_str());
- if(blend < 1 || blend > 100) blend = 50;
- ostringstream buf;
- buf << blend;
- myProperties[key] = buf.str();
+ if(blend < 1 || blend > 100)
+ myProperties[key] = ourDefaultProperties[key];
break;
}
@@ -222,6 +220,12 @@ Properties& Properties::operator=(const Properties& properties)
return *this;
}
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Properties::setDefault(PropertyType key, const string& value)
+{
+ ourDefaultProperties[key] = value;
+}
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Properties::copy(const Properties& properties)
{
@@ -261,14 +265,7 @@ void Properties::print() const
void Properties::setDefaults()
{
for(int i = 0; i < LastPropType; ++i)
- {
- if(i == Display_PPBlend) // special case, handle global default
- {
- myProperties[i] = "50"; // FIXME - for now, just use 50
- }
- else
- myProperties[i] = ourDefaultProperties[i];
- }
+ myProperties[i] = ourDefaultProperties[i];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -310,7 +307,7 @@ void Properties::printHeader()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-const char* const Properties::ourDefaultProperties[LastPropType] = {
+string Properties::ourDefaultProperties[LastPropType] = {
"", // Cartridge.MD5
"", // Cartridge.Manufacturer
"", // Cartridge.ModelNo
diff --git a/src/emucore/Props.hxx b/src/emucore/Props.hxx
index 272005a8b..a1b1ab108 100644
--- a/src/emucore/Props.hxx
+++ b/src/emucore/Props.hxx
@@ -136,6 +136,14 @@ class Properties
*/
Properties& operator = (const Properties& properties);
+ /**
+ Set the default value associated with key to the given value.
+
+ @param key The key of the property to set
+ @param value The value to assign to the property
+ */
+ static void setDefault(PropertyType key, const string& value);
+
private:
/**
Helper function to perform a deep copy of the specified
@@ -183,7 +191,7 @@ class Properties
string myProperties[LastPropType];
// List of default properties to use when none have been provided
- static const char* const ourDefaultProperties[LastPropType];
+ static string ourDefaultProperties[LastPropType];
// The text strings associated with each property type
static const char* const ourPropertyNames[LastPropType];
diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx
index 84908a796..2a8d1e5bd 100644
--- a/src/emucore/Settings.cxx
+++ b/src/emucore/Settings.cxx
@@ -55,10 +55,11 @@ Settings::Settings(OSystem& osystem)
// TV filtering options
setInternal("tv.filter", "0");
- setInternal("tv.scanlines", "25");
- setInternal("tv.scaninter", "true");
+ setInternal("tv.phosphor", "50");
setInternal("tv.jitter", "false");
setInternal("tv.jitter_recovery", "10");
+ setInternal("tv.scanlines", "25");
+ setInternal("tv.scaninter", "true");
// TV options when using 'custom' mode
setInternal("tv.contrast", "0.0");
setInternal("tv.brightness", "0.0");
@@ -278,6 +279,9 @@ void Settings::validate()
sort(s.begin(), s.end());
if(s != "bgopry") setInternal("tia.dbgcolors", "roygpb");
+ i = getInt("tv.phosphor");
+ if(i < 0 || i > 100) setInternal("tv.phosphor", "50");
+
i = getInt("tv.filter");
if(i < 0 || i > 5) setInternal("tv.filter", "0");
@@ -368,17 +372,19 @@ void Settings::usage() const
<< " -volume Set the volume (0 - 100)\n"
<< endl
#endif
- << " -tia.zoom Use the specified zoom level (windowed mode) for TIA image\n"
- << " -tia.inter <1|0> Enable interpolated (smooth) scaling for TIA image\n"
- << " -tia.aspectn Scale TIA width by the given percentage in NTSC mode\n"
- << " -tia.aspectp Scale TIA width by the given percentage in PAL mode\n"
- << " -tia.fsfill <1|0> Stretch TIA image to fill fullscreen mode\n"
+ << " -tia.zoom Use the specified zoom level (windowed mode) for TIA image\n"
+ << " -tia.inter <1|0> Enable interpolated (smooth) scaling for TIA image\n"
+ << " -tia.aspectn Scale TIA width by the given percentage in NTSC mode\n"
+ << " -tia.aspectp Scale TIA width by the given percentage in PAL mode\n"
+ << " -tia.fsfill <1|0> Stretch TIA image to fill fullscreen mode\n"
+ << " -tia.dbgcolors Debug colors to use for each object (see manual for description)\n"
<< endl
<< " -tv.filter <0-5> Set TV effects off (0) or to specified mode (1-5)\n"
- << " -tv.scanlines <0-100> Set scanline intensity to percentage (0 disables completely)\n"
- << " -tv.scaninter <1|0> Enable interpolated (smooth) scanlines\n"
+ << " -tv.phosphor <0-100> Set default blend level in phosphor mode\n"
<< " -tv.jitter <1|0> Enable TV jitter effect\n"
<< " -tv.jitter_recovery <1-20> Set recovery time for TV jitter effect\n"
+ << " -tv.scanlines <0-100> Set scanline intensity to percentage (0 disables completely)\n"
+ << " -tv.scaninter <1|0> Enable interpolated (smooth) scanlines\n"
<< " -tv.contrast Set TV effects custom contrast to value 1.0 - 1.0\n"
<< " -tv.brightness Set TV effects custom brightness to value 1.0 - 1.0\n"
<< " -tv.hue Set TV effects custom hue to value 1.0 - 1.0\n"
diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx
index 30717911d..57f9beaf8 100644
--- a/src/gui/GameInfoDialog.cxx
+++ b/src/gui/GameInfoDialog.cxx
@@ -361,7 +361,7 @@ GameInfoDialog::GameInfoDialog(
myPPBlendLabel = new StaticTextWidget(myTab, font,
xpos + lwidth + myPhosphor->getWidth() + 10 +
myPPBlend->getWidth() + 4, ypos+1,
- 3*fontWidth, fontHeight, "", kTextAlignLeft);
+ 5*fontWidth, fontHeight, "", kTextAlignLeft);
myPPBlendLabel->setFlags(WIDGET_CLEARBG);
// Add items for tab 3
@@ -490,7 +490,7 @@ void GameInfoDialog::loadView()
const string& blend = myGameProperties.get(Display_PPBlend);
myPPBlend->setValue(atoi(blend.c_str()));
- myPPBlendLabel->setLabel(blend);
+ myPPBlendLabel->setLabel(blend == "0" ? "Auto" : blend);
myTab->loadConfig();
}
@@ -539,7 +539,8 @@ void GameInfoDialog::saveConfig()
myGameProperties.set(Display_Height, myHeightLabel->getLabel() == "Auto" ? "0" :
myHeightLabel->getLabel());
myGameProperties.set(Display_Phosphor, myPhosphor->getSelectedTag().toString());
- myGameProperties.set(Display_PPBlend, myPPBlendLabel->getLabel());
+ myGameProperties.set(Display_PPBlend, myPPBlendLabel->getLabel() == "Auto" ? "0" :
+ myPPBlendLabel->getLabel());
// Determine whether to add or remove an entry from the properties set
if(myDefaultsSelected)
@@ -612,7 +613,10 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd,
break;
case kPPBlendChanged:
- myPPBlendLabel->setValue(myPPBlend->getValue());
+ if(myPPBlend->getValue() == 0)
+ myPPBlendLabel->setLabel("Auto");
+ else
+ myPPBlendLabel->setValue(myPPBlend->getValue());
break;
case kMRangeChanged:
diff --git a/src/gui/VideoDialog.cxx b/src/gui/VideoDialog.cxx
index 58ee2215f..e3c6808df 100644
--- a/src/gui/VideoDialog.cxx
+++ b/src/gui/VideoDialog.cxx
@@ -52,7 +52,7 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
// Set real dimensions
_w = std::min(52 * fontWidth + 10, max_w);
- _h = std::min(14 * (lineHeight + 4) + 10, max_h);
+ _h = std::min(16 * (lineHeight + 4) + 10, max_h);
// The tab widget
xpos = ypos = 5;
@@ -244,18 +244,33 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
xpos += myTVContrast->getWidth() + myTVContrastLabel->getWidth() + 20;
ypos = 8;
- // TV jitter effect
- myTVJitter = new CheckboxWidget(myTab, font, xpos, ypos,
- "Jitter/Roll effect", kTVJitterChanged);
- wid.push_back(myTVJitter);
- ypos += lineHeight;
lwidth = font.getStringWidth("Intensity ");
pwidth = font.getMaxCharWidth() * 6;
+
+ // TV Phosphor effect
+ myTVPhosLabel = new StaticTextWidget(myTab, font, xpos, ypos,
+ font.getStringWidth("Phosphor Effect"), fontHeight,
+ "Phosphor Effect", kTextAlignLeft);
+ ypos += lineHeight;
+
+ // TV Phosphor default level
+ xpos += 20;
+ CREATE_CUSTOM_SLIDERS(PhosLevel, "Default ");
+ ypos += 4;
+
+ // TV jitter effect
+ xpos -= 20;
+ myTVJitter = new CheckboxWidget(myTab, font, xpos, ypos,
+ "Jitter/Roll Effect", kTVJitterChanged);
+ wid.push_back(myTVJitter);
+ xpos += 20;
+ ypos += lineHeight;
CREATE_CUSTOM_SLIDERS(JitterRec, "Recovery ");
myTVJitterRec->setMinValue(1); myTVJitterRec->setMaxValue(20);
ypos += 4;
// Scanline intensity and interpolation
+ xpos -= 20;
myTVScanLabel =
new StaticTextWidget(myTab, font, xpos, ypos, font.getStringWidth("Scanline settings"),
fontHeight, "Scanline settings", kTextAlignLeft);
@@ -289,6 +304,13 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
// Add items for tab 2
addToFocusList(wid, myTab, tabID);
+ //////////////////////////////////////////////////////////
+ // 3) TIA debug colours
+ wid.clear();
+ tabID = myTab->addTab(" Debug Colors ");
+ xpos = ypos = 8;
+
+
// Activate the first tab
myTab->setActiveTab(0);
@@ -376,6 +398,10 @@ void VideoDialog::loadConfig()
// TV Custom adjustables
loadTVAdjustables(NTSCFilter::PRESET_CUSTOM);
+ // TV phosphor blend
+ myTVPhosLevel->setValue(instance().settings().getInt("tv.phosphor"));
+ myTVPhosLevelLabel->setLabel(instance().settings().getString("tv.phosphor"));
+
// TV jitter
myTVJitterRec->setValue(instance().settings().getInt("tv.jitter_recovery"));
myTVJitterRecLabel->setLabel(instance().settings().getString("tv.jitter_recovery"));
@@ -467,6 +493,10 @@ void VideoDialog::saveConfig()
adj.bleed = myTVBleed->getValue();
instance().frameBuffer().tiaSurface().ntsc().setCustomAdjustables(adj);
+ // TV phosphor blend
+ instance().settings().setValue("tv.phosphor", myTVPhosLevelLabel->getLabel());
+ Properties::setDefault(Display_PPBlend, myTVPhosLevelLabel->getLabel());
+
// TV jitter
instance().settings().setValue("tv.jitter", myTVJitter->getState());
instance().settings().setValue("tv.jitter_recovery", myTVJitterRecLabel->getLabel());
@@ -517,6 +547,15 @@ void VideoDialog::setDefaults()
{
myTVMode->setSelected("0", "0");
+ // TV phosphor blend
+ myTVPhosLevel->setValue(50);
+ myTVPhosLevelLabel->setLabel("50");
+
+ // TV jitter
+ myTVJitterRec->setValue(10);
+ myTVJitterRecLabel->setLabel("10");
+ handleTVJitterChange(false);
+
// TV scanline intensity and interpolation
myTVScanIntense->setValue(25);
myTVScanIntenseLabel->setLabel("25");
@@ -525,11 +564,6 @@ void VideoDialog::setDefaults()
// Make sure that mutually-exclusive items are not enabled at the same time
handleTVModeChange(NTSCFilter::PRESET_OFF);
loadTVAdjustables(NTSCFilter::PRESET_CUSTOM);
-
- // TV jitter
- myTVJitterRec->setValue(10);
- myTVJitterRecLabel->setLabel("10");
- handleTVJitterChange(false);
break;
}
}
@@ -666,12 +700,14 @@ void VideoDialog::handleCommand(CommandSender* sender, int cmd,
break;
case kTVGammaChanged: myTVGammaLabel->setValue(myTVGamma->getValue());
break;
- case kTVScanIntenseChanged: myTVScanIntenseLabel->setValue(myTVScanIntense->getValue());
+ case kTVPhosLevelChanged: myTVPhosLevelLabel->setValue(myTVPhosLevel->getValue());
break;
case kTVJitterChanged: handleTVJitterChange(myTVJitter->getState());
break;
case kTVJitterRecChanged: myTVJitterRecLabel->setValue(myTVJitterRec->getValue());
break;
+ case kTVScanIntenseChanged: myTVScanIntenseLabel->setValue(myTVScanIntense->getValue());
+ break;
case kCloneCompositeCmd: loadTVAdjustables(NTSCFilter::PRESET_COMPOSITE);
break;
case kCloneSvideoCmd: loadTVAdjustables(NTSCFilter::PRESET_SVIDEO);
diff --git a/src/gui/VideoDialog.hxx b/src/gui/VideoDialog.hxx
index af3b128fe..28a168051 100644
--- a/src/gui/VideoDialog.hxx
+++ b/src/gui/VideoDialog.hxx
@@ -95,6 +95,16 @@ class VideoDialog : public Dialog
SliderWidget* myTVGamma;
StaticTextWidget* myTVGammaLabel;
+ // TV jitter effects
+ CheckboxWidget* myTVJitter;
+ SliderWidget* myTVJitterRec;
+ StaticTextWidget* myTVJitterRecLabel;
+
+ // TV phosphor effect
+ StaticTextWidget* myTVPhosLabel;
+ SliderWidget* myTVPhosLevel;
+ StaticTextWidget* myTVPhosLevelLabel;
+
// TV scanline intensity and interpolation
StaticTextWidget* myTVScanLabel;
SliderWidget* myTVScanIntense;
@@ -108,11 +118,6 @@ class VideoDialog : public Dialog
ButtonWidget* myCloneBad;
ButtonWidget* myCloneCustom;
- // TV jitter effects
- CheckboxWidget* myTVJitter;
- SliderWidget* myTVJitterRec;
- StaticTextWidget* myTVJitterRecLabel;
-
enum {
kNAspectRatioChanged = 'VDan',
kPAspectRatioChanged = 'VDap',
@@ -134,6 +139,8 @@ class VideoDialog : public Dialog
kTVJitterChanged = 'TVjt',
kTVJitterRecChanged = 'TVjr',
+ kTVPhosLevelChanged = 'TVpl',
+
kCloneCompositeCmd = 'CLcp',
kCloneSvideoCmd = 'CLsv',
kCloneRGBCmd = 'CLrb',
|