implement emulation fullscreen overscan

This commit is contained in:
thrust26 2019-05-14 22:44:48 +02:00
parent 5aab1afc7c
commit 94de76b78e
5 changed files with 71 additions and 19 deletions

View File

@ -137,10 +137,11 @@ bool FrameBuffer::initialize()
#endif
// Determine possible TIA windowed zoom levels
double overscan = 1 - myOSystem.settings().getInt("tia.fs_overscan") / 100.0;
uInt32 minZoom = 2 * hidpiScaleFactor();
uInt32 maxZoom = maxWindowSizeForScreen(
TIAConstants::viewableWidth, TIAConstants::viewableHeight,
myAbsDesktopSize.w, myAbsDesktopSize.h);
myAbsDesktopSize.w * overscan, myAbsDesktopSize.h * overscan);
for(uInt32 zoom = minZoom; zoom <= maxZoom; ++zoom)
{
ostringstream desc;
@ -874,6 +875,7 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
EventHandlerState state = myOSystem.eventHandler().state();
bool tiaMode = (state != EventHandlerState::DEBUGGER &&
state != EventHandlerState::LAUNCHER);
double overscan = 1 - myOSystem.settings().getInt("tia.fs_overscan") / 100.0;
// TIA mode allows zooming at integral factors in windowed modes,
// and also non-integral factors in fullscreen mode
@ -882,7 +884,7 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
// TIA windowed modes
uInt32 minZoom = 2 * hidpiScaleFactor();
uInt32 maxZoom = maxWindowSizeForScreen(baseWidth, baseHeight,
myAbsDesktopSize.w, myAbsDesktopSize.h);
myAbsDesktopSize.w * overscan, myAbsDesktopSize.h * overscan);
#if 0 // FIXME - does this apply any longer??
// Aspect ratio
@ -898,7 +900,7 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
desc << "Zoom " << zoom << "x";
VideoMode mode(baseWidth*zoom, baseHeight*zoom, baseWidth*zoom, baseHeight*zoom,
VideoMode::Stretch::Fill, desc.str(), zoom);
VideoMode::Stretch::Fill, overscan, desc.str(), zoom);
myWindowedModeList.add(mode);
}
@ -906,19 +908,19 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
for(uInt32 i = 0; i < myFullscreenDisplays.size(); ++i)
{
maxZoom = maxWindowSizeForScreen(baseWidth, baseHeight,
myFullscreenDisplays[i].w, myFullscreenDisplays[i].h);
myFullscreenDisplays[i].w * overscan, myFullscreenDisplays[i].h * overscan);
// Add both normal aspect and filled modes
// It's easier to define them both now, and simply switch between
// them when necessary
VideoMode mode1(baseWidth*maxZoom, baseHeight*maxZoom,
myFullscreenDisplays[i].w, myFullscreenDisplays[i].h,
VideoMode::Stretch::Preserve,
VideoMode::Stretch::Preserve, overscan,
"Preserve aspect, no stretch", maxZoom, i);
myFullscreenModeLists[i].add(mode1);
VideoMode mode2(baseWidth*maxZoom, baseHeight*maxZoom,
myFullscreenDisplays[i].w, myFullscreenDisplays[i].h,
VideoMode::Stretch::Fill,
VideoMode::Stretch::Fill, overscan,
"Ignore aspect, full stretch", maxZoom, i);
myFullscreenModeLists[i].add(mode2);
}
@ -932,8 +934,9 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
for(uInt32 i = 0; i < myFullscreenDisplays.size(); ++i)
{
myFullscreenModeLists[i].add(
VideoMode(baseWidth, baseHeight, myFullscreenDisplays[i].w, myFullscreenDisplays[i].h,
VideoMode::Stretch::None, "", 1, i)
VideoMode(baseWidth, baseHeight,
myFullscreenDisplays[i].w, myFullscreenDisplays[i].h,
VideoMode::Stretch::None, 1.0, "", 1, i)
);
}
}
@ -988,7 +991,7 @@ FrameBuffer::VideoMode::VideoMode()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBuffer::VideoMode::VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
Stretch smode, const string& desc,
Stretch smode, double overscan, const string& desc,
uInt32 zoomLevel, Int32 fsindex)
: stretch(smode),
description(desc),
@ -1011,6 +1014,7 @@ FrameBuffer::VideoMode::VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
if(fsIndex != -1)
{
//double overscan = 1 - myOSystem.settings().getInt("tia.fs_overscan") / 100.0;
switch(stretch)
{
case Stretch::Preserve:
@ -1025,19 +1029,21 @@ FrameBuffer::VideoMode::VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
else
stretchFactor = float(screen.h) / ih;
iw = uInt32(stretchFactor * iw);
ih = uInt32(stretchFactor * ih);
iw = uInt32(stretchFactor * iw) * overscan;
ih = uInt32(stretchFactor * ih) * overscan;
break;
}
case Stretch::Fill:
// Scale to all available space
iw = screen.w;
ih = screen.h;
iw = screen.w * overscan;
ih = screen.h * overscan;
break;
case Stretch::None:
// Don't do any scaling at all
// Don't do any scaling at all, but obey overscan
iw = std::min(iw, screen.w) * overscan;
ih = std::min(ih, screen.h) * overscan;
break;
}
}

View File

@ -67,7 +67,7 @@ class FrameBuffer
Int32 fsIndex;
VideoMode();
VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, Stretch smode,
VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, Stretch smode, double overscan = 1.0,
const string& desc = "", uInt32 zoomLevel = 1, Int32 fsindex = -1);
friend ostream& operator<<(ostream& os, const VideoMode& vm)

View File

@ -37,7 +37,6 @@ Settings::Settings()
setPermanent("video", "");
setPermanent("speed", "1.0");
setPermanent("vsync", "true");
setPermanent("fullscreen", "false");
setPermanent("center", "false");
setPermanent("palette", "standard");
setPermanent("uimessages", "true");
@ -47,7 +46,9 @@ Settings::Settings()
setPermanent("tia.inter", "false");
setPermanent("tia.aspectn", "100");
setPermanent("tia.aspectp", "100");
setPermanent("fullscreen", "false");
setPermanent("tia.fs_stretch", "false");
setPermanent("tia.fs_overscan", "0");
setPermanent("tia.dbgcolors", "roygpb");
// TV filtering options
@ -393,6 +394,7 @@ void Settings::usage() const
<< " -tia.aspectp <number> Scale TIA width by the given percentage in PAL\n"
<< " mode\n"
<< " -tia.fs_stretch <1|0> Stretch TIA image to fill fullscreen mode\n"
<< " -tia.fs_overscan <0-10> Add overscan to TIA image in fill fullscreen mode\n"
<< " -tia.dbgcolors <string> Debug colors to use for each object (see manual\n"
<< " for description)\n"
<< endl

View File

@ -180,7 +180,7 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
ypos = VBORDER;
// Fullscreen
myFullscreen = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Fullscreen");
myFullscreen = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Fullscreen", kFullScreenChanged);
wid.push_back(myFullscreen);
ypos += lineHeight + VGAP;
@ -191,8 +191,16 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
ypos += lineHeight + VGAP;*/
// FS stretch
myUseStretch = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Fullscreen stretch");
myUseStretch = new CheckboxWidget(myTab, font, xpos + INDENT, ypos + 1, "Stretch");
wid.push_back(myUseStretch);
ypos += lineHeight + VGAP;
// FS overscan
myUseOverscan = new SliderWidget(myTab, font, xpos + INDENT, ypos - 1, swidth, lineHeight,
"Overscan", font.getStringWidth("Overscan "), kOverscanChanged, fontWidth * 3, "%");
myUseOverscan->setMinValue(0); myUseOverscan->setMaxValue(10);
myUseOverscan->setTickmarkInterval(2);
wid.push_back(myUseOverscan);
ypos += (lineHeight + VGAP) * 2;
// Skip progress load bars for SuperCharger ROMs
@ -359,9 +367,10 @@ void VideoDialog::loadConfig()
myFullscreen->setState(instance().settings().getBool("fullscreen"));
/*string mode = instance().settings().getString("fullscreenmode");
myFullScreenMode->setSelected(mode);*/
// Fullscreen stretch setting
myUseStretch->setState(instance().settings().getBool("tia.fs_stretch"));
// Fullscreen overscan setting
myUseOverscan->setValue(instance().settings().getInt("tia.fs_overscan"));
// Use sync to vertical blank
myUseVSync->setState(instance().settings().getBool("vsync"));
@ -433,6 +442,8 @@ void VideoDialog::saveConfig()
myFullScreenMode->getSelectedTag().toString());*/
// Fullscreen stretch setting
instance().settings().setValue("tia.fs_stretch", myUseStretch->getState());
// Fullscreen overscan
instance().settings().setValue("tia.fs_overscan", myUseOverscan->getValueLabel());
// Use sync to vertical blank
instance().settings().setValue("vsync", myUseVSync->getState());
@ -570,6 +581,26 @@ void VideoDialog::loadTVAdjustables(NTSCFilter::Preset preset)
myTVGamma->setValue(adj.gamma);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::handleFullScreenChange()
{
bool enable = myFullscreen->getState();
myUseStretch->setEnabled(enable);
myUseOverscan->setEnabled(enable);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::handleOverscanChange()
{
if (myUseOverscan->getValue() == 0)
{
myUseOverscan->setValueLabel("Off");
myUseOverscan->setValueUnit("");
}
else
myUseOverscan->setValueUnit("%");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::handlePhosphorChange()
{
@ -595,6 +626,14 @@ void VideoDialog::handleCommand(CommandSender* sender, int cmd,
mySpeed->setValueLabel(formatSpeed(mySpeed->getValue()));
break;
case kFullScreenChanged:
handleFullScreenChange();
break;
case kOverscanChanged:
handleOverscanChange();
break;
case kTVModeChanged:
handleTVModeChange(NTSCFilter::Preset(myTVMode->getSelectedTag().toInt()));
break;

View File

@ -45,6 +45,8 @@ class VideoDialog : public Dialog
void handleTVModeChange(NTSCFilter::Preset);
void loadTVAdjustables(NTSCFilter::Preset preset);
void handleFullScreenChange();
void handleOverscanChange();
void handlePhosphorChange();
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
@ -63,6 +65,7 @@ class VideoDialog : public Dialog
CheckboxWidget* myFullscreen;
//PopUpWidget* myFullScreenMode;
CheckboxWidget* myUseStretch;
SliderWidget* myUseOverscan;
CheckboxWidget* myUseVSync;
CheckboxWidget* myUIMessages;
CheckboxWidget* myCenter;
@ -99,6 +102,8 @@ class VideoDialog : public Dialog
enum {
kSpeedupChanged = 'VDSp',
kFullScreenChanged = 'VDFs',
kOverscanChanged = 'VDOv',
kTVModeChanged = 'VDtv',
kCloneCompositeCmd = 'CLcp',