mirror of https://github.com/stella-emu/stella.git
The default phosphor blend level can now be set globally (fixes #144).
Added new 'tv.phosphor' commandline argument to accomplish the above, and associated UI item in Video Settings. Updated docs for 'tv.phosphor' and 'tia.debugcolors'. More work is needed on this, since I need to add screenshots for this new functionality.
This commit is contained in:
parent
aa5be284cb
commit
d613173cd7
|
@ -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
|
||||
|
|
|
@ -1865,6 +1865,23 @@
|
|||
(vs. an integral stretch which won't necessarily completely fill the screen).</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><pre>-tia.debugcolors <ROYGBP></pre></td>
|
||||
<td>Assigns the colours (R)ed, (O)range, (Y)ellow, (G)reen, (B)lue and (P)urple
|
||||
to each graphical register P0/M0/P1/M1/PF/BL, respectively. Currently,
|
||||
these change be changed around to apply different colours to the
|
||||
respective register.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><pre>-tv.phosphor <0 - 100></pre></td>
|
||||
<td>Enable default phosphor blending level; 0 implies no mixing, and 100
|
||||
is full mixing (not recommended). Note that this doesn't actually
|
||||
enable phosphor mode; that is done for each ROM in the ROM properties.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><pre>-tv.jitter <1|0></pre></td>
|
||||
<td>Enable TV jitter/roll effect, when there are too many or too few scanlines
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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,15 +265,8 @@ 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];
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
PropertyType Properties::getPropertyType(const string& name)
|
||||
|
@ -310,7 +307,7 @@ void Properties::printHeader()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const char* const Properties::ourDefaultProperties[LastPropType] = {
|
||||
string Properties::ourDefaultProperties[LastPropType] = {
|
||||
"", // Cartridge.MD5
|
||||
"", // Cartridge.Manufacturer
|
||||
"", // Cartridge.ModelNo
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
@ -373,12 +377,14 @@ void Settings::usage() const
|
|||
<< " -tia.aspectn <number> Scale TIA width by the given percentage in NTSC mode\n"
|
||||
<< " -tia.aspectp <number> 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 <string> 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 <value> Set TV effects custom contrast to value 1.0 - 1.0\n"
|
||||
<< " -tv.brightness <value> Set TV effects custom brightness to value 1.0 - 1.0\n"
|
||||
<< " -tv.hue <value> Set TV effects custom hue to value 1.0 - 1.0\n"
|
||||
|
|
|
@ -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,6 +613,9 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd,
|
|||
break;
|
||||
|
||||
case kPPBlendChanged:
|
||||
if(myPPBlend->getValue() == 0)
|
||||
myPPBlendLabel->setLabel("Auto");
|
||||
else
|
||||
myPPBlendLabel->setValue(myPPBlend->getValue());
|
||||
break;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue