added optional refresh rate adaption in fullscreen mode

This commit is contained in:
thrust26 2020-05-18 12:26:05 +02:00
parent 63f1414007
commit 77f24947f0
6 changed files with 95 additions and 0 deletions

View File

@ -340,9 +340,74 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
if(SDL_GetRendererInfo(myRenderer, &renderinfo) >= 0) if(SDL_GetRendererInfo(myRenderer, &renderinfo) >= 0)
myOSystem.settings().setValue("video", renderinfo.name); myOSystem.settings().setValue("video", renderinfo.name);
adaptRefreshRate();
return true; return true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferSDL2::adaptRefreshRate()
{
const bool adapt = myOSystem.settings().getBool("tia.refresh");
// adapt only in emulation (and debugger?) and fullscreen mode
// TODO: adapt while creating new window
if(adapt && fullScreen()
&& (myBufferType == BufferType::Emulator/* || myBufferType == BufferType::Debugger*/))
{
SDL_DisplayMode sdlMode;
if(SDL_GetWindowDisplayMode(myWindow, &sdlMode) != 0)
{
Logger::error("Display mode could not be retrieved");
return false;
}
const int currentRefreshRate = sdlMode.refresh_rate;
const string format = myOSystem.console().getFormatString();
const bool isNtsc = format == "NTSC" || format == "PAL60" || format == "SECAM60";
sdlMode.refresh_rate = isNtsc ? 60 : 50; // TODO: check for multiples e.g. 120/100 too
if(currentRefreshRate != sdlMode.refresh_rate)
{
const int display = SDL_GetWindowDisplayIndex(myWindow);
SDL_DisplayMode closestSdlMode;
if(SDL_GetClosestDisplayMode(display, &sdlMode, &closestSdlMode) == NULL)
{
Logger::error("Closest display mode could not be retrieved");
return false;
}
// Note: Modes are scanned with size being first priority,
// therefore the size will never change.
// Only change if the display supports a better refresh rate
if(currentRefreshRate != closestSdlMode.refresh_rate)
{
// Switch to new mode
if(SDL_SetWindowDisplayMode(myWindow, &closestSdlMode) != 0)
{
Logger::error("Display refresh rate change failed");
return false;
}
// Any change only works in real fullscreen mode!
if(SDL_SetWindowFullscreen(myWindow, SDL_WINDOW_FULLSCREEN) != 0)
{
Logger::error("Display fullscreen change failed");
return false;
}
ostringstream msg;
msg << "Display refresh rate changed from " << currentRefreshRate << "Hz to "
<< closestSdlMode.refresh_rate << "Hz";
Logger::info(msg.str());
return true;
}
}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSDL2::setTitle(const string& title) void FrameBufferSDL2::setTitle(const string& title)
{ {

View File

@ -181,6 +181,14 @@ class FrameBufferSDL2 : public FrameBuffer
*/ */
bool setVideoMode(const string& title, const VideoMode& mode) override; bool setVideoMode(const string& title, const VideoMode& mode) override;
/**
Adapt display refresh rate to game refresh rate in (real) fullscreen mode
@return True if the refresh rate was changed
*/
bool adaptRefreshRate();
/** /**
This method is called to create a surface with the given attributes. This method is called to create a surface with the given attributes.

View File

@ -81,6 +81,13 @@ class FrameBuffer
} }
}; };
struct DisplayMode
{
uInt32 display;
Common::Size size;
uInt32 refresh_rate;
};
enum class BufferType { enum class BufferType {
None, None,
Launcher, Launcher,
@ -439,6 +446,7 @@ class FrameBuffer
virtual int scaleY(int y) const { return y; } virtual int scaleY(int y) const { return y; }
protected: protected:
/** /**
This method is called to query and initialize the video hardware This method is called to query and initialize the video hardware
for desktop and fullscreen resolution information. Since several for desktop and fullscreen resolution information. Since several

View File

@ -54,6 +54,7 @@ Settings::Settings()
setPermanent("tia.fs_stretch", "false"); setPermanent("tia.fs_stretch", "false");
setPermanent("tia.fs_overscan", "0"); setPermanent("tia.fs_overscan", "0");
setPermanent("tia.vsizeadjust", 0); setPermanent("tia.vsizeadjust", 0);
setPermanent("tia.refresh", "false");
setPermanent("tia.dbgcolors", "roygpb"); setPermanent("tia.dbgcolors", "roygpb");
// Palette options // Palette options
setPermanent("palette", PaletteHandler::SETTING_STANDARD); setPermanent("palette", PaletteHandler::SETTING_STANDARD);

View File

@ -166,9 +166,14 @@ void VideoAudioDialog::addDisplayTab()
myTVOverscan->setMinValue(0); myTVOverscan->setMaxValue(10); myTVOverscan->setMinValue(0); myTVOverscan->setMaxValue(10);
myTVOverscan->setTickmarkIntervals(2); myTVOverscan->setTickmarkIntervals(2);
wid.push_back(myTVOverscan); wid.push_back(myTVOverscan);
// Adapt refresh rate
ypos += lineHeight + VGAP; ypos += lineHeight + VGAP;
myRefreshAdjust = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Adapt refresh rate");
wid.push_back(myRefreshAdjust);
// Vertical size // Vertical size
ypos += lineHeight + VGAP;
myVSizeAdjust = myVSizeAdjust =
new SliderWidget(myTab, _font, xpos, ypos-1, swidth, lineHeight, new SliderWidget(myTab, _font, xpos, ypos-1, swidth, lineHeight,
"V-Size adjust", lwidth, kVSizeChanged, fontWidth * 7, "%", 0, true); "V-Size adjust", lwidth, kVSizeChanged, fontWidth * 7, "%", 0, true);
@ -176,6 +181,7 @@ void VideoAudioDialog::addDisplayTab()
myVSizeAdjust->setTickmarkIntervals(2); myVSizeAdjust->setTickmarkIntervals(2);
wid.push_back(myVSizeAdjust); wid.push_back(myVSizeAdjust);
// Add items for tab 0 // Add items for tab 0
addToFocusList(wid, myTab, tabID); addToFocusList(wid, myTab, tabID);
} }
@ -486,6 +492,8 @@ void VideoAudioDialog::loadConfig()
myUseStretch->setState(instance().settings().getBool("tia.fs_stretch")); myUseStretch->setState(instance().settings().getBool("tia.fs_stretch"));
// Fullscreen overscan setting // Fullscreen overscan setting
myTVOverscan->setValue(instance().settings().getInt("tia.fs_overscan")); myTVOverscan->setValue(instance().settings().getInt("tia.fs_overscan"));
// Adapt refresh rate
myRefreshAdjust->setState(instance().settings().getBool("tia.refresh"));
handleFullScreenChange(); handleFullScreenChange();
// Aspect ratio setting (NTSC and PAL) // Aspect ratio setting (NTSC and PAL)
@ -597,6 +605,8 @@ void VideoAudioDialog::saveConfig()
instance().settings().setValue("tia.fs_stretch", myUseStretch->getState()); instance().settings().setValue("tia.fs_stretch", myUseStretch->getState());
// Fullscreen overscan // Fullscreen overscan
instance().settings().setValue("tia.fs_overscan", myTVOverscan->getValueLabel()); instance().settings().setValue("tia.fs_overscan", myTVOverscan->getValueLabel());
// Adapt refresh rate
instance().settings().setValue("tia.refresh", myRefreshAdjust->getState());
// TIA zoom levels // TIA zoom levels
instance().settings().setValue("tia.zoom", myTIAZoom->getValue() / 100.0); instance().settings().setValue("tia.zoom", myTIAZoom->getValue() / 100.0);
@ -709,6 +719,7 @@ void VideoAudioDialog::setDefaults()
//myFullScreenMode->setSelectedIndex(0); //myFullScreenMode->setSelectedIndex(0);
myUseStretch->setState(false); myUseStretch->setState(false);
myTVOverscan->setValue(0); myTVOverscan->setValue(0);
myRefreshAdjust->setState(false);
myTIAZoom->setValue(300); myTIAZoom->setValue(300);
myVSizeAdjust->setValue(0); myVSizeAdjust->setValue(0);
@ -834,6 +845,7 @@ void VideoAudioDialog::handleFullScreenChange()
bool enable = myFullscreen->getState(); bool enable = myFullscreen->getState();
myUseStretch->setEnabled(enable); myUseStretch->setEnabled(enable);
myTVOverscan->setEnabled(enable); myTVOverscan->setEnabled(enable);
myRefreshAdjust->setEnabled(enable);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -74,6 +74,7 @@ class VideoAudioDialog : public Dialog
//PopUpWidget* myFullScreenMode; //PopUpWidget* myFullScreenMode;
CheckboxWidget* myUseStretch{nullptr}; CheckboxWidget* myUseStretch{nullptr};
SliderWidget* myTVOverscan{nullptr}; SliderWidget* myTVOverscan{nullptr};
CheckboxWidget* myRefreshAdjust{nullptr};
SliderWidget* myTIAZoom{nullptr}; SliderWidget* myTIAZoom{nullptr};
SliderWidget* myVSizeAdjust{nullptr}; SliderWidget* myVSizeAdjust{nullptr};