port screen layout stuff. encapsulate screen layout code.
This commit is contained in:
parent
2451f3fed8
commit
d480808d72
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
Copyright 2016-2023 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
melonDS is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with melonDS. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#ifndef FRONTENDUTIL_H
|
||||
#define FRONTENDUTIL_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace melonDS
|
||||
{
|
||||
class NDS;
|
||||
}
|
||||
namespace Frontend
|
||||
{
|
||||
using namespace melonDS;
|
||||
|
||||
enum ScreenLayout
|
||||
{
|
||||
screenLayout_Natural, // top screen above bottom screen always
|
||||
screenLayout_Horizontal,
|
||||
screenLayout_Vertical,
|
||||
screenLayout_Hybrid,
|
||||
screenLayout_MAX,
|
||||
};
|
||||
|
||||
enum ScreenRotation
|
||||
{
|
||||
screenRot_0Deg,
|
||||
screenRot_90Deg,
|
||||
screenRot_180Deg,
|
||||
screenRot_270Deg,
|
||||
screenRot_MAX,
|
||||
};
|
||||
|
||||
enum ScreenSizing
|
||||
{
|
||||
screenSizing_Even, // both screens get same size
|
||||
screenSizing_EmphTop, // make top screen as big as possible, fit bottom screen in remaining space
|
||||
screenSizing_EmphBot,
|
||||
screenSizing_Auto, // not applied in SetupScreenLayout
|
||||
screenSizing_TopOnly,
|
||||
screenSizing_BotOnly,
|
||||
screenSizing_MAX,
|
||||
};
|
||||
|
||||
// setup the display layout based on the provided display size and parameters
|
||||
// * screenWidth/screenHeight: size of the host display
|
||||
// * screenLayout: how the DS screens are laid out
|
||||
// * rotation: angle at which the DS screens are presented
|
||||
// * sizing: how the display size is shared between the two screens
|
||||
// * screenGap: size of the gap between the two screens in pixels
|
||||
// * integerScale: force screens to be scaled up at integer scaling factors
|
||||
// * screenSwap: whether to swap the position of both screens
|
||||
// * topAspect/botAspect: ratio by which to scale the top and bottom screen respectively
|
||||
void SetupScreenLayout(int screenWidth, int screenHeight,
|
||||
ScreenLayout screenLayout,
|
||||
ScreenRotation rotation,
|
||||
ScreenSizing sizing,
|
||||
int screenGap,
|
||||
bool integerScale,
|
||||
bool swapScreens,
|
||||
float topAspect, float botAspect);
|
||||
|
||||
const int MaxScreenTransforms = 3;
|
||||
|
||||
// get a 2x3 transform matrix for each screen and whether it's a top or bottom screen
|
||||
// note: the transform assumes an origin point at the top left of the display,
|
||||
// X going right and Y going down
|
||||
// for each screen the source coordinates should be (0,0) and (256,192)
|
||||
// 'out' should point to an array of 6*MaxScreenTransforms floats
|
||||
// 'kind' should point to an array of MaxScreenTransforms ints
|
||||
// (0 = indicates top screen, 1 = bottom screen)
|
||||
// returns the amount of screens
|
||||
int GetScreenTransforms(float* out, int* kind);
|
||||
|
||||
// de-transform the provided host display coordinates to get coordinates
|
||||
// on the bottom screen
|
||||
bool GetTouchCoords(int& x, int& y, bool clamp);
|
||||
|
||||
}
|
||||
|
||||
#endif // FRONTENDUTIL_H
|
|
@ -16,29 +16,13 @@
|
|||
with melonDS. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
#include "FrontendUtil.h"
|
||||
#include "ScreenLayout.h"
|
||||
|
||||
|
||||
namespace Frontend
|
||||
{
|
||||
|
||||
float TopScreenMtx[6];
|
||||
float BotScreenMtx[6];
|
||||
float HybScreenMtx[6];
|
||||
float TouchMtx[6];
|
||||
float HybTouchMtx[6];
|
||||
bool TopEnable;
|
||||
bool BotEnable;
|
||||
bool HybEnable;
|
||||
int HybScreen;
|
||||
int HybPrevTouchScreen; // 0:unknown, 1:buttom screen, 2:hybrid screen
|
||||
|
||||
void M23_Identity(float* m)
|
||||
{
|
||||
m[0] = 1; m[1] = 0;
|
||||
|
@ -122,8 +106,22 @@ void M23_Transform(float* m, float& x, float& y)
|
|||
}
|
||||
|
||||
|
||||
void SetupScreenLayout(int screenWidth, int screenHeight,
|
||||
ScreenLayout screenLayout,
|
||||
ScreenLayout::ScreenLayout()
|
||||
{
|
||||
M23_Identity(TopScreenMtx);
|
||||
M23_Identity(BotScreenMtx);
|
||||
M23_Identity(HybScreenMtx);
|
||||
M23_Identity(TouchMtx);
|
||||
M23_Identity(HybTouchMtx);
|
||||
TopEnable = true;
|
||||
BotEnable = true;
|
||||
HybEnable = false;
|
||||
HybScreen = 0;
|
||||
HybPrevTouchScreen = 0;
|
||||
}
|
||||
|
||||
void ScreenLayout::Setup(int screenWidth, int screenHeight,
|
||||
ScreenLayoutType screenLayout,
|
||||
ScreenRotation rotation,
|
||||
ScreenSizing sizing,
|
||||
int screenGap,
|
||||
|
@ -448,7 +446,7 @@ void SetupScreenLayout(int screenWidth, int screenHeight,
|
|||
}
|
||||
}
|
||||
|
||||
int GetScreenTransforms(float* out, int* kind)
|
||||
int ScreenLayout::GetScreenTransforms(float* out, int* kind)
|
||||
{
|
||||
int num = 0;
|
||||
if (TopEnable)
|
||||
|
@ -469,7 +467,7 @@ int GetScreenTransforms(float* out, int* kind)
|
|||
return num;
|
||||
}
|
||||
|
||||
bool GetTouchCoords(int& x, int& y, bool clamp)
|
||||
bool ScreenLayout::GetTouchCoords(int& x, int& y, bool clamp)
|
||||
{
|
||||
if (HybEnable && HybScreen == 1)
|
||||
{
|
||||
|
@ -548,6 +546,3 @@ bool GetTouchCoords(int& x, int& y, bool clamp)
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
Copyright 2016-2023 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
melonDS is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with melonDS. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#ifndef SCREENLAYOUT_H
|
||||
#define SCREENLAYOUT_H
|
||||
|
||||
enum ScreenLayoutType
|
||||
{
|
||||
screenLayout_Natural, // top screen above bottom screen always
|
||||
screenLayout_Horizontal,
|
||||
screenLayout_Vertical,
|
||||
screenLayout_Hybrid,
|
||||
screenLayout_MAX,
|
||||
};
|
||||
|
||||
enum ScreenRotation
|
||||
{
|
||||
screenRot_0Deg,
|
||||
screenRot_90Deg,
|
||||
screenRot_180Deg,
|
||||
screenRot_270Deg,
|
||||
screenRot_MAX,
|
||||
};
|
||||
|
||||
enum ScreenSizing
|
||||
{
|
||||
screenSizing_Even, // both screens get same size
|
||||
screenSizing_EmphTop, // make top screen as big as possible, fit bottom screen in remaining space
|
||||
screenSizing_EmphBot,
|
||||
screenSizing_Auto, // not applied in SetupScreenLayout
|
||||
screenSizing_TopOnly,
|
||||
screenSizing_BotOnly,
|
||||
screenSizing_MAX,
|
||||
};
|
||||
|
||||
const int kMaxScreenTransforms = 3;
|
||||
|
||||
class ScreenLayout
|
||||
{
|
||||
public:
|
||||
ScreenLayout();
|
||||
~ScreenLayout() {}
|
||||
|
||||
// setup the display layout based on the provided display size and parameters
|
||||
// * screenWidth/screenHeight: size of the host display
|
||||
// * screenLayout: how the DS screens are laid out
|
||||
// * rotation: angle at which the DS screens are presented
|
||||
// * sizing: how the display size is shared between the two screens
|
||||
// * screenGap: size of the gap between the two screens in pixels
|
||||
// * integerScale: force screens to be scaled up at integer scaling factors
|
||||
// * screenSwap: whether to swap the position of both screens
|
||||
// * topAspect/botAspect: ratio by which to scale the top and bottom screen respectively
|
||||
void Setup(int screenWidth, int screenHeight,
|
||||
ScreenLayoutType screenLayout,
|
||||
ScreenRotation rotation,
|
||||
ScreenSizing sizing,
|
||||
int screenGap,
|
||||
bool integerScale,
|
||||
bool swapScreens,
|
||||
float topAspect, float botAspect);
|
||||
|
||||
// get a 2x3 transform matrix for each screen and whether it's a top or bottom screen
|
||||
// note: the transform assumes an origin point at the top left of the display,
|
||||
// X going right and Y going down
|
||||
// for each screen the source coordinates should be (0,0) and (256,192)
|
||||
// 'out' should point to an array of 6*MaxScreenTransforms floats
|
||||
// 'kind' should point to an array of MaxScreenTransforms ints
|
||||
// (0 = indicates top screen, 1 = bottom screen)
|
||||
// returns the amount of screens
|
||||
int GetScreenTransforms(float* out, int* kind);
|
||||
|
||||
// de-transform the provided host display coordinates to get coordinates
|
||||
// on the bottom screen
|
||||
bool GetTouchCoords(int& x, int& y, bool clamp);
|
||||
|
||||
private:
|
||||
float TopScreenMtx[6];
|
||||
float BotScreenMtx[6];
|
||||
float HybScreenMtx[6];
|
||||
float TouchMtx[6];
|
||||
float HybTouchMtx[6];
|
||||
bool TopEnable;
|
||||
bool BotEnable;
|
||||
bool HybEnable;
|
||||
int HybScreen;
|
||||
int HybPrevTouchScreen; // 0:unknown, 1:buttom screen, 2:hybrid screen
|
||||
};
|
||||
|
||||
#endif // SCREENLAYOUT_H
|
|
@ -44,8 +44,7 @@ set(SOURCES_QT_SDL
|
|||
ArchiveUtil.h
|
||||
ArchiveUtil.cpp
|
||||
|
||||
../Util_Video.cpp
|
||||
../FrontendUtil.h
|
||||
../ScreenLayout.cpp
|
||||
../mic_blow.h
|
||||
|
||||
../glad/glad.c
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "Platform.h"
|
||||
#include "Config.h"
|
||||
#include "FrontendUtil.h"
|
||||
#include "ScreenLayout.h"
|
||||
#include "main.h"
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
@ -37,16 +37,6 @@ namespace Config
|
|||
{
|
||||
using namespace melonDS;
|
||||
|
||||
int ScreenRotation;
|
||||
int ScreenGap;
|
||||
int ScreenLayout;
|
||||
bool ScreenSwap;
|
||||
int ScreenSizing;
|
||||
bool IntegerScaling;
|
||||
int ScreenAspectTop;
|
||||
int ScreenAspectBot;
|
||||
bool ScreenFilter;
|
||||
|
||||
bool ScreenUseGL;
|
||||
bool ScreenVSync;
|
||||
int ScreenVSyncInterval;
|
||||
|
@ -108,10 +98,10 @@ RangeList IntRanges =
|
|||
{"Audio.Interpolation", {0, 3}},
|
||||
{"Instance*.Audio.Volume", {0, 256}},
|
||||
{"Mic.InputType", {0, micInputType_MAX-1}},
|
||||
{"Instance*.Window*.ScreenRotation", {0, Frontend::screenRot_MAX-1}},
|
||||
{"Instance*.Window*.ScreenRotation", {0, screenRot_MAX-1}},
|
||||
{"Instance*.Window*.ScreenGap", {0, 500}},
|
||||
{"Instance*.Window*.ScreenLayout", {0, Frontend::screenLayout_MAX-1}},
|
||||
{"Instance*.Window*.ScreenSizing", {0, Frontend::screenSizing_MAX-1}},
|
||||
{"Instance*.Window*.ScreenLayout", {0, screenLayout_MAX-1}},
|
||||
{"Instance*.Window*.ScreenSizing", {0, screenSizing_MAX-1}},
|
||||
{"Instance*.Window*.ScreenAspectTop", {0, AspectRatiosNum-1}},
|
||||
{"Instance*.Window*.ScreenAspectBot", {0, AspectRatiosNum-1}},
|
||||
{"MP.AudioMode", {0, 2}},
|
||||
|
|
|
@ -151,16 +151,6 @@ private:
|
|||
};
|
||||
|
||||
|
||||
extern int ScreenRotation;
|
||||
extern int ScreenGap;
|
||||
extern int ScreenLayout;
|
||||
extern bool ScreenSwap;
|
||||
extern int ScreenSizing;
|
||||
extern int ScreenAspectTop;
|
||||
extern int ScreenAspectBot;
|
||||
extern bool IntegerScaling;
|
||||
extern bool ScreenFilter;
|
||||
|
||||
extern bool ScreenUseGL;
|
||||
extern bool ScreenVSync;
|
||||
extern int ScreenVSyncInterval;
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "types.h"
|
||||
#include "version.h"
|
||||
|
||||
#include "FrontendUtil.h"
|
||||
#include "ScreenLayout.h"
|
||||
|
||||
#include "Args.h"
|
||||
#include "NDS.h"
|
||||
|
@ -79,19 +79,6 @@ EmuThread::EmuThread(EmuInstance* inst, QObject* parent) : QThread(parent)
|
|||
EmuRunning = emuStatus_Paused;
|
||||
EmuPauseStack = EmuPauseStackRunning;
|
||||
RunningSomething = false;
|
||||
|
||||
/*connect(this, SIGNAL(windowUpdate()), mainWindow->panel, SLOT(repaint()));
|
||||
connect(this, SIGNAL(windowTitleChange(QString)), mainWindow, SLOT(onTitleUpdate(QString)));
|
||||
connect(this, SIGNAL(windowEmuStart()), mainWindow, SLOT(onEmuStart()));
|
||||
connect(this, SIGNAL(windowEmuStop()), mainWindow, SLOT(onEmuStop()));
|
||||
connect(this, SIGNAL(windowEmuPause()), mainWindow->actPause, SLOT(trigger()));
|
||||
connect(this, SIGNAL(windowEmuReset()), mainWindow->actReset, SLOT(trigger()));
|
||||
connect(this, SIGNAL(windowEmuFrameStep()), mainWindow->actFrameStep, SLOT(trigger()));
|
||||
connect(this, SIGNAL(windowLimitFPSChange()), mainWindow->actLimitFramerate, SLOT(trigger()));
|
||||
connect(this, SIGNAL(screenLayoutChange()), mainWindow->panel, SLOT(onScreenLayoutChanged()));
|
||||
connect(this, SIGNAL(windowFullscreenToggle()), mainWindow, SLOT(onFullscreenToggled()));
|
||||
connect(this, SIGNAL(swapScreensToggle()), mainWindow->actScreenSwap, SLOT(trigger()));
|
||||
connect(this, SIGNAL(screenEmphasisToggle()), mainWindow, SLOT(onScreenEmphasisToggled()));*/
|
||||
}
|
||||
|
||||
void EmuThread::attachWindow(MainWindow* window)
|
||||
|
@ -108,7 +95,7 @@ void EmuThread::attachWindow(MainWindow* window)
|
|||
connect(this, SIGNAL(windowEmuReset()), window->actReset, SLOT(trigger()));
|
||||
connect(this, SIGNAL(windowEmuFrameStep()), window->actFrameStep, SLOT(trigger()));
|
||||
connect(this, SIGNAL(windowLimitFPSChange()), window->actLimitFramerate, SLOT(trigger()));
|
||||
connect(this, SIGNAL(screenLayoutChange()), window->panel, SLOT(onScreenLayoutChanged()));
|
||||
connect(this, SIGNAL(autoScreenSizingChange(int)), window->panel, SLOT(onAutoScreenSizingChanged(int)));
|
||||
connect(this, SIGNAL(windowFullscreenToggle()), window, SLOT(onFullscreenToggled()));
|
||||
connect(this, SIGNAL(swapScreensToggle()), window->actScreenSwap, SLOT(trigger()));
|
||||
connect(this, SIGNAL(screenEmphasisToggle()), window, SLOT(onScreenEmphasisToggled()));
|
||||
|
@ -124,7 +111,7 @@ void EmuThread::detachWindow(MainWindow* window)
|
|||
disconnect(this, SIGNAL(windowEmuReset()), window->actReset, SLOT(trigger()));
|
||||
disconnect(this, SIGNAL(windowEmuFrameStep()), window->actFrameStep, SLOT(trigger()));
|
||||
disconnect(this, SIGNAL(windowLimitFPSChange()), window->actLimitFramerate, SLOT(trigger()));
|
||||
disconnect(this, SIGNAL(screenLayoutChange()), window->panel, SLOT(onScreenLayoutChanged()));
|
||||
disconnect(this, SIGNAL(autoScreenSizingChange(int)), window->panel, SLOT(onAutoScreenSizingChanged(int)));
|
||||
disconnect(this, SIGNAL(windowFullscreenToggle()), window, SLOT(onFullscreenToggled()));
|
||||
disconnect(this, SIGNAL(swapScreensToggle()), window->actScreenSwap, SLOT(trigger()));
|
||||
disconnect(this, SIGNAL(screenEmphasisToggle()), window, SLOT(onScreenEmphasisToggled()));
|
||||
|
@ -307,7 +294,6 @@ void EmuThread::run()
|
|||
emuInstance->micProcess();
|
||||
|
||||
// auto screen layout
|
||||
if (Config::ScreenSizing == Frontend::screenSizing_Auto)
|
||||
{
|
||||
mainScreenPos[2] = mainScreenPos[1];
|
||||
mainScreenPos[1] = mainScreenPos[0];
|
||||
|
@ -319,20 +305,20 @@ void EmuThread::run()
|
|||
{
|
||||
// constant flickering, likely displaying 3D on both screens
|
||||
// TODO: when both screens are used for 2D only...???
|
||||
guess = Frontend::screenSizing_Even;
|
||||
guess = screenSizing_Even;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mainScreenPos[0] == 1)
|
||||
guess = Frontend::screenSizing_EmphTop;
|
||||
guess = screenSizing_EmphTop;
|
||||
else
|
||||
guess = Frontend::screenSizing_EmphBot;
|
||||
guess = screenSizing_EmphBot;
|
||||
}
|
||||
|
||||
if (guess != autoScreenSizing)
|
||||
{
|
||||
autoScreenSizing = guess;
|
||||
emit screenLayoutChange();
|
||||
emit autoScreenSizingChange(autoScreenSizing);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ signals:
|
|||
|
||||
void windowLimitFPSChange();
|
||||
|
||||
void screenLayoutChange();
|
||||
void autoScreenSizingChange(int sizing);
|
||||
|
||||
void windowFullscreenToggle();
|
||||
|
||||
|
|
|
@ -59,7 +59,6 @@ using namespace melonDS;
|
|||
|
||||
// TEMP
|
||||
extern bool RunningSomething;
|
||||
extern int autoScreenSizing;
|
||||
|
||||
extern int videoRenderer;
|
||||
extern bool videoSettingsDirty;
|
||||
|
@ -91,6 +90,9 @@ ScreenPanel::ScreenPanel(QWidget* parent) : QWidget(parent)
|
|||
|
||||
osdEnabled = false;
|
||||
osdID = 1;
|
||||
|
||||
loadConfig();
|
||||
setFilter(mainWindow->getWindowConfig().GetBool("ScreenFilter"));
|
||||
}
|
||||
|
||||
ScreenPanel::~ScreenPanel()
|
||||
|
@ -99,6 +101,25 @@ ScreenPanel::~ScreenPanel()
|
|||
delete mouseTimer;
|
||||
}
|
||||
|
||||
void ScreenPanel::loadConfig()
|
||||
{
|
||||
auto& cfg = mainWindow->getWindowConfig();
|
||||
|
||||
screenRotation = cfg.GetInt("ScreenRotation");
|
||||
screenGap = cfg.GetInt("ScreenGap");
|
||||
screenLayout = cfg.GetInt("ScreenLayout");
|
||||
screenSwap = cfg.GetBool("ScreenSwap");
|
||||
screenSizing = cfg.GetInt("ScreenSizing");
|
||||
integerScaling = cfg.GetBool("IntegerScaling");
|
||||
screenAspectTop = cfg.GetInt("ScreenAspectTop");
|
||||
screenAspectBot = cfg.GetInt("ScreenAspectBot");
|
||||
}
|
||||
|
||||
void ScreenPanel::setFilter(bool filter)
|
||||
{
|
||||
this->filter = filter;
|
||||
}
|
||||
|
||||
void ScreenPanel::setMouseHide(bool enable, int delay)
|
||||
{
|
||||
mouseHide = enable;
|
||||
|
@ -112,16 +133,16 @@ void ScreenPanel::setupScreenLayout()
|
|||
int w = width();
|
||||
int h = height();
|
||||
|
||||
int sizing = Config::ScreenSizing;
|
||||
if (sizing == 3) sizing = autoScreenSizing;
|
||||
int sizing = screenSizing;
|
||||
if (sizing == screenSizing_Auto) sizing = autoScreenSizing;
|
||||
|
||||
float aspectTop, aspectBot;
|
||||
|
||||
for (auto ratio : aspectRatios)
|
||||
{
|
||||
if (ratio.id == Config::ScreenAspectTop)
|
||||
if (ratio.id == screenAspectTop)
|
||||
aspectTop = ratio.ratio;
|
||||
if (ratio.id == Config::ScreenAspectBot)
|
||||
if (ratio.id == screenAspectBot)
|
||||
aspectBot = ratio.ratio;
|
||||
}
|
||||
|
||||
|
@ -131,49 +152,49 @@ void ScreenPanel::setupScreenLayout()
|
|||
if (aspectBot == 0)
|
||||
aspectBot = ((float) w / h) / (4.f / 3.f);
|
||||
|
||||
Frontend::SetupScreenLayout(w, h,
|
||||
static_cast<Frontend::ScreenLayout>(Config::ScreenLayout),
|
||||
static_cast<Frontend::ScreenRotation>(Config::ScreenRotation),
|
||||
static_cast<Frontend::ScreenSizing>(sizing),
|
||||
Config::ScreenGap,
|
||||
Config::IntegerScaling != 0,
|
||||
Config::ScreenSwap != 0,
|
||||
layout.Setup(w, h,
|
||||
static_cast<ScreenLayoutType>(screenLayout),
|
||||
static_cast<ScreenRotation>(screenRotation),
|
||||
static_cast<ScreenSizing>(sizing),
|
||||
screenGap,
|
||||
integerScaling != 0,
|
||||
screenSwap != 0,
|
||||
aspectTop,
|
||||
aspectBot);
|
||||
|
||||
numScreens = Frontend::GetScreenTransforms(screenMatrix[0], screenKind);
|
||||
numScreens = layout.GetScreenTransforms(screenMatrix[0], screenKind);
|
||||
}
|
||||
|
||||
QSize ScreenPanel::screenGetMinSize(int factor = 1)
|
||||
{
|
||||
bool isHori = (Config::ScreenRotation == Frontend::screenRot_90Deg
|
||||
|| Config::ScreenRotation == Frontend::screenRot_270Deg);
|
||||
int gap = Config::ScreenGap * factor;
|
||||
bool isHori = (screenRotation == screenRot_90Deg
|
||||
|| screenRotation == screenRot_270Deg);
|
||||
int gap = screenGap * factor;
|
||||
|
||||
int w = 256 * factor;
|
||||
int h = 192 * factor;
|
||||
|
||||
if (Config::ScreenSizing == Frontend::screenSizing_TopOnly
|
||||
|| Config::ScreenSizing == Frontend::screenSizing_BotOnly)
|
||||
if (screenSizing == screenSizing_TopOnly
|
||||
|| screenSizing == screenSizing_BotOnly)
|
||||
{
|
||||
return QSize(w, h);
|
||||
}
|
||||
|
||||
if (Config::ScreenLayout == Frontend::screenLayout_Natural)
|
||||
if (screenLayout == screenLayout_Natural)
|
||||
{
|
||||
if (isHori)
|
||||
return QSize(h+gap+h, w);
|
||||
else
|
||||
return QSize(w, h+gap+h);
|
||||
}
|
||||
else if (Config::ScreenLayout == Frontend::screenLayout_Vertical)
|
||||
else if (screenLayout == screenLayout_Vertical)
|
||||
{
|
||||
if (isHori)
|
||||
return QSize(h, w+gap+w);
|
||||
else
|
||||
return QSize(w, h+gap+h);
|
||||
}
|
||||
else if (Config::ScreenLayout == Frontend::screenLayout_Horizontal)
|
||||
else if (screenLayout == screenLayout_Horizontal)
|
||||
{
|
||||
if (isHori)
|
||||
return QSize(h+gap+h, w);
|
||||
|
@ -191,10 +212,20 @@ QSize ScreenPanel::screenGetMinSize(int factor = 1)
|
|||
|
||||
void ScreenPanel::onScreenLayoutChanged()
|
||||
{
|
||||
loadConfig();
|
||||
|
||||
setMinimumSize(screenGetMinSize());
|
||||
setupScreenLayout();
|
||||
}
|
||||
|
||||
void ScreenPanel::onAutoScreenSizingChanged(int sizing)
|
||||
{
|
||||
autoScreenSizing = sizing;
|
||||
if (screenSizing != screenSizing_Auto) return;
|
||||
|
||||
setupScreenLayout();
|
||||
}
|
||||
|
||||
void ScreenPanel::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
setupScreenLayout();
|
||||
|
@ -209,7 +240,7 @@ void ScreenPanel::mousePressEvent(QMouseEvent* event)
|
|||
int x = event->pos().x();
|
||||
int y = event->pos().y();
|
||||
|
||||
if (Frontend::GetTouchCoords(x, y, false))
|
||||
if (layout.GetTouchCoords(x, y, false))
|
||||
{
|
||||
touching = true;
|
||||
assert(emuInstance->getNDS() != nullptr);
|
||||
|
@ -242,7 +273,7 @@ void ScreenPanel::mouseMoveEvent(QMouseEvent* event)
|
|||
int x = event->pos().x();
|
||||
int y = event->pos().y();
|
||||
|
||||
if (Frontend::GetTouchCoords(x, y, true))
|
||||
if (layout.GetTouchCoords(x, y, true))
|
||||
{
|
||||
assert(emuInstance->getNDS() != nullptr);
|
||||
emuInstance->getNDS()->TouchScreen(x, y);
|
||||
|
@ -261,7 +292,7 @@ void ScreenPanel::tabletEvent(QTabletEvent* event)
|
|||
int x = event->x();
|
||||
int y = event->y();
|
||||
|
||||
if (Frontend::GetTouchCoords(x, y, event->type()==QEvent::TabletMove))
|
||||
if (layout.GetTouchCoords(x, y, event->type()==QEvent::TabletMove))
|
||||
{
|
||||
touching = true;
|
||||
assert(emuInstance->getNDS() != nullptr);
|
||||
|
@ -296,7 +327,7 @@ void ScreenPanel::touchEvent(QTouchEvent* event)
|
|||
int x = (int)lastPosition.x();
|
||||
int y = (int)lastPosition.y();
|
||||
|
||||
if (Frontend::GetTouchCoords(x, y, event->type()==QEvent::TouchUpdate))
|
||||
if (layout.GetTouchCoords(x, y, event->type()==QEvent::TouchUpdate))
|
||||
{
|
||||
touching = true;
|
||||
assert(emuInstance->getNDS() != nullptr);
|
||||
|
@ -1115,7 +1146,6 @@ void ScreenPanelGL::transferLayout()
|
|||
lastScreenHeight = windowInfo->surface_height;
|
||||
}
|
||||
|
||||
this->filter = Config::ScreenFilter;
|
||||
this->windowInfo = *windowInfo;
|
||||
|
||||
screenSettingsLock.unlock();
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include <QTimer>
|
||||
|
||||
#include "glad/glad.h"
|
||||
#include "FrontendUtil.h"
|
||||
#include "ScreenLayout.h"
|
||||
#include "duckstation/gl/context.h"
|
||||
|
||||
|
||||
|
@ -58,6 +58,8 @@ public:
|
|||
explicit ScreenPanel(QWidget* parent);
|
||||
virtual ~ScreenPanel();
|
||||
|
||||
void setFilter(bool filter);
|
||||
|
||||
void setMouseHide(bool enable, int delay);
|
||||
|
||||
QTimer* setupMouseTimer();
|
||||
|
@ -70,11 +72,31 @@ public:
|
|||
|
||||
private slots:
|
||||
void onScreenLayoutChanged();
|
||||
void onAutoScreenSizingChanged(int sizing);
|
||||
|
||||
protected:
|
||||
MainWindow* mainWindow;
|
||||
EmuInstance* emuInstance;
|
||||
|
||||
bool filter;
|
||||
|
||||
int screenRotation;
|
||||
int screenGap;
|
||||
int screenLayout;
|
||||
bool screenSwap;
|
||||
int screenSizing;
|
||||
bool integerScaling;
|
||||
int screenAspectTop, screenAspectBot;
|
||||
|
||||
int autoScreenSizing;
|
||||
|
||||
ScreenLayout layout;
|
||||
float screenMatrix[kMaxScreenTransforms][6];
|
||||
int screenKind[kMaxScreenTransforms];
|
||||
int numScreens;
|
||||
|
||||
bool touching = false;
|
||||
|
||||
bool mouseHide;
|
||||
int mouseHideDelay;
|
||||
|
||||
|
@ -95,6 +117,8 @@ protected:
|
|||
unsigned int osdID;
|
||||
std::deque<OSDItem> osdItems;
|
||||
|
||||
void loadConfig();
|
||||
|
||||
virtual void setupScreenLayout();
|
||||
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
|
@ -107,12 +131,6 @@ protected:
|
|||
void touchEvent(QTouchEvent* event);
|
||||
bool event(QEvent* event) override;
|
||||
|
||||
float screenMatrix[Frontend::MaxScreenTransforms][6];
|
||||
int screenKind[Frontend::MaxScreenTransforms];
|
||||
int numScreens;
|
||||
|
||||
bool touching = false;
|
||||
|
||||
void showCursor();
|
||||
|
||||
int osdFindBreakPoint(const char* text, int i);
|
||||
|
@ -141,7 +159,7 @@ private:
|
|||
void setupScreenLayout() override;
|
||||
|
||||
QImage screen[2];
|
||||
QTransform screenTrans[Frontend::MaxScreenTransforms];
|
||||
QTransform screenTrans[kMaxScreenTransforms];
|
||||
};
|
||||
|
||||
|
||||
|
@ -187,7 +205,6 @@ private:
|
|||
|
||||
QMutex screenSettingsLock;
|
||||
WindowInfo windowInfo;
|
||||
bool filter;
|
||||
|
||||
int lastScreenWidth = -1, lastScreenHeight = -1;
|
||||
|
||||
|
|
|
@ -462,7 +462,7 @@ MainWindow::MainWindow(int id, EmuInstance* inst, QWidget* parent) :
|
|||
QMenu* submenu = menu->addMenu("Screen rotation");
|
||||
grpScreenRotation = new QActionGroup(submenu);
|
||||
|
||||
for (int i = 0; i < Frontend::screenRot_MAX; i++)
|
||||
for (int i = 0; i < screenRot_MAX; i++)
|
||||
{
|
||||
int data = i*90;
|
||||
actScreenRotation[i] = submenu->addAction(QString("%1°").arg(data));
|
||||
|
@ -496,7 +496,7 @@ MainWindow::MainWindow(int id, EmuInstance* inst, QWidget* parent) :
|
|||
|
||||
const char* screenlayout[] = {"Natural", "Vertical", "Horizontal", "Hybrid"};
|
||||
|
||||
for (int i = 0; i < Frontend::screenLayout_MAX; i++)
|
||||
for (int i = 0; i < screenLayout_MAX; i++)
|
||||
{
|
||||
actScreenLayout[i] = submenu->addAction(QString(screenlayout[i]));
|
||||
actScreenLayout[i]->setActionGroup(grpScreenLayout);
|
||||
|
@ -518,7 +518,7 @@ MainWindow::MainWindow(int id, EmuInstance* inst, QWidget* parent) :
|
|||
|
||||
const char* screensizing[] = {"Even", "Emphasize top", "Emphasize bottom", "Auto", "Top only", "Bottom only"};
|
||||
|
||||
for (int i = 0; i < Frontend::screenSizing_MAX; i++)
|
||||
for (int i = 0; i < screenSizing_MAX; i++)
|
||||
{
|
||||
actScreenSizing[i] = submenu->addAction(QString(screensizing[i]));
|
||||
actScreenSizing[i]->setActionGroup(grpScreenSizing);
|
||||
|
@ -594,8 +594,6 @@ MainWindow::MainWindow(int id, EmuInstance* inst, QWidget* parent) :
|
|||
}
|
||||
setMenuBar(menubar);
|
||||
|
||||
//resize(curW, curH);
|
||||
|
||||
if (localCfg.GetString("Firmware.Username") == "Arisotura")
|
||||
actMPNewInstance->setText("Fart");
|
||||
|
||||
|
@ -606,10 +604,6 @@ MainWindow::MainWindow(int id, EmuInstance* inst, QWidget* parent) :
|
|||
move(frameGeo.topLeft());
|
||||
#endif
|
||||
|
||||
/*if (oldMax)
|
||||
showMaximized();
|
||||
else
|
||||
show();*/
|
||||
std::string geom = windowCfg.GetString("Geometry");
|
||||
if (!geom.empty())
|
||||
{
|
||||
|
@ -658,32 +652,35 @@ MainWindow::MainWindow(int id, EmuInstance* inst, QWidget* parent) :
|
|||
|
||||
actSavestateSRAMReloc->setChecked(globalCfg.GetBool("Savestate.RelocSRAM"));
|
||||
|
||||
actScreenRotation[Config::ScreenRotation]->setChecked(true);
|
||||
actScreenRotation[windowCfg.GetInt("ScreenRotation")]->setChecked(true);
|
||||
|
||||
int screenGap = windowCfg.GetInt("ScreenGap");
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (actScreenGap[i]->data().toInt() == Config::ScreenGap)
|
||||
if (actScreenGap[i]->data().toInt() == screenGap)
|
||||
{
|
||||
actScreenGap[i]->setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
actScreenLayout[Config::ScreenLayout]->setChecked(true);
|
||||
actScreenSizing[Config::ScreenSizing]->setChecked(true);
|
||||
actIntegerScaling->setChecked(Config::IntegerScaling);
|
||||
actScreenLayout[windowCfg.GetInt("ScreenLayout")]->setChecked(true);
|
||||
actScreenSizing[windowCfg.GetInt("ScreenSizing")]->setChecked(true);
|
||||
actIntegerScaling->setChecked(windowCfg.GetBool("IntegerScaling"));
|
||||
|
||||
actScreenSwap->setChecked(Config::ScreenSwap);
|
||||
actScreenSwap->setChecked(windowCfg.GetBool("ScreenSwap"));
|
||||
|
||||
int aspectTop = windowCfg.GetInt("ScreenAspectTop");
|
||||
int aspectBot = windowCfg.GetInt("ScreenAspectBot");
|
||||
for (int i = 0; i < AspectRatiosNum; i++)
|
||||
{
|
||||
if (Config::ScreenAspectTop == aspectRatios[i].id)
|
||||
if (aspectTop == aspectRatios[i].id)
|
||||
actScreenAspectTop[i]->setChecked(true);
|
||||
if (Config::ScreenAspectBot == aspectRatios[i].id)
|
||||
if (aspectBot == aspectRatios[i].id)
|
||||
actScreenAspectBot[i]->setChecked(true);
|
||||
}
|
||||
|
||||
actScreenFiltering->setChecked(Config::ScreenFilter);
|
||||
actScreenFiltering->setChecked(windowCfg.GetBool("ScreenFilter"));
|
||||
actShowOSD->setChecked(showOSD);
|
||||
|
||||
actLimitFramerate->setChecked(emuInstance->doLimitFPS);
|
||||
|
@ -1886,7 +1883,7 @@ void MainWindow::onChangeScreenSize()
|
|||
void MainWindow::onChangeScreenRotation(QAction* act)
|
||||
{
|
||||
int rot = act->data().toInt();
|
||||
Config::ScreenRotation = rot;
|
||||
windowCfg.SetInt("ScreenRotation", rot);
|
||||
|
||||
emit screenLayoutChange();
|
||||
}
|
||||
|
@ -1894,7 +1891,7 @@ void MainWindow::onChangeScreenRotation(QAction* act)
|
|||
void MainWindow::onChangeScreenGap(QAction* act)
|
||||
{
|
||||
int gap = act->data().toInt();
|
||||
Config::ScreenGap = gap;
|
||||
windowCfg.SetInt("ScreenGap", gap);
|
||||
|
||||
emit screenLayoutChange();
|
||||
}
|
||||
|
@ -1902,30 +1899,32 @@ void MainWindow::onChangeScreenGap(QAction* act)
|
|||
void MainWindow::onChangeScreenLayout(QAction* act)
|
||||
{
|
||||
int layout = act->data().toInt();
|
||||
Config::ScreenLayout = layout;
|
||||
windowCfg.SetInt("ScreenLayout", layout);
|
||||
|
||||
emit screenLayoutChange();
|
||||
}
|
||||
|
||||
void MainWindow::onChangeScreenSwap(bool checked)
|
||||
{
|
||||
Config::ScreenSwap = checked?1:0;
|
||||
windowCfg.SetBool("ScreenSwap", checked);
|
||||
|
||||
// Swap between top and bottom screen when displaying one screen.
|
||||
if (Config::ScreenSizing == Frontend::screenSizing_TopOnly)
|
||||
int sizing = windowCfg.GetInt("ScreenSizing");
|
||||
if (sizing == screenSizing_TopOnly)
|
||||
{
|
||||
// Bottom Screen.
|
||||
Config::ScreenSizing = Frontend::screenSizing_BotOnly;
|
||||
actScreenSizing[Frontend::screenSizing_TopOnly]->setChecked(false);
|
||||
actScreenSizing[Config::ScreenSizing]->setChecked(true);
|
||||
sizing = screenSizing_BotOnly;
|
||||
actScreenSizing[screenSizing_TopOnly]->setChecked(false);
|
||||
actScreenSizing[sizing]->setChecked(true);
|
||||
}
|
||||
else if (Config::ScreenSizing == Frontend::screenSizing_BotOnly)
|
||||
else if (sizing == screenSizing_BotOnly)
|
||||
{
|
||||
// Top Screen.
|
||||
Config::ScreenSizing = Frontend::screenSizing_TopOnly;
|
||||
actScreenSizing[Frontend::screenSizing_BotOnly]->setChecked(false);
|
||||
actScreenSizing[Config::ScreenSizing]->setChecked(true);
|
||||
sizing = screenSizing_TopOnly;
|
||||
actScreenSizing[screenSizing_BotOnly]->setChecked(false);
|
||||
actScreenSizing[sizing]->setChecked(true);
|
||||
}
|
||||
windowCfg.SetInt("ScreenSizing", sizing);
|
||||
|
||||
emit screenLayoutChange();
|
||||
}
|
||||
|
@ -1933,7 +1932,7 @@ void MainWindow::onChangeScreenSwap(bool checked)
|
|||
void MainWindow::onChangeScreenSizing(QAction* act)
|
||||
{
|
||||
int sizing = act->data().toInt();
|
||||
Config::ScreenSizing = sizing;
|
||||
windowCfg.SetInt("ScreenSizing", sizing);
|
||||
|
||||
emit screenLayoutChange();
|
||||
}
|
||||
|
@ -1945,11 +1944,11 @@ void MainWindow::onChangeScreenAspect(QAction* act)
|
|||
|
||||
if (group == grpScreenAspectTop)
|
||||
{
|
||||
Config::ScreenAspectTop = aspect;
|
||||
windowCfg.SetInt("ScreenAspectTop", aspect);
|
||||
}
|
||||
else
|
||||
{
|
||||
Config::ScreenAspectBot = aspect;
|
||||
windowCfg.SetInt("ScreenAspectBot", aspect);
|
||||
}
|
||||
|
||||
emit screenLayoutChange();
|
||||
|
@ -1957,16 +1956,17 @@ void MainWindow::onChangeScreenAspect(QAction* act)
|
|||
|
||||
void MainWindow::onChangeIntegerScaling(bool checked)
|
||||
{
|
||||
Config::IntegerScaling = checked?1:0;
|
||||
windowCfg.SetBool("IntegerScaling", checked);
|
||||
|
||||
emit screenLayoutChange();
|
||||
}
|
||||
|
||||
void MainWindow::onChangeScreenFiltering(bool checked)
|
||||
{
|
||||
Config::ScreenFilter = checked?1:0;
|
||||
windowCfg.SetBool("ScreenFilter", checked);
|
||||
|
||||
emit screenLayoutChange();
|
||||
//emit screenLayoutChange();
|
||||
panel->setFilter(checked);
|
||||
}
|
||||
|
||||
void MainWindow::onChangeShowOSD(bool checked)
|
||||
|
@ -2016,15 +2016,16 @@ void MainWindow::onFullscreenToggled()
|
|||
|
||||
void MainWindow::onScreenEmphasisToggled()
|
||||
{
|
||||
int currentSizing = Config::ScreenSizing;
|
||||
if (currentSizing == Frontend::screenSizing_EmphTop)
|
||||
int currentSizing = windowCfg.GetInt("ScreenSizing");
|
||||
if (currentSizing == screenSizing_EmphTop)
|
||||
{
|
||||
Config::ScreenSizing = Frontend::screenSizing_EmphBot;
|
||||
currentSizing = screenSizing_EmphBot;
|
||||
}
|
||||
else if (currentSizing == Frontend::screenSizing_EmphBot)
|
||||
else if (currentSizing == screenSizing_EmphBot)
|
||||
{
|
||||
Config::ScreenSizing = Frontend::screenSizing_EmphTop;
|
||||
currentSizing = screenSizing_EmphTop;
|
||||
}
|
||||
windowCfg.SetInt("ScreenSizing", currentSizing);
|
||||
|
||||
emit screenLayoutChange();
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#define WINDOW_H
|
||||
|
||||
#include "glad/glad.h"
|
||||
#include "FrontendUtil.h"
|
||||
#include "ScreenLayout.h"
|
||||
#include "duckstation/gl/context.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
@ -108,6 +108,7 @@ public:
|
|||
~MainWindow();
|
||||
|
||||
EmuInstance* getEmuInstance() { return emuInstance; }
|
||||
Config::Table& getWindowConfig() { return windowCfg; }
|
||||
|
||||
void attachEmuThread(EmuThread* thread);
|
||||
|
||||
|
@ -296,14 +297,14 @@ public:
|
|||
QAction* actSavestateSRAMReloc;
|
||||
QAction* actScreenSize[4];
|
||||
QActionGroup* grpScreenRotation;
|
||||
QAction* actScreenRotation[Frontend::screenRot_MAX];
|
||||
QAction* actScreenRotation[screenRot_MAX];
|
||||
QActionGroup* grpScreenGap;
|
||||
QAction* actScreenGap[6];
|
||||
QActionGroup* grpScreenLayout;
|
||||
QAction* actScreenLayout[Frontend::screenLayout_MAX];
|
||||
QAction* actScreenLayout[screenLayout_MAX];
|
||||
QAction* actScreenSwap;
|
||||
QActionGroup* grpScreenSizing;
|
||||
QAction* actScreenSizing[Frontend::screenSizing_MAX];
|
||||
QAction* actScreenSizing[screenSizing_MAX];
|
||||
QAction* actIntegerScaling;
|
||||
QActionGroup* grpScreenAspectTop;
|
||||
QAction** actScreenAspectTop;
|
||||
|
|
|
@ -318,12 +318,6 @@ int main(int argc, char** argv)
|
|||
#endif
|
||||
SANITIZE(Config::ScreenVSyncInterval, 1, 20);
|
||||
SANITIZE(Config::GL_ScaleFactor, 1, 16);
|
||||
SANITIZE(Config::ScreenRotation, 0, (int)Frontend::screenRot_MAX);
|
||||
SANITIZE(Config::ScreenGap, 0, 500);
|
||||
SANITIZE(Config::ScreenLayout, 0, (int)Frontend::screenLayout_MAX);
|
||||
SANITIZE(Config::ScreenSizing, 0, (int)Frontend::screenSizing_MAX);
|
||||
SANITIZE(Config::ScreenAspectTop, 0, AspectRatiosNum);
|
||||
SANITIZE(Config::ScreenAspectBot, 0, AspectRatiosNum);
|
||||
#undef SANITIZE
|
||||
|
||||
camStarted[0] = false;
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "EmuInstance.h"
|
||||
#include "Window.h"
|
||||
#include "EmuThread.h"
|
||||
#include "FrontendUtil.h"
|
||||
#include "ScreenLayout.h"
|
||||
|
||||
class MelonApplication : public QApplication
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue