mirror of https://github.com/stella-emu/stella.git
First pass at implementing 'hidpi' mode. For now, it is available with 'hidpi' option only from the commandline.
- This is still a WIP, but is already very usable; I can finally see the UI on my 4k monitor :)
This commit is contained in:
parent
fccd62607b
commit
e7759048ca
|
@ -613,7 +613,7 @@ FBInitStatus Console::initializeVideo(bool full)
|
|||
const string& title = string("Stella ") + STELLA_VERSION +
|
||||
": \"" + myProperties.get(PropType::Cart_Name) + "\"";
|
||||
fbstatus = myOSystem.frameBuffer().createDisplay(title,
|
||||
TIAConstants::viewableWidth, TIAConstants::viewableHeight);
|
||||
TIAConstants::viewableWidth, TIAConstants::viewableHeight, false);
|
||||
if(fbstatus != FBInitStatus::Success)
|
||||
return fbstatus;
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ FrameBuffer::FrameBuffer(OSystem& osystem)
|
|||
myStatsEnabled(false),
|
||||
myLastScanlines(0),
|
||||
myGrabMouse(false),
|
||||
myHiDPIEnabled(false),
|
||||
myCurrentModeList(nullptr)
|
||||
{
|
||||
}
|
||||
|
@ -79,8 +80,22 @@ bool FrameBuffer::initialize()
|
|||
query_h = s.h;
|
||||
}
|
||||
// Various parts of the codebase assume a minimum screen size
|
||||
myDesktopSize.w = std::max(query_w, FBMinimum::Width);
|
||||
myDesktopSize.h = std::max(query_h, FBMinimum::Height);
|
||||
myAbsDesktopSize.w = std::max(query_w, FBMinimum::Width);
|
||||
myAbsDesktopSize.h = std::max(query_h, FBMinimum::Height);
|
||||
myDesktopSize = myAbsDesktopSize;
|
||||
|
||||
// Check for HiDPI mode (is it activated, and can we use it?)
|
||||
myHiDPIEnabled = myOSystem.settings().getBool("hidpi") &&
|
||||
((myAbsDesktopSize.w / 2) >= FBMinimum::Width) &&
|
||||
((myAbsDesktopSize.h / 2) >= FBMinimum::Height);
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
#ifdef GUI_SUPPORT
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -121,12 +136,11 @@ bool FrameBuffer::initialize()
|
|||
#endif
|
||||
|
||||
// Determine possible TIA windowed zoom levels
|
||||
uInt32 minZoom = 2 * hidpiScaleFactor();
|
||||
uInt32 maxZoom = maxWindowSizeForScreen(
|
||||
TIAConstants::viewableWidth, TIAConstants::viewableHeight,
|
||||
myDesktopSize.w, myDesktopSize.h);
|
||||
|
||||
// Figure our the smallest zoom level we can use
|
||||
for(uInt32 zoom = 2; zoom <= maxZoom; ++zoom)
|
||||
myAbsDesktopSize.w, myAbsDesktopSize.h);
|
||||
for(uInt32 zoom = minZoom; zoom <= maxZoom; ++zoom)
|
||||
{
|
||||
ostringstream desc;
|
||||
desc << "Zoom " << zoom << "x";
|
||||
|
@ -166,11 +180,19 @@ void FrameBuffer::setUIPalette()
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FBInitStatus FrameBuffer::createDisplay(const string& title,
|
||||
uInt32 width, uInt32 height)
|
||||
uInt32 width, uInt32 height,
|
||||
bool honourHiDPI)
|
||||
{
|
||||
++myInitializedCount;
|
||||
myScreenTitle = title;
|
||||
|
||||
// In HiDPI mode, all created displays must be scaled by 2x
|
||||
if(honourHiDPI && hidpiEnabled())
|
||||
{
|
||||
width *= hidpiScaleFactor();
|
||||
height *= hidpiScaleFactor();
|
||||
}
|
||||
|
||||
// A 'windowed' system is defined as one where the window size can be
|
||||
// larger than the screen size, as there's some sort of window manager
|
||||
// that takes care of it (all current desktop systems fall in this category)
|
||||
|
@ -245,9 +267,10 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
|
|||
myMsg.counter = 0;
|
||||
|
||||
// Create surfaces for TIA statistics and general messages
|
||||
const GUI::Font& f = hidpiEnabled() ? infoFont() : font();
|
||||
myStatsMsg.color = kColorInfo;
|
||||
myStatsMsg.w = font().getMaxCharWidth() * 40 + 3;
|
||||
myStatsMsg.h = (font().getFontHeight() + 2) * 3;
|
||||
myStatsMsg.w = f.getMaxCharWidth() * 40 + 3;
|
||||
myStatsMsg.h = (f.getFontHeight() + 2) * 3;
|
||||
|
||||
if(!myStatsMsg.surface)
|
||||
{
|
||||
|
@ -427,7 +450,7 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position,
|
|||
myMsg.w = font().getStringWidth(myMsg.text) + 10;
|
||||
myMsg.h = font().getFontHeight() + 8;
|
||||
myMsg.surface->setSrcSize(myMsg.w, myMsg.h);
|
||||
myMsg.surface->setDstSize(myMsg.w, myMsg.h);
|
||||
myMsg.surface->setDstSize(myMsg.w * hidpiScaleFactor(), myMsg.h * hidpiScaleFactor());
|
||||
myMsg.position = position;
|
||||
myMsg.enabled = true;
|
||||
#endif
|
||||
|
@ -439,7 +462,8 @@ void FrameBuffer::drawFrameStats(float framesPerSecond)
|
|||
#ifdef GUI_SUPPORT
|
||||
const ConsoleInfo& info = myOSystem.console().about();
|
||||
int xPos = 2, yPos = 0;
|
||||
const int dy = font().getFontHeight() + 2;
|
||||
const GUI::Font& f = hidpiEnabled() ? infoFont() : font();
|
||||
const int dy = f.getFontHeight() + 2;
|
||||
|
||||
ostringstream ss;
|
||||
|
||||
|
@ -456,7 +480,7 @@ void FrameBuffer::drawFrameStats(float framesPerSecond)
|
|||
<< "Hz => "
|
||||
<< info.DisplayFormat;
|
||||
|
||||
myStatsMsg.surface->drawString(font(), ss.str(), xPos, yPos,
|
||||
myStatsMsg.surface->drawString(f, ss.str(), xPos, yPos,
|
||||
myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor);
|
||||
|
||||
yPos += dy;
|
||||
|
@ -468,7 +492,7 @@ void FrameBuffer::drawFrameStats(float framesPerSecond)
|
|||
<< std::fixed << std::setprecision(0) << 100 * myOSystem.settings().getFloat("speed")
|
||||
<< "% speed";
|
||||
|
||||
myStatsMsg.surface->drawString(font(), ss.str(), xPos, yPos,
|
||||
myStatsMsg.surface->drawString(f, ss.str(), xPos, yPos,
|
||||
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
|
||||
|
||||
yPos += dy;
|
||||
|
@ -477,10 +501,12 @@ void FrameBuffer::drawFrameStats(float framesPerSecond)
|
|||
ss << info.BankSwitch;
|
||||
if (myOSystem.settings().getBool("dev.settings")) ss << "| Developer";
|
||||
|
||||
myStatsMsg.surface->drawString(font(), ss.str(), xPos, yPos,
|
||||
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
|
||||
myStatsMsg.surface->drawString(f, ss.str(), xPos, yPos,
|
||||
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
|
||||
|
||||
myStatsMsg.surface->setDstPos(myImageRect.x() + 10, myImageRect.y() + 8);
|
||||
myStatsMsg.surface->setDstSize(myStatsMsg.w * hidpiScaleFactor(),
|
||||
myStatsMsg.h * hidpiScaleFactor());
|
||||
myStatsMsg.surface->render();
|
||||
#endif
|
||||
}
|
||||
|
@ -850,8 +876,9 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
|
|||
if(tiaMode)
|
||||
{
|
||||
// TIA windowed modes
|
||||
uInt32 minZoom = 2 * hidpiScaleFactor();
|
||||
uInt32 maxZoom = maxWindowSizeForScreen(baseWidth, baseHeight,
|
||||
myDesktopSize.w, myDesktopSize.h);
|
||||
myAbsDesktopSize.w, myAbsDesktopSize.h);
|
||||
|
||||
#if 0 // FIXME - does this apply any longer??
|
||||
// Aspect ratio
|
||||
|
@ -861,7 +888,7 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
|
|||
#endif
|
||||
|
||||
// Determine all zoom levels
|
||||
for(uInt32 zoom = 2; zoom <= maxZoom; ++zoom)
|
||||
for(uInt32 zoom = minZoom; zoom <= maxZoom; ++zoom)
|
||||
{
|
||||
ostringstream desc;
|
||||
desc << "Zoom " << zoom << "x";
|
||||
|
|
|
@ -104,10 +104,14 @@ class FrameBuffer
|
|||
@param title The title of the application / window
|
||||
@param width The width of the framebuffer
|
||||
@param height The height of the framebuffer
|
||||
@param honourHiDPI If true, consult the 'hidpi' setting and enlarge
|
||||
the display size accordingly; if false, use the
|
||||
exact dimensions as given
|
||||
|
||||
@return Status of initialization (see FBInitStatus 'enum')
|
||||
*/
|
||||
FBInitStatus createDisplay(const string& title, uInt32 width, uInt32 height);
|
||||
FBInitStatus createDisplay(const string& title, uInt32 width, uInt32 height,
|
||||
bool honourHiDPI = true);
|
||||
|
||||
/**
|
||||
Updates the display, which depending on the current mode could mean
|
||||
|
@ -255,6 +259,13 @@ class FrameBuffer
|
|||
*/
|
||||
void stateChanged(EventHandlerState state);
|
||||
|
||||
/**
|
||||
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; }
|
||||
|
||||
#ifdef GUI_SUPPORT
|
||||
/**
|
||||
Get the font object(s) of the framebuffer
|
||||
|
@ -498,8 +509,13 @@ class FrameBuffer
|
|||
Common::Size myScreenSize;
|
||||
|
||||
// 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;
|
||||
|
||||
// Maximum absolute dimensions of the desktop area
|
||||
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
|
||||
|
@ -546,6 +562,7 @@ class FrameBuffer
|
|||
uInt32 myLastScanlines;
|
||||
|
||||
bool myGrabMouse;
|
||||
bool myHiDPIEnabled;
|
||||
|
||||
// The list of all available video modes for this framebuffer
|
||||
VideoModeList* myCurrentModeList;
|
||||
|
|
|
@ -41,6 +41,7 @@ Settings::Settings()
|
|||
setPermanent("center", "false");
|
||||
setPermanent("palette", "standard");
|
||||
setPermanent("uimessages", "true");
|
||||
setPermanent("hidpi", "false");
|
||||
|
||||
// TIA specific options
|
||||
setPermanent("tia.zoom", "3");
|
||||
|
|
|
@ -100,6 +100,9 @@ void Dialog::open()
|
|||
_surface = instance().frameBuffer().allocateSurface(_w, _h);
|
||||
_layer = parent().addDialog(this);
|
||||
|
||||
if(instance().frameBuffer().hidpiEnabled())
|
||||
_surface->setDstSize(_w*2, _h*2);
|
||||
|
||||
center();
|
||||
|
||||
if(_myTabList.size())
|
||||
|
|
|
@ -459,11 +459,8 @@ void LauncherDialog::handleKeyDown(StellaKey key, StellaMod mod)
|
|||
// Control-R (reload ROM listing)
|
||||
if(StellaModTest::isControl(mod) && key == KBDK_R)
|
||||
updateListing();
|
||||
// FIXME - use the R77 define in the final release
|
||||
// use the '1' define for testing
|
||||
#if defined(RETRON77)
|
||||
// #if 1
|
||||
else
|
||||
#if defined(RETRON77)
|
||||
// handle keys used by R77
|
||||
switch(key)
|
||||
{
|
||||
|
@ -489,10 +486,9 @@ void LauncherDialog::handleKeyDown(StellaKey key, StellaMod mod)
|
|||
Dialog::handleKeyDown(key, mod);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
else
|
||||
#else
|
||||
Dialog::handleKeyDown(key, mod);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -110,7 +110,8 @@ void RomInfoWidget::parseProperties(const FilesystemNode& node)
|
|||
|
||||
// Scale surface to available image area
|
||||
const Common::Rect& src = mySurface->srcRect();
|
||||
float scale = std::min(float(myAvail.w) / src.width(), float(myAvail.h) / src.height());
|
||||
float scale = std::min(float(myAvail.w) / src.width(), float(myAvail.h) / src.height()) *
|
||||
instance().frameBuffer().hidpiScaleFactor();
|
||||
mySurface->setDstSize(uInt32(src.width() * scale), uInt32(src.height() * scale));
|
||||
mySurfaceIsValid = true;
|
||||
}
|
||||
|
@ -179,8 +180,9 @@ void RomInfoWidget::drawWidget(bool hilite)
|
|||
if(mySurfaceIsValid)
|
||||
{
|
||||
const Common::Rect& dst = mySurface->dstRect();
|
||||
uInt32 x = _x + ((_w - dst.width()) >> 1);
|
||||
uInt32 y = _y + ((yoff - dst.height()) >> 1);
|
||||
const uInt32 scale = instance().frameBuffer().hidpiScaleFactor();
|
||||
uInt32 x = _x*scale + ((_w*scale - dst.width()) >> 1);
|
||||
uInt32 y = _y*scale + ((yoff*scale - dst.height()) >> 1);
|
||||
|
||||
// Make sure when positioning the snapshot surface that we take
|
||||
// the dialog surface position into account
|
||||
|
|
Loading…
Reference in New Issue