mirror of https://github.com/stella-emu/stella.git
added auto-phosphor (resolves #1009)
This commit is contained in:
parent
d2c36ae159
commit
a430ad6927
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
* Added option to start random ROM.
|
* Added option to start random ROM.
|
||||||
|
|
||||||
|
* Added option for automatic phosphor.
|
||||||
|
|
||||||
* Enhanced Game Properties dialog for multigame ROMs.
|
* Enhanced Game Properties dialog for multigame ROMs.
|
||||||
|
|
||||||
* Added 2nd UI theme and hotkey for toggling UI theme.
|
* Added 2nd UI theme and hotkey for toggling UI theme.
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
@ -1309,6 +1309,11 @@
|
||||||
<td>Alt + 3</td>
|
<td>Alt + 3</td>
|
||||||
<td>Cmd + 3</td>
|
<td>Cmd + 3</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>Increase</i> 'phosphor' enabling mode</td>
|
||||||
|
<td>Ctrl-Alt + P</td>
|
||||||
|
<td>Ctrl-Cmd + P</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Toggle 'phosphor' mode</td>
|
<td>Toggle 'phosphor' mode</td>
|
||||||
<td>Alt + P</td>
|
<td>Alt + P</td>
|
||||||
|
@ -2921,11 +2926,11 @@
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td><pre>-tv.phosphor <always|byrom></pre></td>
|
<td><pre>-tv.phosphor <always|auto|byrom></pre></td>
|
||||||
<td>Determine how phosphor mode is enabled. If 'always', then the
|
<td>Determine how phosphor mode is enabled. If 'always' or 'auto', then
|
||||||
ROM properties entry is ignored, and phosphor mode is always turned
|
the ROM properties entry is ignored, and phosphor mode is either always
|
||||||
on. Otherwise, the ROM properties determine whether phosphor mode
|
turned on or automatic. Otherwise, the ROM properties determine whether
|
||||||
is used for each ROM.
|
phosphor mode is used for each ROM.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
@ -3820,8 +3825,8 @@
|
||||||
<tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
|
<tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
|
||||||
<tr><td>TV mode</td><td>Disable TV effects, or select TV preset</td><td>-tv.filter</td></tr>
|
<tr><td>TV mode</td><td>Disable TV effects, or select TV preset</td><td>-tv.filter</td></tr>
|
||||||
<tr><td>Adjustable sliders</td><td>Set specific attribute in 'Custom' TV mode</td><td>-tv.sharpness<br/>-tv.resolution, etc.</td></tr>
|
<tr><td>Adjustable sliders</td><td>Set specific attribute in 'Custom' TV mode</td><td>-tv.sharpness<br/>-tv.resolution, etc.</td></tr>
|
||||||
<tr><td>Phosphor for all ROMs</td><td>Enable phosphor mode for all ROMs</td><td>-tv.phosphor</td></tr>
|
<tr><td>Phosphor</td><td>Select mode for enabling phosphor</td><td>-tv.phosphor</td></tr>
|
||||||
<tr><td>Blend (phosphor)</td><td>Blend level to use in phosphor mode for all ROMs
|
<tr><td>Blend (phosphor)</td><td>Blend level to use in phosphor modes for all ROMs and automatic
|
||||||
(needs to be manually adjusted for your particular hardware)</td><td>-tv.phosblend</td></tr>
|
(needs to be manually adjusted for your particular hardware)</td><td>-tv.phosblend</td></tr>
|
||||||
<tr><td>(Scanlines) Intensity</td><td>Sets scanlines black-level intensity.</br>
|
<tr><td>(Scanlines) Intensity</td><td>Sets scanlines black-level intensity.</br>
|
||||||
Note: No scanlines in 1x mode snapshots</td><td>-tv.scanlines</td></tr>
|
Note: No scanlines in 1x mode snapshots</td><td>-tv.scanlines</td></tr>
|
||||||
|
|
|
@ -660,6 +660,8 @@ PhysicalKeyboardHandler::DefaultCommonMapping = {
|
||||||
{ Event::PhosphorDecrease, KBDK_4, KBDM_SHIFT | MOD3 },
|
{ Event::PhosphorDecrease, KBDK_4, KBDM_SHIFT | MOD3 },
|
||||||
{ Event::PhosphorIncrease, KBDK_4, MOD3 },
|
{ Event::PhosphorIncrease, KBDK_4, MOD3 },
|
||||||
{ Event::TogglePhosphor, KBDK_P, MOD3 },
|
{ Event::TogglePhosphor, KBDK_P, MOD3 },
|
||||||
|
{ Event::PhosphorModeDecrease, KBDK_P, KBDM_SHIFT | KBDM_CTRL | MOD3 },
|
||||||
|
{ Event::PhosphorModeIncrease, KBDK_P, KBDM_CTRL | MOD3 },
|
||||||
{ Event::ScanlinesDecrease, KBDK_5, KBDM_SHIFT | MOD3 },
|
{ Event::ScanlinesDecrease, KBDK_5, KBDM_SHIFT | MOD3 },
|
||||||
{ Event::ScanlinesIncrease, KBDK_5, MOD3 },
|
{ Event::ScanlinesIncrease, KBDK_5, MOD3 },
|
||||||
{ Event::PreviousScanlineMask, KBDK_6, KBDM_SHIFT | MOD3 },
|
{ Event::PreviousScanlineMask, KBDK_6, KBDM_SHIFT | MOD3 },
|
||||||
|
|
|
@ -24,6 +24,10 @@ bool PhosphorHandler::initialize(bool enable, int blend)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
myUsePhosphor = enable;
|
myUsePhosphor = enable;
|
||||||
|
|
||||||
|
// Precalculate the average colors for the 'phosphor' effect
|
||||||
|
if((myUsePhosphor && blend != -1 && blend / 100.F != myPhosphorPercent) || !myLUTInitialized)
|
||||||
|
{
|
||||||
if(blend >= 0 && blend <= 100)
|
if(blend >= 0 && blend <= 100)
|
||||||
myPhosphorPercent = blend / 100.F;
|
myPhosphorPercent = blend / 100.F;
|
||||||
|
|
||||||
|
@ -34,13 +38,10 @@ bool PhosphorHandler::initialize(bool enable, int blend)
|
||||||
if(c1 > c2) return c1; // raise (assumed immediate)
|
if(c1 > c2) return c1; // raise (assumed immediate)
|
||||||
else return c2; // decay
|
else return c2; // decay
|
||||||
};
|
};
|
||||||
|
|
||||||
// Precalculate the average colors for the 'phosphor' effect
|
|
||||||
if(myUsePhosphor)
|
|
||||||
{
|
|
||||||
for(int c = 255; c >= 0; --c)
|
for(int c = 255; c >= 0; --c)
|
||||||
for(int p = 255; p >= 0; --p)
|
for(int p = 255; p >= 0; --p)
|
||||||
ourPhosphorLUT[c][p] = getPhosphor(static_cast<uInt8>(c), static_cast<uInt8>(p));
|
ourPhosphorLUT[c][p] = getPhosphor(static_cast<uInt8>(c), static_cast<uInt8>(p));
|
||||||
|
myLUTInitialized = true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ class PhosphorHandler
|
||||||
|
|
||||||
// Amount to blend when using phosphor effect
|
// Amount to blend when using phosphor effect
|
||||||
float myPhosphorPercent{0.50F};
|
float myPhosphorPercent{0.50F};
|
||||||
|
bool myLUTInitialized{false};
|
||||||
|
|
||||||
// Precalculated averaged phosphor colors
|
// Precalculated averaged phosphor colors
|
||||||
using PhosphorLUT = BSPF::array2D<uInt8, kColor, kColor>;
|
using PhosphorLUT = BSPF::array2D<uInt8, kColor, kColor>;
|
||||||
|
|
|
@ -360,6 +360,8 @@ NLOHMANN_JSON_SERIALIZE_ENUM(Event::Type, {
|
||||||
{Event::PhosphorDecrease, "PhosphorDecrease"},
|
{Event::PhosphorDecrease, "PhosphorDecrease"},
|
||||||
{Event::PhosphorIncrease, "PhosphorIncrease"},
|
{Event::PhosphorIncrease, "PhosphorIncrease"},
|
||||||
{Event::TogglePhosphor, "TogglePhosphor"},
|
{Event::TogglePhosphor, "TogglePhosphor"},
|
||||||
|
{Event::PhosphorModeDecrease, "PhosphorModeDecrease"},
|
||||||
|
{Event::PhosphorModeIncrease, "PhosphorModeIncrease"},
|
||||||
{Event::ToggleDeveloperSet, "ToggleDeveloperSet"},
|
{Event::ToggleDeveloperSet, "ToggleDeveloperSet"},
|
||||||
{Event::ToggleInter, "ToggleInter"},
|
{Event::ToggleInter, "ToggleInter"},
|
||||||
{Event::JitterSenseDecrease, "JitterSenseDecrease"},
|
{Event::JitterSenseDecrease, "JitterSenseDecrease"},
|
||||||
|
|
|
@ -123,7 +123,17 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
|
||||||
// Create subsystems for the console
|
// Create subsystems for the console
|
||||||
my6502 = make_unique<M6502>(myOSystem.settings());
|
my6502 = make_unique<M6502>(myOSystem.settings());
|
||||||
myRiot = make_unique<M6532>(*this, myOSystem.settings());
|
myRiot = make_unique<M6532>(*this, myOSystem.settings());
|
||||||
myTIA = make_unique<TIA>(*this, [this]() { return timing(); }, myOSystem.settings());
|
|
||||||
|
const TIA::onPhosphorCallback callback = [&frameBuffer = this->myOSystem.frameBuffer()](bool enable)
|
||||||
|
{
|
||||||
|
frameBuffer.tiaSurface().enablePhosphor(enable);
|
||||||
|
#if DEBUG_BUILD
|
||||||
|
ostringstream msg;
|
||||||
|
msg << "Phosphor effect automatically " << (enable ? "enabled" : "disabled");
|
||||||
|
frameBuffer.showTextMessage(msg.str());
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
myTIA = make_unique<TIA>(*this, [this]() { return timing(); }, myOSystem.settings(), callback);
|
||||||
myFrameManager = make_unique<FrameManager>();
|
myFrameManager = make_unique<FrameManager>();
|
||||||
mySwitches = make_unique<Switches>(myEvent, myProperties, myOSystem.settings());
|
mySwitches = make_unique<Switches>(myEvent, myProperties, myOSystem.settings());
|
||||||
|
|
||||||
|
@ -615,18 +625,65 @@ void Console::changeSpeed(int direction)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Console::togglePhosphor()
|
void Console::togglePhosphor()
|
||||||
{
|
{
|
||||||
if(myOSystem.frameBuffer().tiaSurface().phosphorEnabled())
|
const bool enable = !myOSystem.frameBuffer().tiaSurface().phosphorEnabled();
|
||||||
{
|
if(!enable)
|
||||||
myProperties.set(PropType::Display_Phosphor, "NO");
|
myProperties.set(PropType::Display_Phosphor, "NO");
|
||||||
myOSystem.frameBuffer().tiaSurface().enablePhosphor(false);
|
else
|
||||||
myOSystem.frameBuffer().showTextMessage("Phosphor effect disabled");
|
myProperties.set(PropType::Display_Phosphor, "YES");
|
||||||
|
myOSystem.frameBuffer().tiaSurface().enablePhosphor(enable);
|
||||||
|
|
||||||
|
// disable auto-phosphor
|
||||||
|
if(myTIA->autoPhosphorEnabled())
|
||||||
|
myTIA->enableAutoPhosphor(false);
|
||||||
|
|
||||||
|
ostringstream msg;
|
||||||
|
msg << "Phosphor effect " << (enable ? "enabled" : "disabled");
|
||||||
|
myOSystem.frameBuffer().showTextMessage(msg.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Console::cyclePhosphorMode(int direction)
|
||||||
|
{
|
||||||
|
static constexpr std::array<string_view, 3> MESSAGES = {
|
||||||
|
"by ROM", "always on", "auto-enabled"
|
||||||
|
};
|
||||||
|
static constexpr std::array<string_view, 3> VALUE = {
|
||||||
|
"byrom", "always", "auto"
|
||||||
|
};
|
||||||
|
const string value = myOSystem.settings().getString("tv.phosphor");
|
||||||
|
int mode;
|
||||||
|
|
||||||
|
for(mode = 2; mode > 0; --mode)
|
||||||
|
if(value == VALUE[mode])
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(direction)
|
||||||
|
{
|
||||||
|
mode = BSPF::clampw(mode + direction, 0, 2);
|
||||||
|
if(mode == 0)
|
||||||
|
{
|
||||||
|
myOSystem.frameBuffer().tiaSurface().enablePhosphor(
|
||||||
|
myProperties.get(PropType::Display_Phosphor) == "YES",
|
||||||
|
BSPF::stoi(myProperties.get(PropType::Display_PPBlend)));
|
||||||
|
myTIA->enableAutoPhosphor(false);
|
||||||
|
}
|
||||||
|
else if(mode == 1)
|
||||||
|
{
|
||||||
|
myOSystem.frameBuffer().tiaSurface().enablePhosphor(
|
||||||
|
true, myOSystem.settings().getInt("tv.phosblend"));
|
||||||
|
myTIA->enableAutoPhosphor(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
myProperties.set(PropType::Display_Phosphor, "YES");
|
myOSystem.frameBuffer().tiaSurface().enablePhosphor(
|
||||||
myOSystem.frameBuffer().tiaSurface().enablePhosphor(true);
|
false, myOSystem.settings().getInt("tv.phosblend"));
|
||||||
myOSystem.frameBuffer().showTextMessage("Phosphor effect enabled");
|
myTIA->enableAutoPhosphor(true);
|
||||||
}
|
}
|
||||||
|
myOSystem.settings().setValue("tv.phosphor", VALUE[mode]);
|
||||||
|
}
|
||||||
|
ostringstream msg;
|
||||||
|
msg << "Phosphor mode " << MESSAGES[mode];
|
||||||
|
myOSystem.frameBuffer().showTextMessage(msg.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -693,7 +750,7 @@ void Console::initializeAudio()
|
||||||
.updateAudioQueueExtraFragments(myAudioSettings.bufferSize())
|
.updateAudioQueueExtraFragments(myAudioSettings.bufferSize())
|
||||||
.updateAudioQueueHeadroom(myAudioSettings.headroom())
|
.updateAudioQueueHeadroom(myAudioSettings.headroom())
|
||||||
.updateSpeedFactor(myOSystem.settings().getBool("turbo")
|
.updateSpeedFactor(myOSystem.settings().getBool("turbo")
|
||||||
? 20.0F
|
? 50.0F
|
||||||
: myOSystem.settings().getFloat("speed"));
|
: myOSystem.settings().getFloat("speed"));
|
||||||
|
|
||||||
createAudioQueue();
|
createAudioQueue();
|
||||||
|
|
|
@ -252,6 +252,11 @@ class Console : public Serializable, public ConsoleIO
|
||||||
*/
|
*/
|
||||||
void togglePhosphor();
|
void togglePhosphor();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Toggles auto-phosphor.
|
||||||
|
*/
|
||||||
|
void cyclePhosphorMode(int direction = +1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Change the "Display.PPBlend" variable.
|
Change the "Display.PPBlend" variable.
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,8 @@ class Event
|
||||||
PreviousAttribute, NextAttribute, DecreaseAttribute, IncreaseAttribute,
|
PreviousAttribute, NextAttribute, DecreaseAttribute, IncreaseAttribute,
|
||||||
ScanlinesDecrease, ScanlinesIncrease,
|
ScanlinesDecrease, ScanlinesIncrease,
|
||||||
PreviousScanlineMask, NextScanlineMask,
|
PreviousScanlineMask, NextScanlineMask,
|
||||||
PhosphorDecrease, PhosphorIncrease, TogglePhosphor, ToggleInter,
|
PhosphorDecrease, PhosphorIncrease, TogglePhosphor,
|
||||||
|
PhosphorModeDecrease, PhosphorModeIncrease, ToggleInter,
|
||||||
ToggleDeveloperSet, JitterRecDecrease, JitterRecIncrease,
|
ToggleDeveloperSet, JitterRecDecrease, JitterRecIncrease,
|
||||||
JitterSenseDecrease, JitterSenseIncrease, ToggleJitter,
|
JitterSenseDecrease, JitterSenseIncrease, ToggleJitter,
|
||||||
|
|
||||||
|
|
|
@ -738,6 +738,22 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case Event::PhosphorModeDecrease:
|
||||||
|
if(pressed && !repeated)
|
||||||
|
{
|
||||||
|
myOSystem.console().cyclePhosphorMode(-1);
|
||||||
|
myGlobalKeyHandler->setSetting(GlobalKeyHandler::Setting::PHOSPHOR_MODE);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
case Event::PhosphorModeIncrease:
|
||||||
|
if(pressed && !repeated)
|
||||||
|
{
|
||||||
|
myOSystem.console().cyclePhosphorMode(+1);
|
||||||
|
myGlobalKeyHandler->setSetting(GlobalKeyHandler::Setting::PHOSPHOR_MODE);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
case Event::ScanlinesDecrease:
|
case Event::ScanlinesDecrease:
|
||||||
if(pressed)
|
if(pressed)
|
||||||
{
|
{
|
||||||
|
@ -3004,6 +3020,8 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { {
|
||||||
{ Event::IncreaseAttribute, "Increase selected 'Custom' attribute" },
|
{ Event::IncreaseAttribute, "Increase selected 'Custom' attribute" },
|
||||||
// Other TV effects
|
// Other TV effects
|
||||||
{ Event::TogglePhosphor, "Toggle 'phosphor' effect" },
|
{ Event::TogglePhosphor, "Toggle 'phosphor' effect" },
|
||||||
|
{ Event::PhosphorModeDecrease, "Decrease 'phosphor' enabling mode" },
|
||||||
|
{ Event::PhosphorModeIncrease, "Increase 'phosphor' enabling mode" },
|
||||||
{ Event::PhosphorDecrease, "Decrease 'phosphor' blend" },
|
{ Event::PhosphorDecrease, "Decrease 'phosphor' blend" },
|
||||||
{ Event::PhosphorIncrease, "Increase 'phosphor' blend" },
|
{ Event::PhosphorIncrease, "Increase 'phosphor' blend" },
|
||||||
{ Event::ScanlinesDecrease, "Decrease scanlines" },
|
{ Event::ScanlinesDecrease, "Decrease scanlines" },
|
||||||
|
@ -3181,6 +3199,7 @@ const Event::EventSet EventHandler::AudioVideoEvents = {
|
||||||
Event::PreviousVideoMode, Event::NextVideoMode,
|
Event::PreviousVideoMode, Event::NextVideoMode,
|
||||||
Event::PreviousAttribute, Event::NextAttribute, Event::DecreaseAttribute, Event::IncreaseAttribute,
|
Event::PreviousAttribute, Event::NextAttribute, Event::DecreaseAttribute, Event::IncreaseAttribute,
|
||||||
Event::PhosphorDecrease, Event::PhosphorIncrease, Event::TogglePhosphor,
|
Event::PhosphorDecrease, Event::PhosphorIncrease, Event::TogglePhosphor,
|
||||||
|
Event::PhosphorModeDecrease, Event::PhosphorModeIncrease,
|
||||||
Event::ScanlinesDecrease, Event::ScanlinesIncrease,
|
Event::ScanlinesDecrease, Event::ScanlinesIncrease,
|
||||||
Event::PreviousScanlineMask, Event::NextScanlineMask,
|
Event::PreviousScanlineMask, Event::NextScanlineMask,
|
||||||
Event::ToggleInter,
|
Event::ToggleInter,
|
||||||
|
|
|
@ -540,7 +540,7 @@ class EventHandler
|
||||||
#else
|
#else
|
||||||
REFRESH_SIZE = 0,
|
REFRESH_SIZE = 0,
|
||||||
#endif
|
#endif
|
||||||
EMUL_ACTIONLIST_SIZE = 233 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE,
|
EMUL_ACTIONLIST_SIZE = 235 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE,
|
||||||
MENU_ACTIONLIST_SIZE = 20
|
MENU_ACTIONLIST_SIZE = 20
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -328,12 +328,20 @@ FBInitStatus FrameBuffer::createDisplay(string_view title, BufferType type,
|
||||||
// Phosphor mode can be enabled either globally or per-ROM
|
// Phosphor mode can be enabled either globally or per-ROM
|
||||||
int p_blend = 0;
|
int p_blend = 0;
|
||||||
bool enable = false;
|
bool enable = false;
|
||||||
|
const string phosphor = myOSystem.settings().getString("tv.phosphor");
|
||||||
|
|
||||||
if(myOSystem.settings().getString("tv.phosphor") == "always")
|
myOSystem.console().tia().enableAutoPhosphor(phosphor == "auto");
|
||||||
|
|
||||||
|
if(phosphor == "always")
|
||||||
{
|
{
|
||||||
p_blend = myOSystem.settings().getInt("tv.phosblend");
|
p_blend = myOSystem.settings().getInt("tv.phosblend");
|
||||||
enable = true;
|
enable = true;
|
||||||
}
|
}
|
||||||
|
else if(phosphor == "auto")
|
||||||
|
{
|
||||||
|
p_blend = myOSystem.settings().getInt("tv.phosblend");
|
||||||
|
enable = false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p_blend = BSPF::stoi(myOSystem.console().properties().get(PropType::Display_PPBlend));
|
p_blend = BSPF::stoi(myOSystem.console().properties().get(PropType::Display_PPBlend));
|
||||||
|
@ -719,7 +727,7 @@ void FrameBuffer::drawFrameStats(float framesPerSecond)
|
||||||
<< "fps @ "
|
<< "fps @ "
|
||||||
<< std::fixed << std::setprecision(0) << 100 *
|
<< std::fixed << std::setprecision(0) << 100 *
|
||||||
(myOSystem.settings().getBool("turbo")
|
(myOSystem.settings().getBool("turbo")
|
||||||
? 20.0F
|
? 50.0F
|
||||||
: myOSystem.settings().getFloat("speed"))
|
: myOSystem.settings().getFloat("speed"))
|
||||||
<< "% speed";
|
<< "% speed";
|
||||||
|
|
||||||
|
|
|
@ -390,6 +390,7 @@ GlobalKeyHandler::SettingData GlobalKeyHandler::getSettingData(const Setting set
|
||||||
{Setting::NTSC_BLEEDING, {true, std::bind(&TIASurface::changeNTSCAdjustable, &myOSystem.frameBuffer().tiaSurface(),
|
{Setting::NTSC_BLEEDING, {true, std::bind(&TIASurface::changeNTSCAdjustable, &myOSystem.frameBuffer().tiaSurface(),
|
||||||
static_cast<int>(NTSCFilter::Adjustables::BLEEDING), _1)}},
|
static_cast<int>(NTSCFilter::Adjustables::BLEEDING), _1)}},
|
||||||
// Other TV effects adjustables
|
// Other TV effects adjustables
|
||||||
|
{Setting::PHOSPHOR_MODE, {true, std::bind(&Console::cyclePhosphorMode, &myOSystem.console(), _1)}},
|
||||||
{Setting::PHOSPHOR, {true, std::bind(&Console::changePhosphor, &myOSystem.console(), _1)}},
|
{Setting::PHOSPHOR, {true, std::bind(&Console::changePhosphor, &myOSystem.console(), _1)}},
|
||||||
{Setting::SCANLINES, {true, std::bind(&TIASurface::changeScanlineIntensity, &myOSystem.frameBuffer().tiaSurface(), _1)}},
|
{Setting::SCANLINES, {true, std::bind(&TIASurface::changeScanlineIntensity, &myOSystem.frameBuffer().tiaSurface(), _1)}},
|
||||||
{Setting::SCANLINE_MASK, {false, std::bind(&TIASurface::cycleScanlineMask, &myOSystem.frameBuffer().tiaSurface(), _1)}},
|
{Setting::SCANLINE_MASK, {false, std::bind(&TIASurface::cycleScanlineMask, &myOSystem.frameBuffer().tiaSurface(), _1)}},
|
||||||
|
|
|
@ -69,6 +69,7 @@ class GlobalKeyHandler
|
||||||
NTSC_FRINGING,
|
NTSC_FRINGING,
|
||||||
NTSC_BLEEDING,
|
NTSC_BLEEDING,
|
||||||
// Other TV effects adjustables
|
// Other TV effects adjustables
|
||||||
|
PHOSPHOR_MODE,
|
||||||
PHOSPHOR,
|
PHOSPHOR,
|
||||||
SCANLINES,
|
SCANLINES,
|
||||||
SCANLINE_MASK,
|
SCANLINE_MASK,
|
||||||
|
|
|
@ -125,7 +125,10 @@ bool ProfilingRunner::runOne(const ProfilingRun& run)
|
||||||
|
|
||||||
M6502 cpu(mySettings);
|
M6502 cpu(mySettings);
|
||||||
M6532 riot(consoleIO, mySettings);
|
M6532 riot(consoleIO, mySettings);
|
||||||
TIA tia(consoleIO, []() { return ConsoleTiming::ntsc; }, mySettings);
|
|
||||||
|
const TIA::onPhosphorCallback callback = [] (bool enable) {};
|
||||||
|
|
||||||
|
TIA tia(consoleIO, []() { return ConsoleTiming::ntsc; }, mySettings, callback);
|
||||||
System system(rng, cpu, riot, tia, *cartridge);
|
System system(rng, cpu, riot, tia, *cartridge);
|
||||||
|
|
||||||
consoleIO.myLeftControl = make_unique<Joystick>(Controller::Jack::Left, event, system);
|
consoleIO.myLeftControl = make_unique<Joystick>(Controller::Jack::Left, event, system);
|
||||||
|
|
|
@ -362,7 +362,7 @@ void Settings::validate()
|
||||||
if(s != "bgopry") setValue("tia.dbgcolors", "roygpb");
|
if(s != "bgopry") setValue("tia.dbgcolors", "roygpb");
|
||||||
|
|
||||||
s = getString("tv.phosphor");
|
s = getString("tv.phosphor");
|
||||||
if(s != "always" && s != "byrom") setValue("tv.phosphor", "byrom");
|
if(s != "always" && s != "byrom" && s != "auto") setValue("tv.phosphor", "byrom");
|
||||||
|
|
||||||
i = getInt("tv.phosblend");
|
i = getInt("tv.phosblend");
|
||||||
if(i < 0 || i > 100) setValue("tv.phosblend", "50");
|
if(i < 0 || i > 100) setValue("tv.phosblend", "50");
|
||||||
|
@ -576,7 +576,8 @@ void Settings::usage()
|
||||||
<< " -tia.correct_aspect <1|0> Enable aspect ratio correct scaling\n\n"
|
<< " -tia.correct_aspect <1|0> Enable aspect ratio correct scaling\n\n"
|
||||||
<< " -tv.filter <0-5> Set TV effects off (0) or to specified mode\n"
|
<< " -tv.filter <0-5> Set TV effects off (0) or to specified mode\n"
|
||||||
<< " (1-5)\n"
|
<< " (1-5)\n"
|
||||||
<< " -tv.phosphor <always|byrom> When to use phosphor mode\n"
|
<< " -tv.phosphor <always|auto|> When to use phosphor mode\n"
|
||||||
|
<< " byrom\n"
|
||||||
<< " -tv.phosblend <0-100> Set default blend level in phosphor mode\n"
|
<< " -tv.phosblend <0-100> Set default blend level in phosphor mode\n"
|
||||||
<< " -tv.scanlines <0-100> Set scanline intensity to percentage\n"
|
<< " -tv.scanlines <0-100> Set scanline intensity to percentage\n"
|
||||||
<< " (0 disables completely)\n"
|
<< " (0 disables completely)\n"
|
||||||
|
|
|
@ -63,10 +63,11 @@ static constexpr uInt8 resxLateHblankThreshold = TIAConstants::H_CYCLES - 3;
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
TIA::TIA(ConsoleIO& console, const ConsoleTimingProvider& timingProvider,
|
TIA::TIA(ConsoleIO& console, const ConsoleTimingProvider& timingProvider,
|
||||||
Settings& settings)
|
Settings& settings, const onPhosphorCallback callback)
|
||||||
: myConsole{console},
|
: myConsole{console},
|
||||||
myTimingProvider{timingProvider},
|
myTimingProvider{timingProvider},
|
||||||
mySettings{settings},
|
mySettings{settings},
|
||||||
|
myPhosphorCallback{callback},
|
||||||
myPlayfield{~CollisionMask::playfield & 0x7FFF},
|
myPlayfield{~CollisionMask::playfield & 0x7FFF},
|
||||||
myMissile0{~CollisionMask::missile0 & 0x7FFF},
|
myMissile0{~CollisionMask::missile0 & 0x7FFF},
|
||||||
myMissile1{~CollisionMask::missile1 & 0x7FFF},
|
myMissile1{~CollisionMask::missile1 & 0x7FFF},
|
||||||
|
@ -186,6 +187,12 @@ void TIA::initialize()
|
||||||
myFrontBuffer.fill(0);
|
myFrontBuffer.fill(0);
|
||||||
myFramebuffer.fill(0);
|
myFramebuffer.fill(0);
|
||||||
|
|
||||||
|
memset(&myPosP0, 0, sizeof(ObjectPos));
|
||||||
|
memset(&myPosP1, 0, sizeof(ObjectPos));
|
||||||
|
memset(&myPosM0, 0, sizeof(ObjectPos));
|
||||||
|
memset(&myPosM1, 0, sizeof(ObjectPos));
|
||||||
|
memset(&myPosBL, 0, sizeof(ObjectPos));
|
||||||
|
|
||||||
applyDeveloperSettings();
|
applyDeveloperSettings();
|
||||||
|
|
||||||
// Must be done last, after all other items have reset
|
// Must be done last, after all other items have reset
|
||||||
|
@ -193,6 +200,8 @@ void TIA::initialize()
|
||||||
setFixedColorPalette(mySettings.getString("tia.dbgcolors"));
|
setFixedColorPalette(mySettings.getString("tia.dbgcolors"));
|
||||||
enableFixedColors(
|
enableFixedColors(
|
||||||
mySettings.getBool(devSettings ? "dev.debugcolors" : "plr.debugcolors"));
|
mySettings.getBool(devSettings ? "dev.debugcolors" : "plr.debugcolors"));
|
||||||
|
myAutoPhosphorEnabled = mySettings.getString("tv.phosphor") == "auto";
|
||||||
|
myAutoPhosphorActive = false;
|
||||||
|
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
createAccessArrays();
|
createAccessArrays();
|
||||||
|
@ -1396,6 +1405,83 @@ void TIA::onFrameComplete()
|
||||||
|
|
||||||
myFrontBufferScanlines = scanlinesLastFrame();
|
myFrontBufferScanlines = scanlinesLastFrame();
|
||||||
|
|
||||||
|
if(myAutoPhosphorEnabled)
|
||||||
|
{
|
||||||
|
static constexpr int MIN_FLICKER_DELTA = 6;
|
||||||
|
static constexpr int MAX_FLICKER_DELTA = TIAConstants::H_PIXEL - MIN_FLICKER_DELTA;
|
||||||
|
static constexpr int MIN_DIFF = 4;
|
||||||
|
static constexpr int PHOSPHOR_FRAMES = 8;
|
||||||
|
|
||||||
|
int diffCount[FLICKER_FRAMES - 1];
|
||||||
|
|
||||||
|
//cerr << missingScanlines << ", " << myFrontBufferScanlines << " | ";
|
||||||
|
//cerr << myFlickerFrame << ": ";
|
||||||
|
for(int frame = 0; frame < FLICKER_FRAMES - 1; ++frame)
|
||||||
|
{
|
||||||
|
int otherFrame = (myFlickerFrame + frame + 1) % FLICKER_FRAMES;
|
||||||
|
//cerr << otherFrame << " ";
|
||||||
|
// TODO:
|
||||||
|
// - differentiate fast movement and flicker
|
||||||
|
// - movement is directional
|
||||||
|
// - flicker goes back and forth
|
||||||
|
// - ignore disabled objects
|
||||||
|
diffCount[frame] = 0;
|
||||||
|
for(uInt32 y = 0; y < myFrontBufferScanlines; ++y)
|
||||||
|
{
|
||||||
|
int delta;
|
||||||
|
delta = std::abs(myPosP0[y][myFlickerFrame] - myPosP0[y][otherFrame]);
|
||||||
|
if(delta >= MIN_FLICKER_DELTA && delta <= MAX_FLICKER_DELTA)
|
||||||
|
++diffCount[frame];
|
||||||
|
delta = std::abs(myPosP1[y][myFlickerFrame] - myPosP1[y][otherFrame]);
|
||||||
|
if(delta >= MIN_FLICKER_DELTA && delta <= MAX_FLICKER_DELTA)
|
||||||
|
++diffCount[frame];
|
||||||
|
delta = std::abs(myPosM0[y][myFlickerFrame] - myPosM0[y][otherFrame]);
|
||||||
|
if(delta >= MIN_FLICKER_DELTA && delta <= MAX_FLICKER_DELTA)
|
||||||
|
++diffCount[frame];
|
||||||
|
delta = std::abs(myPosM1[y][myFlickerFrame] - myPosM1[y][otherFrame]);
|
||||||
|
if(delta >= MIN_FLICKER_DELTA && delta <= MAX_FLICKER_DELTA)
|
||||||
|
++diffCount[frame];
|
||||||
|
delta = std::abs(myPosBL[y][myFlickerFrame] - myPosBL[y][otherFrame]);
|
||||||
|
if(delta >= MIN_FLICKER_DELTA && delta <= MAX_FLICKER_DELTA)
|
||||||
|
++diffCount[frame];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//cerr << ": ";
|
||||||
|
//for(int i = 0; i < FLICKER_FRAMES - 1; ++i)
|
||||||
|
// cerr << diffCount[i] << ", ";
|
||||||
|
if(diffCount[0] > MIN_DIFF &&
|
||||||
|
(diffCount[0] > diffCount[1] * 1.1 ||
|
||||||
|
diffCount[0] > diffCount[2] * 1.2 ||
|
||||||
|
diffCount[0] > diffCount[3] * 1.3))
|
||||||
|
{
|
||||||
|
if(myFlickerCount < PHOSPHOR_FRAMES)
|
||||||
|
{
|
||||||
|
myFlickerCount += 2; // enabled phosphor twice as fast
|
||||||
|
if(myFlickerCount >= PHOSPHOR_FRAMES && !myAutoPhosphorActive)
|
||||||
|
{
|
||||||
|
myAutoPhosphorActive = true;
|
||||||
|
myPhosphorCallback(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(myFlickerCount)
|
||||||
|
{
|
||||||
|
if(--myFlickerCount == 0 && myAutoPhosphorActive)
|
||||||
|
{
|
||||||
|
myAutoPhosphorActive = false;
|
||||||
|
myPhosphorCallback(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//cerr << "|" << myFlickerCount;
|
||||||
|
//if(myAutoPhosphorActive)
|
||||||
|
// cerr << " *** ON ***\n";
|
||||||
|
//else
|
||||||
|
// cerr << " off\n";
|
||||||
|
|
||||||
|
if(--myFlickerFrame < 0)
|
||||||
|
myFlickerFrame = FLICKER_FRAMES - 1;
|
||||||
|
}
|
||||||
|
|
||||||
++myFramesSinceLastRender;
|
++myFramesSinceLastRender;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1552,7 +1638,51 @@ FORCE_INLINE void TIA::nextLine()
|
||||||
myBall.nextLine();
|
myBall.nextLine();
|
||||||
myPlayfield.nextLine();
|
myPlayfield.nextLine();
|
||||||
|
|
||||||
if (myFrameManager->isRendering() && myFrameManager->getY() == 0) flushLineCache();
|
if(myFrameManager->isRendering())
|
||||||
|
{
|
||||||
|
if(myFrameManager->getY() == 0)
|
||||||
|
flushLineCache();
|
||||||
|
if(myAutoPhosphorEnabled)
|
||||||
|
{
|
||||||
|
// Test ROMs:
|
||||||
|
// - missing phosphor:
|
||||||
|
// x Princess Rescue: Lives display (~same x-position, different y-position)
|
||||||
|
// - QB: flicker sprite for multi color (same position, different shape and color)
|
||||||
|
// - Star Castle Arcade: vector font flicker (same position, different shape)
|
||||||
|
// - Omega Race: no phosphor enabled (flickers every 2nd frame)
|
||||||
|
// - Riddle of the Sphinx: shots (too small to be detected)
|
||||||
|
// - Missile Command: explosions
|
||||||
|
// - Yars' Revenge: shield, neutral zone (PF flicker)
|
||||||
|
//
|
||||||
|
// - unneccassary phosphor:
|
||||||
|
// - Gas Hog: before game starts (odd invisible position changes)
|
||||||
|
// x Turmoil: M1 rockets (gap between RESM1 and HMOVE?)
|
||||||
|
// x Fathom: seaweed (many sprites moving vertically)
|
||||||
|
// x FourPlay: game start (???)
|
||||||
|
// x Freeway: always (too many sprites?)
|
||||||
|
const uInt32 y = myFrameManager->getY();
|
||||||
|
//const int otherFrame = myFlickerFrame ^ 1;
|
||||||
|
//cerr << y << " ";
|
||||||
|
//if(myPlayer0.getGRPOld() != 0)
|
||||||
|
myPosP0[y][myFlickerFrame] = myPlayer0.getPosition();
|
||||||
|
//if(myPlayer1.getGRPOld() != 0)
|
||||||
|
myPosP1[y][myFlickerFrame] = myPlayer1.getPosition();
|
||||||
|
//if(myMissile0.isOn())
|
||||||
|
myPosM0[y][myFlickerFrame] = myMissile0.getPosition();
|
||||||
|
//else
|
||||||
|
// myPosM0[y][myFlickerFrame] = myPosM0[y][otherFrame];
|
||||||
|
//if(myMissile1.isOn())
|
||||||
|
myPosM1[y][myFlickerFrame] = myMissile1.getPosition();
|
||||||
|
//else
|
||||||
|
// myPosM1[y][myFlickerFrame] = myPosM1[y][otherFrame];
|
||||||
|
//if(myBall.isOn())
|
||||||
|
myPosBL[y][myFlickerFrame] = myBall.getPosition();
|
||||||
|
//else
|
||||||
|
// myPosBL[y][myFlickerFrame] = myPosBL[y][otherFrame];
|
||||||
|
|
||||||
|
//cerr << int(myPlayer0.getPosition()) << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mySystem->m6502().clearHaltRequest();
|
mySystem->m6502().clearHaltRequest();
|
||||||
}
|
}
|
||||||
|
@ -1574,6 +1704,15 @@ void TIA::cloneLastLine()
|
||||||
|
|
||||||
std::copy_n(myBackBuffer.begin() + (y - 1) * TIAConstants::H_PIXEL,
|
std::copy_n(myBackBuffer.begin() + (y - 1) * TIAConstants::H_PIXEL,
|
||||||
TIAConstants::H_PIXEL, myBackBuffer.begin() + y * TIAConstants::H_PIXEL);
|
TIAConstants::H_PIXEL, myBackBuffer.begin() + y * TIAConstants::H_PIXEL);
|
||||||
|
|
||||||
|
if(myAutoPhosphorEnabled)
|
||||||
|
{
|
||||||
|
myPosP0[y][myFlickerFrame] = myPosP0[y - 1][myFlickerFrame];
|
||||||
|
myPosP1[y][myFlickerFrame] = myPosP1[y - 1][myFlickerFrame];
|
||||||
|
myPosM0[y][myFlickerFrame] = myPosM0[y - 1][myFlickerFrame];
|
||||||
|
myPosM1[y][myFlickerFrame] = myPosM1[y - 1][myFlickerFrame];
|
||||||
|
myPosBL[y][myFlickerFrame] = myPosBL[y - 1][myFlickerFrame];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,8 @@ class TIA : public Device
|
||||||
friend class TIADebug;
|
friend class TIADebug;
|
||||||
friend class RiotDebug;
|
friend class RiotDebug;
|
||||||
|
|
||||||
|
using onPhosphorCallback = std::function<void(bool)>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create a new TIA for the specified console
|
Create a new TIA for the specified console
|
||||||
|
|
||||||
|
@ -116,7 +118,7 @@ class TIA : public Device
|
||||||
@param settings The settings object for this TIA device
|
@param settings The settings object for this TIA device
|
||||||
*/
|
*/
|
||||||
TIA(ConsoleIO& console, const ConsoleTimingProvider& timingProvider,
|
TIA(ConsoleIO& console, const ConsoleTimingProvider& timingProvider,
|
||||||
Settings& settings);
|
Settings& settings, const onPhosphorCallback callback);
|
||||||
~TIA() override = default;
|
~TIA() override = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -277,6 +279,8 @@ class TIA : public Device
|
||||||
Enables/disables color-loss for PAL modes only.
|
Enables/disables color-loss for PAL modes only.
|
||||||
|
|
||||||
@param enabled Whether to enable or disable PAL color-loss mode
|
@param enabled Whether to enable or disable PAL color-loss mode
|
||||||
|
|
||||||
|
@return True if color-loss got enabled
|
||||||
*/
|
*/
|
||||||
bool enableColorLoss(bool enabled);
|
bool enableColorLoss(bool enabled);
|
||||||
|
|
||||||
|
@ -294,6 +298,32 @@ class TIA : public Device
|
||||||
*/
|
*/
|
||||||
bool colorLossActive() const { return myColorLossActive; }
|
bool colorLossActive() const { return myColorLossActive; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enables/disables auto-phosphor.
|
||||||
|
|
||||||
|
@param enabled Whether to enable or disable auto-phosphor mode
|
||||||
|
*/
|
||||||
|
void enableAutoPhosphor(bool enabled)
|
||||||
|
{
|
||||||
|
myAutoPhosphorEnabled = enabled;
|
||||||
|
if(!enabled)
|
||||||
|
myAutoPhosphorActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Answers whether auto-phosphor is enabled.
|
||||||
|
|
||||||
|
@return Auto-phosphor is enabled
|
||||||
|
*/
|
||||||
|
bool autoPhosphorEnabled() const { return myAutoPhosphorEnabled; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Answers whether auto-phosphor is active.
|
||||||
|
|
||||||
|
@return Auto-phosphor is acitve
|
||||||
|
*/
|
||||||
|
bool autoPhosphorActive() const { return myAutoPhosphorActive; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Answers the current color clock we've gotten to on this scanline.
|
Answers the current color clock we've gotten to on this scanline.
|
||||||
|
|
||||||
|
@ -965,7 +995,17 @@ class TIA : public Device
|
||||||
bool myColorLossEnabled{false};
|
bool myColorLossEnabled{false};
|
||||||
bool myColorLossActive{false};
|
bool myColorLossActive{false};
|
||||||
|
|
||||||
std::array<uInt32, 16> myColorCounts;
|
/**
|
||||||
|
* Auto-phosphor detection variables.
|
||||||
|
*/
|
||||||
|
bool myAutoPhosphorEnabled{true};
|
||||||
|
bool myAutoPhosphorActive{true};
|
||||||
|
static constexpr int FLICKER_FRAMES = 1 + 4; // compare current frame with previous 4 frames
|
||||||
|
using ObjectPos = BSPF::array2D<uInt8, TIAConstants::frameBufferHeight, FLICKER_FRAMES>;
|
||||||
|
ObjectPos myPosP0, myPosP1, myPosM0, myPosM1, myPosBL;
|
||||||
|
int myFlickerFrame{0};
|
||||||
|
int myFlickerCount{0};
|
||||||
|
onPhosphorCallback myPhosphorCallback;
|
||||||
|
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -160,7 +160,7 @@ void GameInfoDialog::addEmulationTab()
|
||||||
// Phosphor
|
// Phosphor
|
||||||
ypos += lineHeight + VGAP;
|
ypos += lineHeight + VGAP;
|
||||||
myPhosphor = new CheckboxWidget(myTab, _font, HBORDER, ypos + 1,
|
myPhosphor = new CheckboxWidget(myTab, _font, HBORDER, ypos + 1,
|
||||||
"Phosphor (enabled for all ROMs)", kPhosphorChanged);
|
"Phosphor (auto-enabled for all ROMs)", kPhosphorChanged);
|
||||||
myPhosphor->setToolTip(Event::TogglePhosphor);
|
myPhosphor->setToolTip(Event::TogglePhosphor);
|
||||||
wid.push_back(myPhosphor);
|
wid.push_back(myPhosphor);
|
||||||
|
|
||||||
|
@ -770,7 +770,6 @@ void GameInfoDialog::loadEmulationProperties(const Properties& props)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
myTypeDetected->setLabel(bsDetected);
|
myTypeDetected->setLabel(bsDetected);
|
||||||
updateMultiCart();
|
|
||||||
|
|
||||||
// Start bank
|
// Start bank
|
||||||
VarList::push_back(items, "Auto", "AUTO");
|
VarList::push_back(items, "Auto", "AUTO");
|
||||||
|
@ -806,10 +805,13 @@ void GameInfoDialog::loadEmulationProperties(const Properties& props)
|
||||||
|
|
||||||
// if phosphor is always enabled, disable game specific phosphor settings
|
// if phosphor is always enabled, disable game specific phosphor settings
|
||||||
const bool alwaysPhosphor = instance().settings().getString("tv.phosphor") == "always";
|
const bool alwaysPhosphor = instance().settings().getString("tv.phosphor") == "always";
|
||||||
|
const bool autoPhosphor = instance().settings().getString("tv.phosphor") == "auto";
|
||||||
const bool usePhosphor = props.get(PropType::Display_Phosphor) == "YES";
|
const bool usePhosphor = props.get(PropType::Display_Phosphor) == "YES";
|
||||||
myPhosphor->setState(usePhosphor);
|
myPhosphor->setState(usePhosphor);
|
||||||
if (alwaysPhosphor)
|
if (alwaysPhosphor)
|
||||||
myPhosphor->setLabel("Phosphor (enabled for all ROMs)");
|
myPhosphor->setLabel("Phosphor (enabled for all ROMs");
|
||||||
|
else if (autoPhosphor)
|
||||||
|
myPhosphor->setLabel("Phosphor (auto-enabled for all ROMs)");
|
||||||
else
|
else
|
||||||
myPhosphor->setLabel("Phosphor");
|
myPhosphor->setLabel("Phosphor");
|
||||||
|
|
||||||
|
@ -823,6 +825,8 @@ void GameInfoDialog::loadEmulationProperties(const Properties& props)
|
||||||
myVCenter->setValueUnit(vcenter ? "px" : "");
|
myVCenter->setValueUnit(vcenter ? "px" : "");
|
||||||
|
|
||||||
mySound->setState(props.get(PropType::Cart_Sound) == "STEREO");
|
mySound->setState(props.get(PropType::Cart_Sound) == "STEREO");
|
||||||
|
|
||||||
|
updateMultiCart();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -1191,9 +1195,9 @@ void GameInfoDialog::updateMultiCart()
|
||||||
myFormat->setEnabled(!isMulti);
|
myFormat->setEnabled(!isMulti);
|
||||||
|
|
||||||
// if phosphor is always enabled, disable game specific phosphor settings
|
// if phosphor is always enabled, disable game specific phosphor settings
|
||||||
const bool alwaysPhosphor = isMulti || instance().settings().getString("tv.phosphor") == "always";
|
const bool globalPhosphor = isMulti || instance().settings().getString("tv.phosphor") != "byrom";
|
||||||
myPhosphor->setEnabled(!alwaysPhosphor);
|
myPhosphor->setEnabled(!globalPhosphor);
|
||||||
myPPBlend->setEnabled(!alwaysPhosphor && myPhosphor->getState());
|
myPPBlend->setEnabled(!globalPhosphor && myPhosphor->getState());
|
||||||
|
|
||||||
myVCenter->setEnabled(!isMulti);
|
myVCenter->setEnabled(!isMulti);
|
||||||
// if stereo is always enabled, disable game specific stereo setting
|
// if stereo is always enabled, disable game specific stereo setting
|
||||||
|
|
|
@ -377,11 +377,17 @@ void VideoAudioDialog::addTVEffectsTab()
|
||||||
CREATE_CUSTOM_SLIDERS(Bleed, "Bleeding ", 0)
|
CREATE_CUSTOM_SLIDERS(Bleed, "Bleeding ", 0)
|
||||||
|
|
||||||
ypos += VGAP * 3;
|
ypos += VGAP * 3;
|
||||||
|
|
||||||
xpos = HBORDER;
|
xpos = HBORDER;
|
||||||
|
|
||||||
// TV Phosphor effect
|
// TV Phosphor effect
|
||||||
myTVPhosphor = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Phosphor for all ROMs", kPhosphorChanged);
|
items.clear();
|
||||||
|
VarList::push_back(items, "by ROM", "byrom");
|
||||||
|
VarList::push_back(items, "always", "always");
|
||||||
|
VarList::push_back(items, "auto", "auto");
|
||||||
|
myTVPhosphor = new PopUpWidget(myTab, _font, xpos, ypos,
|
||||||
|
_font.getStringWidth("by ROM"), lineHeight,
|
||||||
|
items, "Phosphor ", 0, kPhosphorChanged);
|
||||||
|
myTVPhosphor->setToolTip(Event::PhosphorModeDecrease, Event::PhosphorModeIncrease);
|
||||||
wid.push_back(myTVPhosphor);
|
wid.push_back(myTVPhosphor);
|
||||||
ypos += lineHeight + VGAP / 2;
|
ypos += lineHeight + VGAP / 2;
|
||||||
|
|
||||||
|
@ -754,7 +760,7 @@ void VideoAudioDialog::loadConfig()
|
||||||
loadTVAdjustables(NTSCFilter::Preset::CUSTOM);
|
loadTVAdjustables(NTSCFilter::Preset::CUSTOM);
|
||||||
|
|
||||||
// TV phosphor mode & blend
|
// TV phosphor mode & blend
|
||||||
myTVPhosphor->setState(settings.getString("tv.phosphor") == "always");
|
myTVPhosphor->setSelected(settings.getString("tv.phosphor"), "byrom");
|
||||||
myTVPhosLevel->setValue(settings.getInt("tv.phosblend"));
|
myTVPhosLevel->setValue(settings.getInt("tv.phosblend"));
|
||||||
handlePhosphorChange();
|
handlePhosphorChange();
|
||||||
|
|
||||||
|
@ -889,7 +895,7 @@ void VideoAudioDialog::saveConfig()
|
||||||
NTSCFilter::saveConfig(settings);
|
NTSCFilter::saveConfig(settings);
|
||||||
|
|
||||||
// TV phosphor mode & blend
|
// TV phosphor mode & blend
|
||||||
settings.setValue("tv.phosphor", myTVPhosphor->getState() ? "always" : "byrom");
|
settings.setValue("tv.phosphor", myTVPhosphor->getSelectedTag());
|
||||||
settings.setValue("tv.phosblend", myTVPhosLevel->getValueLabel() == "Off"
|
settings.setValue("tv.phosblend", myTVPhosLevel->getValueLabel() == "Off"
|
||||||
? "0" : myTVPhosLevel->getValueLabel());
|
? "0" : myTVPhosLevel->getValueLabel());
|
||||||
|
|
||||||
|
@ -1029,7 +1035,7 @@ void VideoAudioDialog::setDefaults()
|
||||||
myTVMode->setSelected("0", "0");
|
myTVMode->setSelected("0", "0");
|
||||||
|
|
||||||
// TV phosphor mode & blend
|
// TV phosphor mode & blend
|
||||||
myTVPhosphor->setState(false);
|
myTVPhosphor->setSelected("byrom");
|
||||||
myTVPhosLevel->setValue(50);
|
myTVPhosLevel->setValue(50);
|
||||||
|
|
||||||
// TV scanline intensity & mask
|
// TV scanline intensity & mask
|
||||||
|
@ -1209,7 +1215,7 @@ void VideoAudioDialog::handleOverscanChange()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void VideoAudioDialog::handlePhosphorChange()
|
void VideoAudioDialog::handlePhosphorChange()
|
||||||
{
|
{
|
||||||
myTVPhosLevel->setEnabled(myTVPhosphor->getState());
|
myTVPhosLevel->setEnabled(myTVPhosphor->getSelectedTag() != "byrom");
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -96,7 +96,7 @@ class VideoAudioDialog : public Dialog
|
||||||
SliderWidget* myTVBleed{nullptr};
|
SliderWidget* myTVBleed{nullptr};
|
||||||
|
|
||||||
// TV phosphor effect
|
// TV phosphor effect
|
||||||
CheckboxWidget* myTVPhosphor{nullptr};
|
PopUpWidget* myTVPhosphor{nullptr};
|
||||||
SliderWidget* myTVPhosLevel{nullptr};
|
SliderWidget* myTVPhosLevel{nullptr};
|
||||||
|
|
||||||
// TV scanline intensity and interpolation
|
// TV scanline intensity and interpolation
|
||||||
|
|
Loading…
Reference in New Issue