mirror of https://github.com/stella-emu/stella.git
added optional refresh rate adaption in fullscreen mode
This commit is contained in:
parent
63f1414007
commit
77f24947f0
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue