mirror of https://github.com/stella-emu/stella.git
implement emulation fullscreen overscan
This commit is contained in:
parent
5aab1afc7c
commit
94de76b78e
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue