adapt desktop size and maximum TIA zoom level to display used

This commit is contained in:
thrust26 2021-04-06 15:56:01 +02:00
parent 2015d98abf
commit e0585212b8
7 changed files with 132 additions and 80 deletions

View File

@ -12,6 +12,19 @@
Release History
===========================================================================
6.5.2 to 6.5.3 (XXX, 2021)
* Improved support of multiple monitors with different resolutions.
* Improved analog input reading (Paddles, Keyboards...).
* Fixed QuadTari handling for controller types other than Joysticks.
* Fixed immediate disassembling when switching options in debugger.
-Have fun!
6.5.1 to 6.5.2 (February 25, 2021)
* Fixed broken Driving Controller support for Stelladaptor/2600-daptor
@ -23,8 +36,6 @@
* Added CPU usage stats to ARM cart classes debug widgets.
-Have fun!
6.5 to 6.5.1 (January 24, 2021)

View File

@ -91,7 +91,7 @@ Debugger::~Debugger()
void Debugger::initialize()
{
mySize = myOSystem.settings().getSize("dbg.res");
const Common::Size& d = myOSystem.frameBuffer().desktopSize();
const Common::Size& d = myOSystem.frameBuffer().desktopSize(BufferType::Debugger);
// The debugger dialog is resizable, within certain bounds
// We check those bounds now

View File

@ -77,47 +77,45 @@ void FrameBuffer::initialize()
myBackend = MediaFactory::createVideoBackend(myOSystem);
// Get desktop resolution and supported renderers
vector<Common::Size> windowedDisplays;
myBackend->queryHardware(myFullscreenDisplays, windowedDisplays, myRenderers);
uInt32 query_w = windowedDisplays[0].w, query_h = windowedDisplays[0].h;
myBackend->queryHardware(myFullscreenDisplays, myWindowedDisplays, myRenderers);
// Check the 'maxres' setting, which is an undocumented developer feature
// that specifies the desktop size (not normally set)
const Common::Size& s = myOSystem.settings().getSize("maxres");
if(s.valid())
int numDisplays = int(myWindowedDisplays.size());
for(int display = 0; display < numDisplays; ++display)
{
query_w = s.w;
query_h = s.h;
}
// Various parts of the codebase assume a minimum screen size
myAbsDesktopSize.w = std::max(query_w, FBMinimum::Width);
myAbsDesktopSize.h = std::max(query_h, FBMinimum::Height);
myDesktopSize = myAbsDesktopSize;
uInt32 query_w = myWindowedDisplays[display].w, query_h = myWindowedDisplays[display].h;
// Check for HiDPI mode (is it activated, and can we use it?)
myHiDPIAllowed = ((myAbsDesktopSize.w / 2) >= FBMinimum::Width) &&
((myAbsDesktopSize.h / 2) >= FBMinimum::Height);
myHiDPIEnabled = myHiDPIAllowed && myOSystem.settings().getBool("hidpi");
// Check the 'maxres' setting, which is an undocumented developer feature
// that specifies the desktop size (not normally set)
const Common::Size& s = myOSystem.settings().getSize("maxres");
if(s.valid())
{
query_w = s.w;
query_h = s.h;
}
// Various parts of the codebase assume a minimum screen size
Common::Size size(std::max(query_w, FBMinimum::Width), std::max(query_h, FBMinimum::Height));
myAbsDesktopSize.push_back(size);
// In HiDPI mode, the desktop resolution is essentially halved
// Later, the output is scaled and rendered in 2x mode
if(hidpiEnabled())
{
myDesktopSize.w = myAbsDesktopSize.w / hidpiScaleFactor();
myDesktopSize.h = myAbsDesktopSize.h / hidpiScaleFactor();
// Check for HiDPI mode (is it activated, and can we use it?)
myHiDPIAllowed.push_back(((myAbsDesktopSize[display].w / 2) >= FBMinimum::Width) &&
((myAbsDesktopSize[display].h / 2) >= FBMinimum::Height));
myHiDPIEnabled.push_back(myHiDPIAllowed.back() && myOSystem.settings().getBool("hidpi"));
// In HiDPI mode, the desktop resolution is essentially halved
// Later, the output is scaled and rendered in 2x mode
if(myHiDPIEnabled.back())
{
size.w = myAbsDesktopSize[display].w / hidpiScaleFactor();
size.h = myAbsDesktopSize[display].h / hidpiScaleFactor();
}
myDesktopSize.push_back(size);
}
#ifdef GUI_SUPPORT
setupFonts();
#endif
// Determine possible TIA windowed zoom levels
myTIAMaxZoom = maxWindowZoom(TIAConstants::viewableWidth,
TIAConstants::viewableHeight);
float currentTIAZoom = myOSystem.settings().getFloat("tia.zoom");
myOSystem.settings().setValue("tia.zoom",
BSPF::clampw(currentTIAZoom, supportedTIAMinZoom(), myTIAMaxZoom));
setUIPalette();
myGrabMouse = myOSystem.settings().getBool("grabmouse");
@ -126,6 +124,20 @@ void FrameBuffer::initialize()
myTIASurface = make_unique<TIASurface>(myOSystem);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const int FrameBuffer::displayId(BufferType bufferType) const
{
const int maxDisplay = int(myWindowedDisplays.size()) - 1;
int display;
if(bufferType == myBufferType)
display = myBackend->getCurrentDisplayIndex();
else
display = myOSystem.settings().getInt(getDisplayKey(bufferType));
return std::min(std::max(0, display), maxDisplay);
}
#ifdef GUI_SUPPORT
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setupFonts()
@ -218,6 +230,10 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type,
++myInitializedCount;
myBackend->setTitle(title);
// Always save, maybe only the mode of the window has changed
saveCurrentWindowPosition();
myBufferType = type;
// In HiDPI mode, all created displays must be scaled appropriately
if(honourHiDPI && hidpiEnabled())
{
@ -235,22 +251,32 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type,
// If the WINDOWED_SUPPORT macro is defined, we treat the system as the
// former type; if not, as the latter type
int display = displayId();
#ifdef WINDOWED_SUPPORT
// We assume that a desktop of at least minimum acceptable size means that
// we're running on a 'large' system, and the window size requirements
// can be relaxed
// Otherwise, we treat the system as if WINDOWED_SUPPORT is not defined
if(myDesktopSize.w < FBMinimum::Width && myDesktopSize.h < FBMinimum::Height &&
size > myDesktopSize)
if(myDesktopSize[display].w < FBMinimum::Width &&
myDesktopSize[display].h < FBMinimum::Height &&
size > myDesktopSize[display])
return FBInitStatus::FailTooLarge;
#else
// Make sure this mode is even possible
// We only really need to worry about it in non-windowed environments,
// where requesting a window that's too large will probably cause a crash
if(size > myDesktopSize)
if(size > myDesktopSize[display])
return FBInitStatus::FailTooLarge;
#endif
if(myBufferType == BufferType::Emulator)
{
// Determine possible TIA windowed zoom levels
float currentTIAZoom = myOSystem.settings().getFloat("tia.zoom");
myOSystem.settings().setValue("tia.zoom",
BSPF::clampw(currentTIAZoom, supportedTIAMinZoom(), supportedTIAMaxZoom()));
}
#ifdef GUI_SUPPORT // TODO: put message stuff in its own class
// Erase any messages from a previous run
myMsg.enabled = false;
@ -282,10 +308,6 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type,
// appropriate for the requested image size
myVidModeHandler.setImageSize(size);
// Always save, maybe only the mode of the window has changed
saveCurrentWindowPosition();
myBufferType = type;
// Initialize video subsystem
string pre_about = myBackend->about();
FBInitStatus status = applyVideoMode();
@ -979,10 +1001,13 @@ void FrameBuffer::stateChanged(EventHandlerState state)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string FrameBuffer::getDisplayKey() const
string FrameBuffer::getDisplayKey(BufferType bufferType) const
{
if(bufferType == BufferType::None)
bufferType = myBufferType;
// save current window's display and position
switch(myBufferType)
switch(bufferType)
{
case BufferType::Launcher:
return "launcherdisplay";
@ -1192,7 +1217,7 @@ void FrameBuffer::switchVideoMode(int direction)
else if(direction == -1) zoom -= ZOOM_STEPS;
// Make sure the level is within the allowable desktop size
zoom = BSPF::clampw(zoom, supportedTIAMinZoom(), myTIAMaxZoom);
zoom = BSPF::clampw(zoom, supportedTIAMinZoom(), supportedTIAMaxZoom());
myOSystem.settings().setValue("tia.zoom", zoom);
}
else
@ -1213,7 +1238,7 @@ void FrameBuffer::switchVideoMode(int direction)
showTextMessage(myActiveVidMode.description);
else
showGaugeMessage("Zoom", myActiveVidMode.description, myActiveVidMode.zoom,
supportedTIAMinZoom(), myTIAMaxZoom);
supportedTIAMinZoom(), supportedTIAMaxZoom());
}
}
@ -1222,13 +1247,12 @@ FBInitStatus FrameBuffer::applyVideoMode()
{
// Update display size, in case windowed/fullscreen mode has changed
const Settings& s = myOSystem.settings();
int display = displayId();
if(s.getBool("fullscreen"))
{
Int32 fsIndex = std::max(myBackend->getCurrentDisplayIndex(), 0);
myVidModeHandler.setDisplaySize(myFullscreenDisplays[fsIndex], fsIndex);
}
myVidModeHandler.setDisplaySize(myFullscreenDisplays[display], display);
else
myVidModeHandler.setDisplaySize(myAbsDesktopSize);
myVidModeHandler.setDisplaySize(myAbsDesktopSize[display]);
const bool inTIAMode = myOSystem.eventHandler().inTIAMode();
@ -1279,16 +1303,18 @@ FBInitStatus FrameBuffer::applyVideoMode()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
float FrameBuffer::maxWindowZoom(uInt32 baseWidth, uInt32 baseHeight) const
float FrameBuffer::maxWindowZoom() const
{
int display = displayId(BufferType::Emulator);
float multiplier = 1;
for(;;)
{
// Figure out the zoomed size of the window
uInt32 width = baseWidth * multiplier;
uInt32 height = baseHeight * multiplier;
uInt32 width = TIAConstants::viewableWidth * multiplier;
uInt32 height = TIAConstants::viewableHeight * multiplier;
if((width > myAbsDesktopSize.w) || (height > myAbsDesktopSize.h))
if((width > myAbsDesktopSize[display].w) || (height > myAbsDesktopSize[display].h))
break;
multiplier += ZOOM_STEPS;

View File

@ -194,9 +194,11 @@ class FrameBuffer
const Common::Rect& screenRect() const { return myActiveVidMode.screenR; }
/**
Returns the current dimensions of the users' desktop.
Returns the dimensions of the mode specific users' desktop.
*/
const Common::Size& desktopSize() const { return myDesktopSize; }
const Common::Size& desktopSize(BufferType bufferType) const {
return myDesktopSize[displayId(bufferType)];
}
/**
Get the supported renderers for the video hardware.
@ -210,7 +212,7 @@ class FrameBuffer
for the framebuffer.
*/
float supportedTIAMinZoom() const { return myTIAMinZoom * hidpiScaleFactor(); }
float supportedTIAMaxZoom() const { return myTIAMaxZoom; }
float supportedTIAMaxZoom() const { return maxWindowZoom(); }
/**
Get the TIA surface associated with the framebuffer.
@ -281,14 +283,14 @@ class FrameBuffer
Answer whether hidpi mode is allowed. In this mode, all FBSurfaces
are scaled to 2x normal size.
*/
bool hidpiAllowed() const { return myHiDPIAllowed; }
bool hidpiAllowed() const { return myHiDPIAllowed[displayId()]; }
/**
Answer whether hidpi mode is enabled. In this mode, all FBSurfaces
are scaled to 2x normal size.
*/
bool hidpiEnabled() const { return myHiDPIEnabled; }
uInt32 hidpiScaleFactor() const { return myHiDPIEnabled ? 2 : 1; }
bool hidpiEnabled() const { return myHiDPIEnabled[displayId()]; }
uInt32 hidpiScaleFactor() const { return myHiDPIEnabled[displayId()] ? 2 : 1; }
/**
This method should be called to save the current settings of all
@ -381,7 +383,7 @@ class FrameBuffer
current window.
*/
string getPositionKey() const;
string getDisplayKey() const;
string getDisplayKey(BufferType bufferType = BufferType::None) const;
void saveCurrentWindowPosition() const;
/**
@ -418,6 +420,12 @@ class FrameBuffer
*/
void drawFrameStats(float framesPerSecond);
/**
Get the display used for the current mode.
*/
const int displayId(BufferType bufferType = BufferType::None) const;
/**
Build an applicable video mode based on the current settings in
effect, whether TIA mode is active, etc. Then tell the backend
@ -431,7 +439,7 @@ class FrameBuffer
Calculate the maximum level by which the base window can be zoomed and
still fit in the desktop screen.
*/
float maxWindowZoom(uInt32 baseWidth, uInt32 baseHeight) const;
float maxWindowZoom() const;
/**
Enables/disables fullscreen mode.
@ -461,16 +469,19 @@ class FrameBuffer
// Maximum dimensions of the desktop area
// Note that this takes 'hidpi' mode into account, so in some cases
// it will be less than the absolute desktop size
Common::Size myDesktopSize;
vector<Common::Size> myDesktopSize;
// Maximum absolute dimensions of the desktop area
Common::Size myAbsDesktopSize;
vector<Common::Size> myAbsDesktopSize;
// The resolution of the attached displays in fullscreen mode
// The primary display is typically the first in the array
// Windowed modes use myDesktopSize directly
vector<Common::Size> myFullscreenDisplays;
// The resolution of the attached displays in windowed mode
vector<Common::Size> myWindowedDisplays;
// Supported renderers
VariantList myRenderers;
@ -523,13 +534,11 @@ class FrameBuffer
uInt32 myLastScanlines{0};
bool myGrabMouse{false};
bool myHiDPIAllowed{false};
bool myHiDPIEnabled{false};
vector<bool> myHiDPIAllowed{false};
vector<bool> myHiDPIEnabled{false};
// Minimum TIA zoom level that can be used for this framebuffer
float myTIAMinZoom{2.F};
// Maximum TIA zoom level that can be used for this framebuffer
float myTIAMaxZoom{1.F};
// Maximum message width [chars]
static constexpr int MESSAGE_WIDTH = 56;

View File

@ -567,7 +567,7 @@ void DeveloperDialog::addDebuggerTab(const GUI::Font& font)
VGAP = Dialog::vGap();
VariantList items;
int xpos, ypos, pwidth;
const Common::Size& ds = instance().frameBuffer().desktopSize();
const Common::Size& ds = instance().frameBuffer().desktopSize(BufferType::Debugger);
xpos = HBORDER;
ypos = VBORDER;
@ -1071,8 +1071,10 @@ void DeveloperDialog::setDefaults()
case 4: // Debugger options
{
#ifdef DEBUGGER_SUPPORT
uInt32 w = std::min(instance().frameBuffer().desktopSize().w, uInt32(DebuggerDialog::kMediumFontMinW));
uInt32 h = std::min(instance().frameBuffer().desktopSize().h, uInt32(DebuggerDialog::kMediumFontMinH));
const Common::Size& size = instance().frameBuffer().desktopSize(BufferType::Debugger);
uInt32 w = std::min(size.w, uInt32(DebuggerDialog::kMediumFontMinW));
uInt32 h = std::min(size.h, uInt32(DebuggerDialog::kMediumFontMinH));
myDebuggerWidthSlider->setValue(w);
myDebuggerHeightSlider->setValue(h);
myDebuggerFontSize->setSelected("medium");
@ -1548,8 +1550,9 @@ void DeveloperDialog::handleFontSize()
minW = DebuggerDialog::kLargeFontMinW;
minH = DebuggerDialog::kLargeFontMinH;
}
minW = std::min(instance().frameBuffer().desktopSize().w, minW);
minH = std::min(instance().frameBuffer().desktopSize().h, minH);
const Common::Size& size = instance().frameBuffer().desktopSize(BufferType::Debugger);
minW = std::min(size.w, minW);
minH = std::min(size.h, minH);
myDebuggerWidthSlider->setMinValue(minW);
if(minW > uInt32(myDebuggerWidthSlider->getValue()))

View File

@ -30,7 +30,7 @@ Launcher::Launcher(OSystem& osystem)
: DialogContainer(osystem),
mySize{myOSystem.settings().getSize("launcherres")}
{
const Common::Size& d = myOSystem.frameBuffer().desktopSize();
const Common::Size& d = myOSystem.frameBuffer().desktopSize(BufferType::Launcher);
double overscan = 1 - myOSystem.settings().getInt("tia.fs_overscan") / 100.0;
// The launcher dialog is resizable, within certain bounds

View File

@ -57,7 +57,7 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent,
int lwidth, pwidth, bwidth;
WidgetArray wid;
VariantList items;
const Common::Size& ds = instance().frameBuffer().desktopSize();
const Common::Size& ds = instance().frameBuffer().desktopSize(BufferType::Launcher);
// Set real dimensions
setSize(64 * fontWidth + HBORDER * 2,
@ -326,12 +326,13 @@ void UIDialog::loadConfig()
// Launcher size
const Common::Size& ls = settings.getSize("launcherres");
const Common::Size& ds = instance().frameBuffer().desktopSize(BufferType::Launcher);
uInt32 w = ls.w, h = ls.h;
w = std::max(w, FBMinimum::Width);
h = std::max(h, FBMinimum::Height);
w = std::min(w, instance().frameBuffer().desktopSize().w);
h = std::min(h, instance().frameBuffer().desktopSize().h);
w = std::min(w, ds.w);
h = std::min(h, ds.h);
myLauncherWidthSlider->setValue(w);
myLauncherHeightSlider->setValue(h);
@ -501,9 +502,11 @@ void UIDialog::setDefaults()
case 1: // Launcher options
{
FilesystemNode node("~");
const Common::Size& size = instance().frameBuffer().desktopSize(BufferType::Launcher);
myRomPath->setText(node.getShortPath());
uInt32 w = std::min<uInt32>(instance().frameBuffer().desktopSize().w, 900);
uInt32 h = std::min<uInt32>(instance().frameBuffer().desktopSize().h, 600);
uInt32 w = std::min<uInt32>(size.w, 900);
uInt32 h = std::min<uInt32>(size.h, 600);
myLauncherWidthSlider->setValue(w);
myLauncherHeightSlider->setValue(h);
myLauncherFontPopup->setSelected("medium", "");
@ -612,7 +615,7 @@ void UIDialog::handleLauncherSize()
FontDesc fd = instance().frameBuffer().getFontDesc(myDialogFontPopup->getSelectedTag().toString());
int w = std::max(FBMinimum::Width, FBMinimum::Width * fd.maxwidth / GUI::stellaMediumDesc.maxwidth);
int h = std::max(FBMinimum::Height, FBMinimum::Height * fd.height / GUI::stellaMediumDesc.height);
const Common::Size& ds = instance().frameBuffer().desktopSize();
const Common::Size& ds = instance().frameBuffer().desktopSize(BufferType::Launcher);
myLauncherWidthSlider->setMinValue(w);
if(myLauncherWidthSlider->getValue() < myLauncherWidthSlider->getMinValue())