Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/frontend/qt_sdl/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ DefaultList<int> DefaultInts =
{"Instance*.Joystick", -1},
{"Instance*.Window*.Width", 256},
{"Instance*.Window*.Height", 384},
{"Instance*.Window*.HybridRatio", 0},
{"Screen.VSyncInterval", 1},
{"3D.Renderer", renderer3D_Software},
{"3D.GL.ScaleFactor", 1},
Expand Down Expand Up @@ -85,6 +86,7 @@ RangeList IntRanges =
{"Mic.InputType", {0, micInputType_MAX-1}},
{"Instance*.Window*.ScreenRotation", {0, screenRot_MAX-1}},
{"Instance*.Window*.ScreenGap", {0, 500}},
{"Instance*.Window*.HybridRatio", {0, 960}},
{"Instance*.Window*.ScreenLayout", {0, screenLayout_MAX-1}},
{"Instance*.Window*.ScreenSizing", {0, screenSizing_MAX-1}},
{"Instance*.Window*.ScreenAspectTop", {0, AspectRatiosNum-1}},
Expand Down
64 changes: 57 additions & 7 deletions src/frontend/qt_sdl/Screen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,18 @@ void ScreenPanel::loadConfig()
auto& cfg = mainWindow->getWindowConfig();

screenRotation = cfg.GetInt("ScreenRotation");
screenGap = cfg.GetInt("ScreenGap");
screenLayout = cfg.GetInt("ScreenLayout");
screenGap = cfg.GetInt("ScreenGap");
HybridRatio = cfg.GetInt("HybridRatio");
screenSwap = cfg.GetBool("ScreenSwap");
screenSizing = cfg.GetInt("ScreenSizing");
integerScaling = cfg.GetBool("IntegerScaling");
screenAspectTop = cfg.GetInt("ScreenAspectTop");
screenAspectBot = cfg.GetInt("ScreenAspectBot");

// Hybrid ratios are represented by layout gap values, but use a separate
// setting so changing the hybrid ratio does not alter the regular gap.
CurrentScreenGap = screenLayout != screenLayout_Hybrid ? screenGap : HybridRatio;
}

void ScreenPanel::setFilter(bool filter)
Expand Down Expand Up @@ -162,17 +167,62 @@ void ScreenPanel::setupScreenLayout()
aspectBot = ratio.ratio;
}

if (aspectTop == 0)
aspectTop = ((float) w / h) / (4.f / 3.f);
// A zero aspect multiplier represents the "window" option. Calculate the
// multiplier from the area available to each screen, rather than from the
// entire panel, so a two-screen layout can fill both panel dimensions.
if (aspectTop == 0 || aspectBot == 0)
{
const float windowAspect = static_cast<float>(w) / h;
const bool singleScreen = sizing == screenSizing_TopOnly
|| sizing == screenSizing_BotOnly;
const bool rotated = screenRotation == screenRot_90Deg
|| screenRotation == screenRot_270Deg;

float windowScreenAspect;
if (singleScreen)
{
// The aspect multiplier is applied before rotation.
windowScreenAspect = rotated
? 192.f / (256.f * windowAspect)
: windowAspect * 192.f / 256.f;
}
else
{
const int layoutDirection = screenLayout == screenLayout_Natural
? screenRotation % 2
: screenLayout - 1;

if (aspectBot == 0)
aspectBot = ((float) w / h) / (4.f / 3.f);
if (layoutDirection == 0)
{
// Screens are stacked along the window's Y axis.
windowScreenAspect = rotated
? (192.f / windowAspect - CurrentScreenGap) / 512.f
: windowAspect * (384.f + CurrentScreenGap) / 256.f;
}
else
{
// Screens are arranged along the window's X axis.
windowScreenAspect = rotated
? (384.f + CurrentScreenGap) / (256.f * windowAspect)
: (windowAspect * 192.f - CurrentScreenGap) / 512.f;
}
}

// Very large gaps or unusually narrow windows can otherwise produce
// a zero or negative width.
windowScreenAspect = std::max(windowScreenAspect, 1.f / 256.f);

if (aspectTop == 0)
aspectTop = windowScreenAspect;
if (aspectBot == 0)
aspectBot = windowScreenAspect;
}

layout.Setup(w, h,
static_cast<ScreenLayoutType>(screenLayout),
static_cast<ScreenRotation>(screenRotation),
static_cast<ScreenSizing>(sizing),
screenGap,
CurrentScreenGap,
integerScaling != 0,
screenSwap != 0,
aspectTop,
Expand All @@ -187,7 +237,7 @@ QSize ScreenPanel::screenGetMinSize(int factor = 1)
{
bool isHori = (screenRotation == screenRot_90Deg
|| screenRotation == screenRot_270Deg);
int gap = screenGap * factor;
int gap = CurrentScreenGap * factor;

int w = 256 * factor;
int h = 192 * factor;
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/qt_sdl/Screen.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,15 @@ private slots:

int screenRotation;
int screenGap;
int HybridRatio;
int screenLayout;
bool screenSwap;
int screenSizing;
bool integerScaling;
int screenAspectTop, screenAspectBot;

int CurrentScreenGap;

int autoScreenSizing;

ScreenLayout layout;
Expand Down
39 changes: 39 additions & 0 deletions src/frontend/qt_sdl/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,27 @@ MainWindow::MainWindow(int id, EmuInstance* inst, QWidget* parent) :

connect(grpScreenGap, &QActionGroup::triggered, this, &MainWindow::onChangeScreenGap);
}
{
QMenu * submenu = menu->addMenu("Hybrid ratio");
GrpHybridRatio = new QActionGroup(submenu);

// ScreenLayout uses the gap between the two smaller screens
// to determine the scale of the large hybrid screen. These
// gap values produce the corresponding display ratios.
const char *hybridRatios[] = {"2:1", "3:1", "4:1", "5:1", "6:1", "7:1", "5:2", "7:3", "9:4"};
const int screenGaps[] = {0, 192, 384, 576, 768, 960, 96, 64, 48};

for (int i = 0; i < 9; i++)
{
int screenGapData = screenGaps[i];
ActHybridRatio[i] = submenu->addAction(QString(hybridRatios[i]));
ActHybridRatio[i]->setActionGroup(GrpHybridRatio);
ActHybridRatio[i]->setData(QVariant(screenGapData));
ActHybridRatio[i]->setCheckable(true);
}

connect(GrpHybridRatio, &QActionGroup::triggered, this, &MainWindow::OnChangeHybridRatio);
}
{
QMenu * submenu = menu->addMenu("Screen layout");
grpScreenLayout = new QActionGroup(submenu);
Expand Down Expand Up @@ -711,6 +732,16 @@ MainWindow::MainWindow(int id, EmuInstance* inst, QWidget* parent) :
}
}

int hybridRatio = windowCfg.GetInt("HybridRatio");
for (int i = 0; i < 9; i++)
{
if (ActHybridRatio[i]->data().toInt() == hybridRatio)
{
ActHybridRatio[i]->setChecked(true);
break;
}
}

actScreenLayout[windowCfg.GetInt("ScreenLayout")]->setChecked(true);
actScreenSizing[windowCfg.GetInt("ScreenSizing")]->setChecked(true);
actIntegerScaling->setChecked(windowCfg.GetBool("IntegerScaling"));
Expand Down Expand Up @@ -2027,6 +2058,14 @@ void MainWindow::onChangeScreenGap(QAction* act)
emit screenLayoutChange();
}

void MainWindow::OnChangeHybridRatio(QAction* act)
{
int gap = act->data().toInt();
windowCfg.SetInt("HybridRatio", gap);

emit screenLayoutChange();
}

void MainWindow::onChangeScreenLayout(QAction* act)
{
int layout = act->data().toInt();
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/qt_sdl/Window.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ private slots:
void onChangeScreenSize();
void onChangeScreenRotation(QAction* act);
void onChangeScreenGap(QAction* act);
void OnChangeHybridRatio(QAction* act);
void onChangeScreenLayout(QAction* act);
void onChangeScreenSwap(bool checked);
void onChangeScreenSizing(QAction* act);
Expand Down Expand Up @@ -279,6 +280,8 @@ private slots:
QAction* actScreenRotation[screenRot_MAX];
QActionGroup* grpScreenGap;
QAction* actScreenGap[6];
QActionGroup* GrpHybridRatio;
QAction* ActHybridRatio[9];
QActionGroup* grpScreenLayout;
QAction* actScreenLayout[screenLayout_MAX];
QAction* actScreenSwap;
Expand Down