mirror of https://github.com/stella-emu/stella.git
handle rounded refresh rates like 59.94 Hz
disable refresh adjust option for macOS
This commit is contained in:
parent
94b1800cc4
commit
137ba30593
|
@ -234,8 +234,6 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
|
|||
return false;
|
||||
|
||||
const bool fullScreen = mode.fsIndex != -1;
|
||||
const bool shouldAdapt = fullScreen && myOSystem.settings().getBool("tia.fs_refresh")
|
||||
&& gameRefreshRate() && refreshRate() % gameRefreshRate() != 0;
|
||||
bool forceCreateRenderer = false;
|
||||
|
||||
// Get windowed window's last display
|
||||
|
@ -272,8 +270,17 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
|
|||
posY = BSPF::clamp(posY, y0 + 50, y1 - 50);
|
||||
}
|
||||
|
||||
#ifndef BSPF_MACOS
|
||||
// macOS does not allow to change the display refresh rate
|
||||
SDL_DisplayMode adaptedSdlMode;
|
||||
const bool shouldAdapt = fullScreen && myOSystem.settings().getBool("tia.fs_refresh")
|
||||
&& gameRefreshRate()
|
||||
// take care of 59.94 Hz
|
||||
&& refreshRate() % gameRefreshRate() != 0 && refreshRate() % (gameRefreshRate() - 1) != 0;
|
||||
const bool adaptRefresh = shouldAdapt && adaptRefreshRate(displayIndex, adaptedSdlMode);
|
||||
#else
|
||||
const bool adaptRefresh = false;
|
||||
#endif
|
||||
const uInt32 flags = SDL_WINDOW_ALLOW_HIGHDPI
|
||||
| (fullScreen ? adaptRefresh ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
||||
|
||||
|
@ -331,6 +338,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
|
|||
|
||||
setWindowIcon();
|
||||
}
|
||||
#ifndef BSPF_MACOS
|
||||
if(adaptRefresh)
|
||||
{
|
||||
// Switch to mode for adapted refresh rate
|
||||
|
@ -346,10 +354,11 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
|
|||
Logger::info(msg.str());
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
return createRenderer(forceCreateRenderer);
|
||||
}
|
||||
|
||||
#ifndef BSPF_MACOS
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adaptedSdlMode)
|
||||
{
|
||||
|
@ -363,7 +372,10 @@ bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adap
|
|||
|
||||
const int currentRefreshRate = sdlMode.refresh_rate;
|
||||
const int wantedRefreshRate = gameRefreshRate();
|
||||
float factor = float(currentRefreshRate) / wantedRefreshRate;
|
||||
// Take care of rounded refresh rates (e.g. 59.94 Hz)
|
||||
float factor = std::min(float(currentRefreshRate) / wantedRefreshRate,
|
||||
float(currentRefreshRate) / (wantedRefreshRate - 1));
|
||||
// Calculate difference taking care of integer factors (e.g. 100/120)
|
||||
float bestDiff = std::abs(factor - std::round(factor)) / factor;
|
||||
bool adapt = false;
|
||||
|
||||
|
@ -382,6 +394,8 @@ bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adap
|
|||
return adapt;
|
||||
}
|
||||
factor = float(closestSdlMode.refresh_rate) / sdlMode.refresh_rate;
|
||||
factor = std::min(float(sdlMode.refresh_rate) / sdlMode.refresh_rate,
|
||||
float(sdlMode.refresh_rate) / (sdlMode.refresh_rate - 1));
|
||||
const float diff = std::abs(factor - std::round(factor)) / factor;
|
||||
if(diff < bestDiff)
|
||||
{
|
||||
|
@ -399,7 +413,74 @@ bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adap
|
|||
|
||||
// Only change if the display supports a better refresh rate
|
||||
return adapt;
|
||||
|
||||
#if 0
|
||||
// Adapting resfresh rate and display size
|
||||
const bool hiDpi = myOSystem.settings().getBool("hidpi");
|
||||
const float mult = float(font().getFontHeight()) / getFontDesc("medium").height * hiDpi ? 2 : 1;
|
||||
const Int32 minWidth = FBMinimum::Width * mult;
|
||||
const Int32 minHeight = FBMinimum::Height * mult;
|
||||
SDL_DisplayMode sdlMode;
|
||||
|
||||
if(SDL_GetCurrentDisplayMode(displayIndex, &sdlMode) != 0)
|
||||
{
|
||||
Logger::error("ERROR: Display mode could not be retrieved");
|
||||
return false;
|
||||
}
|
||||
|
||||
const int numModes = SDL_GetNumDisplayModes(displayIndex);
|
||||
if(numModes < 0)
|
||||
{
|
||||
Logger::error("ERROR: Number of display modes could not be retrieved");
|
||||
return false;
|
||||
}
|
||||
|
||||
const int currentRefreshRate = sdlMode.refresh_rate;
|
||||
const int wantedRefreshRate = gameRefreshRate();
|
||||
// Take care of rounded refresh rates (e.g. 59.94)
|
||||
float factor = std::min(float(currentRefreshRate) / wantedRefreshRate,
|
||||
float(currentRefreshRate) / (wantedRefreshRate - 1));
|
||||
// Calculate difference taking care of integer factors (e.g. 100/120)
|
||||
float bestDiff = std::abs(factor - std::round(factor)) / factor;
|
||||
bool adapt = false;
|
||||
|
||||
for(int mode = 0; mode < numModes; ++mode)
|
||||
{
|
||||
// Note: Display modes returned are sorted by width, height,... refresh_rate
|
||||
if(SDL_GetDisplayMode(displayIndex, mode, &sdlMode) != 0)
|
||||
{
|
||||
Logger::error("ERROR: Display modes could not be retrieved");
|
||||
return false;
|
||||
}
|
||||
// skip too small modes
|
||||
if(sdlMode.w < minWidth || sdlMode.h < minHeight)
|
||||
continue;
|
||||
|
||||
cerr << sdlMode.w << "x" << sdlMode.h << " " << sdlMode.refresh_rate << " Hz" << endl;
|
||||
|
||||
factor = std::min(float(sdlMode.refresh_rate) / wantedRefreshRate,
|
||||
float(sdlMode.refresh_rate) / (wantedRefreshRate - 1));
|
||||
const float diff = std::abs(factor - std::round(factor)) / factor;
|
||||
if(diff < bestDiff)
|
||||
{
|
||||
bestDiff = diff;
|
||||
adaptedSdlMode = sdlMode;
|
||||
adapt = true;
|
||||
}
|
||||
}
|
||||
|
||||
cerr << "refresh rate adapt ";
|
||||
if(adapt)
|
||||
cerr << "required (" << currentRefreshRate << " Hz -> " << adaptedSdlMode.refresh_rate << " Hz)";
|
||||
else
|
||||
cerr << "not required/possible";
|
||||
cerr << endl;
|
||||
|
||||
// Only change if the display supports a better refresh rate
|
||||
return adapt;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferSDL2::createRenderer(bool force)
|
||||
|
@ -540,7 +621,7 @@ int FrameBufferSDL2::gameRefreshRate() const
|
|||
const string format = myOSystem.console().getFormatString();
|
||||
const bool isNtsc = format == "NTSC" || format == "PAL60" || format == "SECAM60";
|
||||
|
||||
return isNtsc ? 60 : 50;
|
||||
return isNtsc ? 60 : 50; // The code will take care of 59/49 Hz
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -181,6 +181,7 @@ class FrameBufferSDL2 : public FrameBuffer
|
|||
*/
|
||||
bool setVideoMode(const string& title, const VideoMode& mode) override;
|
||||
|
||||
#ifndef BSPF_MACOS
|
||||
/**
|
||||
Checks if the display refresh rate should be adapted to game refresh rate in (real) fullscreen mode
|
||||
|
||||
|
@ -190,6 +191,7 @@ class FrameBufferSDL2 : public FrameBuffer
|
|||
@return True if the refresh rate should be changed
|
||||
*/
|
||||
bool adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adaptedSdlMode);
|
||||
#endif
|
||||
|
||||
/**
|
||||
Create a new renderer if required
|
||||
|
|
|
@ -153,10 +153,12 @@ void VideoAudioDialog::addDisplayTab()
|
|||
myUseStretch = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Stretch");
|
||||
wid.push_back(myUseStretch);
|
||||
|
||||
#ifndef BSPF_MACOS
|
||||
// Adapt refresh rate
|
||||
ypos += lineHeight + VGAP;
|
||||
myRefreshAdapt = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Adapt display refresh rate");
|
||||
wid.push_back(myRefreshAdapt);
|
||||
#endif
|
||||
|
||||
// FS overscan
|
||||
ypos += lineHeight + VGAP;
|
||||
|
@ -484,8 +486,10 @@ void VideoAudioDialog::loadConfig()
|
|||
myFullScreenMode->setSelected(mode);*/
|
||||
// Fullscreen stretch setting
|
||||
myUseStretch->setState(instance().settings().getBool("tia.fs_stretch"));
|
||||
#ifndef BSPF_MACOS
|
||||
// Adapt refresh rate
|
||||
myRefreshAdapt->setState(instance().settings().getBool("tia.fs_refresh"));
|
||||
#endif
|
||||
// Fullscreen overscan setting
|
||||
myTVOverscan->setValue(instance().settings().getInt("tia.fs_overscan"));
|
||||
handleFullScreenChange();
|
||||
|
@ -597,8 +601,10 @@ void VideoAudioDialog::saveConfig()
|
|||
instance().settings().setValue("fullscreen", myFullscreen->getState());
|
||||
// Fullscreen stretch setting
|
||||
instance().settings().setValue("tia.fs_stretch", myUseStretch->getState());
|
||||
#ifndef BSPF_MACOS
|
||||
// Adapt refresh rate
|
||||
instance().settings().setValue("tia.fs_refresh", myRefreshAdapt->getState());
|
||||
#endif
|
||||
// Fullscreen overscan
|
||||
instance().settings().setValue("tia.fs_overscan", myTVOverscan->getValueLabel());
|
||||
|
||||
|
@ -712,7 +718,9 @@ void VideoAudioDialog::setDefaults()
|
|||
myFullscreen->setState(false);
|
||||
//myFullScreenMode->setSelectedIndex(0);
|
||||
myUseStretch->setState(false);
|
||||
#ifndef BSPF_MACOS
|
||||
myRefreshAdapt->setState(false);
|
||||
#endif
|
||||
myTVOverscan->setValue(0);
|
||||
myTIAZoom->setValue(300);
|
||||
myVSizeAdjust->setValue(0);
|
||||
|
@ -838,7 +846,9 @@ void VideoAudioDialog::handleFullScreenChange()
|
|||
{
|
||||
bool enable = myFullscreen->getState();
|
||||
myUseStretch->setEnabled(enable);
|
||||
#ifndef BSPF_MACOS
|
||||
myRefreshAdapt->setEnabled(enable);
|
||||
#endif
|
||||
myTVOverscan->setEnabled(enable);
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,9 @@ class VideoAudioDialog : public Dialog
|
|||
CheckboxWidget* myFullscreen{nullptr};
|
||||
CheckboxWidget* myUseStretch{nullptr};
|
||||
SliderWidget* myTVOverscan{nullptr};
|
||||
#ifndef BSPF_MACOS
|
||||
CheckboxWidget* myRefreshAdapt{nullptr};
|
||||
#endif
|
||||
SliderWidget* myTIAZoom{nullptr};
|
||||
SliderWidget* myVSizeAdjust{nullptr};
|
||||
|
||||
|
|
Loading…
Reference in New Issue