Add 'ADAPTABLE_REFRESH_SUPPORT', and enable it on non-Mac systems.

Cleaned up some dead code.
Made MacOS toggle from windowed to fullscreen work the same as all other systems.
This commit is contained in:
Stephen Anthony 2020-05-23 17:15:42 -02:30
parent c4aa9b2a56
commit ac9143ef08
5 changed files with 18 additions and 112 deletions

View File

@ -270,8 +270,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
posY = BSPF::clamp(posY, y0 + 50, y1 - 50); posY = BSPF::clamp(posY, y0 + 50, y1 - 50);
} }
#ifndef BSPF_MACOS #ifdef ADAPTABLE_REFRESH_SUPPORT
// macOS does not allow to change the display refresh rate
SDL_DisplayMode adaptedSdlMode; SDL_DisplayMode adaptedSdlMode;
const bool shouldAdapt = fullScreen && myOSystem.settings().getBool("tia.fs_refresh") const bool shouldAdapt = fullScreen && myOSystem.settings().getBool("tia.fs_refresh")
&& gameRefreshRate() && gameRefreshRate()
@ -284,12 +283,6 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
const uInt32 flags = SDL_WINDOW_ALLOW_HIGHDPI const uInt32 flags = SDL_WINDOW_ALLOW_HIGHDPI
| (fullScreen ? adaptRefresh ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP : 0); | (fullScreen ? adaptRefresh ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
// macOS seems to have issues with destroying the window, and wants to
// keep the same handle
// Problem is, doing so on other platforms results in flickering when
// toggling fullscreen windowed mode
// So we have a special case for macOS
#ifndef BSPF_MACOS
// Don't re-create the window if its display and size hasn't changed, // Don't re-create the window if its display and size hasn't changed,
// as it's not necessary, and causes flashing in fullscreen mode // as it's not necessary, and causes flashing in fullscreen mode
if(myWindow) if(myWindow)
@ -312,18 +305,6 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
SDL_SetWindowTitle(myWindow, title.c_str()); SDL_SetWindowTitle(myWindow, title.c_str());
SDL_SetWindowPosition(myWindow, posX, posY); SDL_SetWindowPosition(myWindow, posX, posY);
} }
#else
// macOS wants to *never* re-create the window
// This sometimes results in the window being resized *after* it's displayed,
// but at least the code works and doesn't crash
if(myWindow)
{
SDL_SetWindowFullscreen(myWindow, flags);
SDL_SetWindowSize(myWindow, mode.screen.w, mode.screen.h);
SDL_SetWindowPosition(myWindow, posX, posY);
SDL_SetWindowTitle(myWindow, title.c_str());
}
#endif
else else
{ {
forceCreateRenderer = true; forceCreateRenderer = true;
@ -338,7 +319,8 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
setWindowIcon(); setWindowIcon();
} }
#ifndef BSPF_MACOS
#ifdef ADAPTABLE_REFRESH_SUPPORT
if(adaptRefresh) if(adaptRefresh)
{ {
// Switch to mode for adapted refresh rate // Switch to mode for adapted refresh rate
@ -355,10 +337,10 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
} }
} }
#endif #endif
return createRenderer(forceCreateRenderer); return createRenderer(forceCreateRenderer);
} }
#ifndef BSPF_MACOS
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adaptedSdlMode) bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adaptedSdlMode)
{ {
@ -412,74 +394,7 @@ bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adap
// Only change if the display supports a better refresh rate // Only change if the display supports a better refresh rate
return adapt; 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) bool FrameBufferSDL2::createRenderer(bool force)
@ -637,10 +552,9 @@ void FrameBufferSDL2::renderToScreen()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSDL2::setWindowIcon() void FrameBufferSDL2::setWindowIcon()
{ {
ASSERT_MAIN_THREAD;
#if !defined(BSPF_MACOS) && !defined(RETRON77) #if !defined(BSPF_MACOS) && !defined(RETRON77)
#include "stella_icon.hxx" #include "stella_icon.hxx"
ASSERT_MAIN_THREAD;
SDL_Surface* surface = SDL_CreateRGBSurfaceFrom(stella_icon, 32, 32, 32, SDL_Surface* surface = SDL_CreateRGBSurfaceFrom(stella_icon, 32, 32, 32,
32 * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000); 32 * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000);

View File

@ -181,7 +181,6 @@ class FrameBufferSDL2 : public FrameBuffer
*/ */
bool setVideoMode(const string& title, const VideoMode& mode) override; 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 Checks if the display refresh rate should be adapted to game refresh rate in (real) fullscreen mode
@ -191,7 +190,6 @@ class FrameBufferSDL2 : public FrameBuffer
@return True if the refresh rate should be changed @return True if the refresh rate should be changed
*/ */
bool adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adaptedSdlMode); bool adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adaptedSdlMode);
#endif
/** /**
Create a new renderer if required Create a new renderer if required

View File

@ -101,6 +101,12 @@ static const string EmptyString("");
#undef PAGE_SIZE #undef PAGE_SIZE
#undef PAGE_MASK #undef PAGE_MASK
// Adaptable refresh is currently not available on MacOS
// In the future, this may expand to other systems
#if !defined(BSPF_MACOS)
#define ADAPTABLE_REFRESH_SUPPORT
#endif
namespace BSPF namespace BSPF
{ {
static constexpr float PI_f = 3.141592653589793238462643383279502884F; static constexpr float PI_f = 3.141592653589793238462643383279502884F;

View File

@ -83,14 +83,6 @@ VideoAudioDialog::VideoAudioDialog(OSystem& osystem, DialogContainer& parent,
addTVEffectsTab(); addTVEffectsTab();
addAudioTab(); addAudioTab();
//const int req_w = std::max(myFastSCBios->getRight(), myCloneBad->getRight()) + HBORDER + 1;
//const int req_h = _th + VGAP * 3
// + std::max(myUseVSync->getBottom(), myTVScanIntense->getBottom())
// + buttonHeight + VBORDER * 2;
//// Set real dimensions
//setSize(req_w, req_h, max_w, max_h);
// Add Defaults, OK and Cancel buttons // Add Defaults, OK and Cancel buttons
WidgetArray wid; WidgetArray wid;
addDefaultsOKCancelBGroup(wid, _font); addDefaultsOKCancelBGroup(wid, _font);
@ -153,11 +145,13 @@ void VideoAudioDialog::addDisplayTab()
myUseStretch = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Stretch"); myUseStretch = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Stretch");
wid.push_back(myUseStretch); wid.push_back(myUseStretch);
#ifndef BSPF_MACOS #ifdef ADAPTABLE_REFRESH_SUPPORT
// Adapt refresh rate // Adapt refresh rate
ypos += lineHeight + VGAP; ypos += lineHeight + VGAP;
myRefreshAdapt = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Adapt display refresh rate"); myRefreshAdapt = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Adapt display refresh rate");
wid.push_back(myRefreshAdapt); wid.push_back(myRefreshAdapt);
#else
myRefreshAdapt = nullptr;
#endif #endif
// FS overscan // FS overscan
@ -482,11 +476,9 @@ void VideoAudioDialog::loadConfig()
// Fullscreen // Fullscreen
myFullscreen->setState(instance().settings().getBool("fullscreen")); myFullscreen->setState(instance().settings().getBool("fullscreen"));
/*string mode = instance().settings().getString("fullscreenmode");
myFullScreenMode->setSelected(mode);*/
// Fullscreen stretch setting // Fullscreen stretch setting
myUseStretch->setState(instance().settings().getBool("tia.fs_stretch")); myUseStretch->setState(instance().settings().getBool("tia.fs_stretch"));
#ifndef BSPF_MACOS #ifdef ADAPTABLE_REFRESH_SUPPORT
// Adapt refresh rate // Adapt refresh rate
myRefreshAdapt->setState(instance().settings().getBool("tia.fs_refresh")); myRefreshAdapt->setState(instance().settings().getBool("tia.fs_refresh"));
#endif #endif
@ -601,7 +593,7 @@ void VideoAudioDialog::saveConfig()
instance().settings().setValue("fullscreen", myFullscreen->getState()); instance().settings().setValue("fullscreen", myFullscreen->getState());
// Fullscreen stretch setting // Fullscreen stretch setting
instance().settings().setValue("tia.fs_stretch", myUseStretch->getState()); instance().settings().setValue("tia.fs_stretch", myUseStretch->getState());
#ifndef BSPF_MACOS #ifdef ADAPTABLE_REFRESH_SUPPORT
// Adapt refresh rate // Adapt refresh rate
instance().settings().setValue("tia.fs_refresh", myRefreshAdapt->getState()); instance().settings().setValue("tia.fs_refresh", myRefreshAdapt->getState());
#endif #endif
@ -621,7 +613,6 @@ void VideoAudioDialog::saveConfig()
// Note: Palette values are saved directly when changed! // Note: Palette values are saved directly when changed!
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// TV Effects tab // TV Effects tab
// TV Mode // TV Mode
@ -716,9 +707,8 @@ void VideoAudioDialog::setDefaults()
myTIAInterpolate->setState(false); myTIAInterpolate->setState(false);
// screen size // screen size
myFullscreen->setState(false); myFullscreen->setState(false);
//myFullScreenMode->setSelectedIndex(0);
myUseStretch->setState(false); myUseStretch->setState(false);
#ifndef BSPF_MACOS #ifdef ADAPTABLE_REFRESH_SUPPORT
myRefreshAdapt->setState(false); myRefreshAdapt->setState(false);
#endif #endif
myTVOverscan->setValue(0); myTVOverscan->setValue(0);
@ -846,7 +836,7 @@ void VideoAudioDialog::handleFullScreenChange()
{ {
bool enable = myFullscreen->getState(); bool enable = myFullscreen->getState();
myUseStretch->setEnabled(enable); myUseStretch->setEnabled(enable);
#ifndef BSPF_MACOS #ifdef ADAPTABLE_REFRESH_SUPPORT
myRefreshAdapt->setEnabled(enable); myRefreshAdapt->setEnabled(enable);
#endif #endif
myTVOverscan->setEnabled(enable); myTVOverscan->setEnabled(enable);

View File

@ -73,9 +73,7 @@ class VideoAudioDialog : public Dialog
CheckboxWidget* myFullscreen{nullptr}; CheckboxWidget* myFullscreen{nullptr};
CheckboxWidget* myUseStretch{nullptr}; CheckboxWidget* myUseStretch{nullptr};
SliderWidget* myTVOverscan{nullptr}; SliderWidget* myTVOverscan{nullptr};
#ifndef BSPF_MACOS
CheckboxWidget* myRefreshAdapt{nullptr}; CheckboxWidget* myRefreshAdapt{nullptr};
#endif
SliderWidget* myTIAZoom{nullptr}; SliderWidget* myTIAZoom{nullptr};
SliderWidget* myVSizeAdjust{nullptr}; SliderWidget* myVSizeAdjust{nullptr};