mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-21 05:09:46 -06:00
move MainWindow and Screen stuff to separate files; WIP
This commit is contained in:
@ -5,6 +5,8 @@ include(FixInterfaceIncludes)
|
|||||||
set(SOURCES_QT_SDL
|
set(SOURCES_QT_SDL
|
||||||
main.cpp
|
main.cpp
|
||||||
main_shaders.h
|
main_shaders.h
|
||||||
|
Screen.cpp
|
||||||
|
Window.cpp
|
||||||
CheatsDialog.cpp
|
CheatsDialog.cpp
|
||||||
Config.cpp
|
Config.cpp
|
||||||
DateTimeDialog.cpp
|
DateTimeDialog.cpp
|
||||||
@ -38,7 +40,7 @@ set(SOURCES_QT_SDL
|
|||||||
SaveManager.cpp
|
SaveManager.cpp
|
||||||
CameraManager.cpp
|
CameraManager.cpp
|
||||||
AudioInOut.cpp
|
AudioInOut.cpp
|
||||||
|
|
||||||
ArchiveUtil.h
|
ArchiveUtil.h
|
||||||
ArchiveUtil.cpp
|
ArchiveUtil.cpp
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#ifndef INPUT_H
|
#ifndef INPUT_H
|
||||||
#define INPUT_H
|
#define INPUT_H
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
namespace Input
|
namespace Input
|
||||||
|
564
src/frontend/qt_sdl/Screen.cpp
Normal file
564
src/frontend/qt_sdl/Screen.cpp
Normal file
@ -0,0 +1,564 @@
|
|||||||
|
/*
|
||||||
|
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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <QPaintEvent>
|
||||||
|
#include <QPainter>
|
||||||
|
#ifndef _WIN32
|
||||||
|
#ifndef APPLE
|
||||||
|
#include <qpa/qplatformnativeinterface.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#include "NDS.h"
|
||||||
|
#include "Platform.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
//#include "main_shaders.h"
|
||||||
|
|
||||||
|
#include "OSD.h"
|
||||||
|
|
||||||
|
using namespace melonDS;
|
||||||
|
|
||||||
|
|
||||||
|
/*const struct { int id; float ratio; const char* label; } aspectRatios[] =
|
||||||
|
{
|
||||||
|
{ 0, 1, "4:3 (native)" },
|
||||||
|
{ 4, (5.f / 3) / (4.f / 3), "5:3 (3DS)"},
|
||||||
|
{ 1, (16.f / 9) / (4.f / 3), "16:9" },
|
||||||
|
{ 2, (21.f / 9) / (4.f / 3), "21:9" },
|
||||||
|
{ 3, 0, "window" }
|
||||||
|
};
|
||||||
|
int AspectRatiosNum = sizeof(aspectRatios) / sizeof(aspectRatios[0]);*/
|
||||||
|
|
||||||
|
// TEMP
|
||||||
|
extern MainWindow* mainWindow;
|
||||||
|
extern EmuThread* emuThread;
|
||||||
|
extern bool RunningSomething;
|
||||||
|
extern int autoScreenSizing;
|
||||||
|
|
||||||
|
extern int videoRenderer;
|
||||||
|
extern bool videoSettingsDirty;
|
||||||
|
|
||||||
|
|
||||||
|
ScreenHandler::ScreenHandler(QWidget* widget)
|
||||||
|
{
|
||||||
|
widget->setMouseTracking(true);
|
||||||
|
widget->setAttribute(Qt::WA_AcceptTouchEvents);
|
||||||
|
QTimer* mouseTimer = setupMouseTimer();
|
||||||
|
widget->connect(mouseTimer, &QTimer::timeout, [=] { if (Config::MouseHide) widget->setCursor(Qt::BlankCursor);});
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenHandler::~ScreenHandler()
|
||||||
|
{
|
||||||
|
mouseTimer->stop();
|
||||||
|
delete mouseTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenHandler::screenSetupLayout(int w, int h)
|
||||||
|
{
|
||||||
|
int sizing = Config::ScreenSizing;
|
||||||
|
if (sizing == 3) sizing = autoScreenSizing;
|
||||||
|
|
||||||
|
float aspectTop, aspectBot;
|
||||||
|
|
||||||
|
for (auto ratio : aspectRatios)
|
||||||
|
{
|
||||||
|
if (ratio.id == Config::ScreenAspectTop)
|
||||||
|
aspectTop = ratio.ratio;
|
||||||
|
if (ratio.id == Config::ScreenAspectBot)
|
||||||
|
aspectBot = ratio.ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aspectTop == 0)
|
||||||
|
aspectTop = ((float) w / h) / (4.f / 3.f);
|
||||||
|
|
||||||
|
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,
|
||||||
|
aspectTop,
|
||||||
|
aspectBot);
|
||||||
|
|
||||||
|
numScreens = Frontend::GetScreenTransforms(screenMatrix[0], screenKind);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize ScreenHandler::screenGetMinSize(int factor = 1)
|
||||||
|
{
|
||||||
|
bool isHori = (Config::ScreenRotation == Frontend::screenRot_90Deg
|
||||||
|
|| Config::ScreenRotation == Frontend::screenRot_270Deg);
|
||||||
|
int gap = Config::ScreenGap * factor;
|
||||||
|
|
||||||
|
int w = 256 * factor;
|
||||||
|
int h = 192 * factor;
|
||||||
|
|
||||||
|
if (Config::ScreenSizing == Frontend::screenSizing_TopOnly
|
||||||
|
|| Config::ScreenSizing == Frontend::screenSizing_BotOnly)
|
||||||
|
{
|
||||||
|
return QSize(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Config::ScreenLayout == Frontend::screenLayout_Natural)
|
||||||
|
{
|
||||||
|
if (isHori)
|
||||||
|
return QSize(h+gap+h, w);
|
||||||
|
else
|
||||||
|
return QSize(w, h+gap+h);
|
||||||
|
}
|
||||||
|
else if (Config::ScreenLayout == Frontend::screenLayout_Vertical)
|
||||||
|
{
|
||||||
|
if (isHori)
|
||||||
|
return QSize(h, w+gap+w);
|
||||||
|
else
|
||||||
|
return QSize(w, h+gap+h);
|
||||||
|
}
|
||||||
|
else if (Config::ScreenLayout == Frontend::screenLayout_Horizontal)
|
||||||
|
{
|
||||||
|
if (isHori)
|
||||||
|
return QSize(h+gap+h, w);
|
||||||
|
else
|
||||||
|
return QSize(w+gap+w, h);
|
||||||
|
}
|
||||||
|
else // hybrid
|
||||||
|
{
|
||||||
|
if (isHori)
|
||||||
|
return QSize(h+gap+h, 3*w + (int)ceil((4*gap) / 3.0));
|
||||||
|
else
|
||||||
|
return QSize(3*w + (int)ceil((4*gap) / 3.0), h+gap+h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenHandler::screenOnMousePress(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
event->accept();
|
||||||
|
if (event->button() != Qt::LeftButton) return;
|
||||||
|
|
||||||
|
int x = event->pos().x();
|
||||||
|
int y = event->pos().y();
|
||||||
|
|
||||||
|
if (Frontend::GetTouchCoords(x, y, false))
|
||||||
|
{
|
||||||
|
touching = true;
|
||||||
|
assert(emuThread->NDS != nullptr);
|
||||||
|
emuThread->NDS->TouchScreen(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenHandler::screenOnMouseRelease(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
event->accept();
|
||||||
|
if (event->button() != Qt::LeftButton) return;
|
||||||
|
|
||||||
|
if (touching)
|
||||||
|
{
|
||||||
|
touching = false;
|
||||||
|
assert(emuThread->NDS != nullptr);
|
||||||
|
emuThread->NDS->ReleaseScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenHandler::screenOnMouseMove(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
event->accept();
|
||||||
|
|
||||||
|
showCursor();
|
||||||
|
|
||||||
|
if (!(event->buttons() & Qt::LeftButton)) return;
|
||||||
|
if (!touching) return;
|
||||||
|
|
||||||
|
int x = event->pos().x();
|
||||||
|
int y = event->pos().y();
|
||||||
|
|
||||||
|
if (Frontend::GetTouchCoords(x, y, true))
|
||||||
|
{
|
||||||
|
assert(emuThread->NDS != nullptr);
|
||||||
|
emuThread->NDS->TouchScreen(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenHandler::screenHandleTablet(QTabletEvent* event)
|
||||||
|
{
|
||||||
|
event->accept();
|
||||||
|
|
||||||
|
switch(event->type())
|
||||||
|
{
|
||||||
|
case QEvent::TabletPress:
|
||||||
|
case QEvent::TabletMove:
|
||||||
|
{
|
||||||
|
int x = event->x();
|
||||||
|
int y = event->y();
|
||||||
|
|
||||||
|
if (Frontend::GetTouchCoords(x, y, event->type()==QEvent::TabletMove))
|
||||||
|
{
|
||||||
|
touching = true;
|
||||||
|
assert(emuThread->NDS != nullptr);
|
||||||
|
emuThread->NDS->TouchScreen(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case QEvent::TabletRelease:
|
||||||
|
if (touching)
|
||||||
|
{
|
||||||
|
assert(emuThread->NDS != nullptr);
|
||||||
|
emuThread->NDS->ReleaseScreen();
|
||||||
|
touching = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenHandler::screenHandleTouch(QTouchEvent* event)
|
||||||
|
{
|
||||||
|
event->accept();
|
||||||
|
|
||||||
|
switch(event->type())
|
||||||
|
{
|
||||||
|
case QEvent::TouchBegin:
|
||||||
|
case QEvent::TouchUpdate:
|
||||||
|
if (event->touchPoints().length() > 0)
|
||||||
|
{
|
||||||
|
QPointF lastPosition = event->touchPoints().first().lastPos();
|
||||||
|
int x = (int)lastPosition.x();
|
||||||
|
int y = (int)lastPosition.y();
|
||||||
|
|
||||||
|
if (Frontend::GetTouchCoords(x, y, event->type()==QEvent::TouchUpdate))
|
||||||
|
{
|
||||||
|
touching = true;
|
||||||
|
assert(emuThread->NDS != nullptr);
|
||||||
|
emuThread->NDS->TouchScreen(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case QEvent::TouchEnd:
|
||||||
|
if (touching)
|
||||||
|
{
|
||||||
|
assert(emuThread->NDS != nullptr);
|
||||||
|
emuThread->NDS->ReleaseScreen();
|
||||||
|
touching = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenHandler::showCursor()
|
||||||
|
{
|
||||||
|
mainWindow->panelWidget->setCursor(Qt::ArrowCursor);
|
||||||
|
mouseTimer->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
QTimer* ScreenHandler::setupMouseTimer()
|
||||||
|
{
|
||||||
|
mouseTimer = new QTimer();
|
||||||
|
mouseTimer->setSingleShot(true);
|
||||||
|
mouseTimer->setInterval(Config::MouseHideSeconds*1000);
|
||||||
|
mouseTimer->start();
|
||||||
|
|
||||||
|
return mouseTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenPanelNative::ScreenPanelNative(QWidget* parent) : QWidget(parent), ScreenHandler(this)
|
||||||
|
{
|
||||||
|
screen[0] = QImage(256, 192, QImage::Format_RGB32);
|
||||||
|
screen[1] = QImage(256, 192, QImage::Format_RGB32);
|
||||||
|
|
||||||
|
screenTrans[0].reset();
|
||||||
|
screenTrans[1].reset();
|
||||||
|
|
||||||
|
OSD::Init(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenPanelNative::~ScreenPanelNative()
|
||||||
|
{
|
||||||
|
OSD::DeInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelNative::setupScreenLayout()
|
||||||
|
{
|
||||||
|
int w = width();
|
||||||
|
int h = height();
|
||||||
|
|
||||||
|
screenSetupLayout(w, h);
|
||||||
|
|
||||||
|
for (int i = 0; i < numScreens; i++)
|
||||||
|
{
|
||||||
|
float* mtx = screenMatrix[i];
|
||||||
|
screenTrans[i].setMatrix(mtx[0], mtx[1], 0.f,
|
||||||
|
mtx[2], mtx[3], 0.f,
|
||||||
|
mtx[4], mtx[5], 1.f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelNative::paintEvent(QPaintEvent* event)
|
||||||
|
{
|
||||||
|
QPainter painter(this);
|
||||||
|
|
||||||
|
// fill background
|
||||||
|
painter.fillRect(event->rect(), QColor::fromRgb(0, 0, 0));
|
||||||
|
|
||||||
|
if (emuThread->emuIsActive())
|
||||||
|
{
|
||||||
|
assert(emuThread->NDS != nullptr);
|
||||||
|
emuThread->FrontBufferLock.lock();
|
||||||
|
int frontbuf = emuThread->FrontBuffer;
|
||||||
|
if (!emuThread->NDS->GPU.Framebuffer[frontbuf][0] || !emuThread->NDS->GPU.Framebuffer[frontbuf][1])
|
||||||
|
{
|
||||||
|
emuThread->FrontBufferLock.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(screen[0].scanLine(0), emuThread->NDS->GPU.Framebuffer[frontbuf][0].get(), 256 * 192 * 4);
|
||||||
|
memcpy(screen[1].scanLine(0), emuThread->NDS->GPU.Framebuffer[frontbuf][1].get(), 256 * 192 * 4);
|
||||||
|
emuThread->FrontBufferLock.unlock();
|
||||||
|
|
||||||
|
QRect screenrc(0, 0, 256, 192);
|
||||||
|
|
||||||
|
for (int i = 0; i < numScreens; i++)
|
||||||
|
{
|
||||||
|
painter.setTransform(screenTrans[i]);
|
||||||
|
painter.drawImage(screenrc, screen[screenKind[i]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OSD::Update();
|
||||||
|
OSD::DrawNative(painter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelNative::resizeEvent(QResizeEvent* event)
|
||||||
|
{
|
||||||
|
setupScreenLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelNative::mousePressEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
screenOnMousePress(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelNative::mouseReleaseEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
screenOnMouseRelease(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelNative::mouseMoveEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
screenOnMouseMove(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelNative::tabletEvent(QTabletEvent* event)
|
||||||
|
{
|
||||||
|
screenHandleTablet(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScreenPanelNative::event(QEvent* event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::TouchBegin
|
||||||
|
|| event->type() == QEvent::TouchEnd
|
||||||
|
|| event->type() == QEvent::TouchUpdate)
|
||||||
|
{
|
||||||
|
screenHandleTouch((QTouchEvent*)event);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return QWidget::event(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelNative::onScreenLayoutChanged()
|
||||||
|
{
|
||||||
|
setMinimumSize(screenGetMinSize());
|
||||||
|
setupScreenLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ScreenPanelGL::ScreenPanelGL(QWidget* parent) : QWidget(parent), ScreenHandler(this)
|
||||||
|
{
|
||||||
|
setAutoFillBackground(false);
|
||||||
|
setAttribute(Qt::WA_NativeWindow, true);
|
||||||
|
setAttribute(Qt::WA_NoSystemBackground, true);
|
||||||
|
setAttribute(Qt::WA_PaintOnScreen, true);
|
||||||
|
setAttribute(Qt::WA_KeyCompression, false);
|
||||||
|
setFocusPolicy(Qt::StrongFocus);
|
||||||
|
setMinimumSize(screenGetMinSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenPanelGL::~ScreenPanelGL()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool ScreenPanelGL::createContext()
|
||||||
|
{
|
||||||
|
std::optional<WindowInfo> windowInfo = getWindowInfo();
|
||||||
|
std::array<GL::Context::Version, 2> versionsToTry = {
|
||||||
|
GL::Context::Version{GL::Context::Profile::Core, 4, 3},
|
||||||
|
GL::Context::Version{GL::Context::Profile::Core, 3, 2}};
|
||||||
|
if (windowInfo.has_value())
|
||||||
|
{
|
||||||
|
glContext = GL::Context::Create(*getWindowInfo(), versionsToTry);
|
||||||
|
glContext->DoneCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
|
return glContext != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal ScreenPanelGL::devicePixelRatioFromScreen() const
|
||||||
|
{
|
||||||
|
const QScreen* screen_for_ratio = window()->windowHandle()->screen();
|
||||||
|
if (!screen_for_ratio)
|
||||||
|
screen_for_ratio = QGuiApplication::primaryScreen();
|
||||||
|
|
||||||
|
return screen_for_ratio ? screen_for_ratio->devicePixelRatio() : static_cast<qreal>(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScreenPanelGL::scaledWindowWidth() const
|
||||||
|
{
|
||||||
|
return std::max(static_cast<int>(std::ceil(static_cast<qreal>(width()) * devicePixelRatioFromScreen())), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScreenPanelGL::scaledWindowHeight() const
|
||||||
|
{
|
||||||
|
return std::max(static_cast<int>(std::ceil(static_cast<qreal>(height()) * devicePixelRatioFromScreen())), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<WindowInfo> ScreenPanelGL::getWindowInfo()
|
||||||
|
{
|
||||||
|
WindowInfo wi;
|
||||||
|
|
||||||
|
// Windows and Apple are easy here since there's no display connection.
|
||||||
|
#if defined(_WIN32)
|
||||||
|
wi.type = WindowInfo::Type::Win32;
|
||||||
|
wi.window_handle = reinterpret_cast<void*>(winId());
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
wi.type = WindowInfo::Type::MacOS;
|
||||||
|
wi.window_handle = reinterpret_cast<void*>(winId());
|
||||||
|
#else
|
||||||
|
QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface();
|
||||||
|
const QString platform_name = QGuiApplication::platformName();
|
||||||
|
if (platform_name == QStringLiteral("xcb"))
|
||||||
|
{
|
||||||
|
wi.type = WindowInfo::Type::X11;
|
||||||
|
wi.display_connection = pni->nativeResourceForWindow("display", windowHandle());
|
||||||
|
wi.window_handle = reinterpret_cast<void*>(winId());
|
||||||
|
}
|
||||||
|
else if (platform_name == QStringLiteral("wayland"))
|
||||||
|
{
|
||||||
|
wi.type = WindowInfo::Type::Wayland;
|
||||||
|
QWindow* handle = windowHandle();
|
||||||
|
if (handle == nullptr)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
wi.display_connection = pni->nativeResourceForWindow("display", handle);
|
||||||
|
wi.window_handle = pni->nativeResourceForWindow("surface", handle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qCritical() << "Unknown PNI platform " << platform_name;
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wi.surface_width = static_cast<u32>(scaledWindowWidth());
|
||||||
|
wi.surface_height = static_cast<u32>(scaledWindowHeight());
|
||||||
|
wi.surface_scale = static_cast<float>(devicePixelRatioFromScreen());
|
||||||
|
|
||||||
|
return wi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QPaintEngine* ScreenPanelGL::paintEngine() const
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelGL::setupScreenLayout()
|
||||||
|
{
|
||||||
|
int w = width();
|
||||||
|
int h = height();
|
||||||
|
|
||||||
|
screenSetupLayout(w, h);
|
||||||
|
if (emuThread)
|
||||||
|
transferLayout(emuThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelGL::resizeEvent(QResizeEvent* event)
|
||||||
|
{
|
||||||
|
setupScreenLayout();
|
||||||
|
|
||||||
|
QWidget::resizeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelGL::mousePressEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
screenOnMousePress(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelGL::mouseReleaseEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
screenOnMouseRelease(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelGL::mouseMoveEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
screenOnMouseMove(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelGL::tabletEvent(QTabletEvent* event)
|
||||||
|
{
|
||||||
|
screenHandleTablet(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScreenPanelGL::event(QEvent* event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::TouchBegin
|
||||||
|
|| event->type() == QEvent::TouchEnd
|
||||||
|
|| event->type() == QEvent::TouchUpdate)
|
||||||
|
{
|
||||||
|
screenHandleTouch((QTouchEvent*)event);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return QWidget::event(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelGL::transferLayout(EmuThread* thread)
|
||||||
|
{
|
||||||
|
std::optional<WindowInfo> windowInfo = getWindowInfo();
|
||||||
|
if (windowInfo.has_value())
|
||||||
|
thread->updateScreenSettings(Config::ScreenFilter, *windowInfo, numScreens, screenKind, &screenMatrix[0][0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPanelGL::onScreenLayoutChanged()
|
||||||
|
{
|
||||||
|
setMinimumSize(screenGetMinSize());
|
||||||
|
setupScreenLayout();
|
||||||
|
}
|
155
src/frontend/qt_sdl/Screen.h
Normal file
155
src/frontend/qt_sdl/Screen.h
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
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 SCREEN_H
|
||||||
|
#define SCREEN_H
|
||||||
|
|
||||||
|
#include "glad/glad.h"
|
||||||
|
#include "FrontendUtil.h"
|
||||||
|
#include "duckstation/gl/context.h"
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QWindow>
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QActionGroup>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QScreen>
|
||||||
|
#include <QCloseEvent>
|
||||||
|
|
||||||
|
|
||||||
|
class EmuThread;
|
||||||
|
|
||||||
|
|
||||||
|
const struct { int id; float ratio; const char* label; } aspectRatios[] =
|
||||||
|
{
|
||||||
|
{ 0, 1, "4:3 (native)" },
|
||||||
|
{ 4, (5.f / 3) / (4.f / 3), "5:3 (3DS)"},
|
||||||
|
{ 1, (16.f / 9) / (4.f / 3), "16:9" },
|
||||||
|
{ 2, (21.f / 9) / (4.f / 3), "21:9" },
|
||||||
|
{ 3, 0, "window" }
|
||||||
|
};
|
||||||
|
constexpr int AspectRatiosNum = sizeof(aspectRatios) / sizeof(aspectRatios[0]);
|
||||||
|
|
||||||
|
|
||||||
|
class ScreenHandler
|
||||||
|
{
|
||||||
|
Q_GADGET
|
||||||
|
|
||||||
|
public:
|
||||||
|
ScreenHandler(QWidget* widget);
|
||||||
|
virtual ~ScreenHandler();
|
||||||
|
QTimer* setupMouseTimer();
|
||||||
|
void updateMouseTimer();
|
||||||
|
QTimer* mouseTimer;
|
||||||
|
QSize screenGetMinSize(int factor);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void screenSetupLayout(int w, int h);
|
||||||
|
|
||||||
|
void screenOnMousePress(QMouseEvent* event);
|
||||||
|
void screenOnMouseRelease(QMouseEvent* event);
|
||||||
|
void screenOnMouseMove(QMouseEvent* event);
|
||||||
|
|
||||||
|
void screenHandleTablet(QTabletEvent* event);
|
||||||
|
void screenHandleTouch(QTouchEvent* event);
|
||||||
|
|
||||||
|
float screenMatrix[Frontend::MaxScreenTransforms][6];
|
||||||
|
int screenKind[Frontend::MaxScreenTransforms];
|
||||||
|
int numScreens;
|
||||||
|
|
||||||
|
bool touching = false;
|
||||||
|
|
||||||
|
void showCursor();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ScreenPanelNative : public QWidget, public ScreenHandler
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ScreenPanelNative(QWidget* parent);
|
||||||
|
virtual ~ScreenPanelNative();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent* event) override;
|
||||||
|
|
||||||
|
void resizeEvent(QResizeEvent* event) override;
|
||||||
|
|
||||||
|
void mousePressEvent(QMouseEvent* event) override;
|
||||||
|
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||||
|
void mouseMoveEvent(QMouseEvent* event) override;
|
||||||
|
|
||||||
|
void tabletEvent(QTabletEvent* event) override;
|
||||||
|
bool event(QEvent* event) override;
|
||||||
|
private slots:
|
||||||
|
void onScreenLayoutChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupScreenLayout();
|
||||||
|
|
||||||
|
QImage screen[2];
|
||||||
|
QTransform screenTrans[Frontend::MaxScreenTransforms];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ScreenPanelGL : public QWidget, public ScreenHandler
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ScreenPanelGL(QWidget* parent);
|
||||||
|
virtual ~ScreenPanelGL();
|
||||||
|
|
||||||
|
std::optional<WindowInfo> getWindowInfo();
|
||||||
|
|
||||||
|
bool createContext();
|
||||||
|
|
||||||
|
GL::Context* getContext() { return glContext.get(); }
|
||||||
|
|
||||||
|
void transferLayout(EmuThread* thread);
|
||||||
|
protected:
|
||||||
|
|
||||||
|
qreal devicePixelRatioFromScreen() const;
|
||||||
|
int scaledWindowWidth() const;
|
||||||
|
int scaledWindowHeight() const;
|
||||||
|
|
||||||
|
QPaintEngine* paintEngine() const override;
|
||||||
|
|
||||||
|
void resizeEvent(QResizeEvent* event) override;
|
||||||
|
|
||||||
|
void mousePressEvent(QMouseEvent* event) override;
|
||||||
|
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||||
|
void mouseMoveEvent(QMouseEvent* event) override;
|
||||||
|
|
||||||
|
void tabletEvent(QTabletEvent* event) override;
|
||||||
|
bool event(QEvent* event) override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onScreenLayoutChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupScreenLayout();
|
||||||
|
|
||||||
|
std::unique_ptr<GL::Context> glContext;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SCREEN_H
|
||||||
|
|
2047
src/frontend/qt_sdl/Window.cpp
Normal file
2047
src/frontend/qt_sdl/Window.cpp
Normal file
File diff suppressed because it is too large
Load Diff
239
src/frontend/qt_sdl/Window.h
Normal file
239
src/frontend/qt_sdl/Window.h
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
/*
|
||||||
|
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 WINDOW_H
|
||||||
|
#define WINDOW_H
|
||||||
|
|
||||||
|
#include "glad/glad.h"
|
||||||
|
#include "FrontendUtil.h"
|
||||||
|
#include "duckstation/gl/context.h"
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QWindow>
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QActionGroup>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QScreen>
|
||||||
|
#include <QCloseEvent>
|
||||||
|
|
||||||
|
#include "Screen.h"
|
||||||
|
|
||||||
|
|
||||||
|
class EmuThread;
|
||||||
|
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MainWindow(QWidget* parent = nullptr);
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
|
bool hasOGL;
|
||||||
|
GL::Context* getOGLContext();
|
||||||
|
|
||||||
|
bool preloadROMs(QStringList file, QStringList gbafile, bool boot);
|
||||||
|
QStringList splitArchivePath(const QString& filename, bool useMemberSyntax);
|
||||||
|
|
||||||
|
void onAppStateChanged(Qt::ApplicationState state);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent* event) override;
|
||||||
|
void changeEvent(QEvent* event) override;
|
||||||
|
|
||||||
|
void keyPressEvent(QKeyEvent* event) override;
|
||||||
|
void keyReleaseEvent(QKeyEvent* event) override;
|
||||||
|
|
||||||
|
void dragEnterEvent(QDragEnterEvent* event) override;
|
||||||
|
void dropEvent(QDropEvent* event) override;
|
||||||
|
|
||||||
|
void focusInEvent(QFocusEvent* event) override;
|
||||||
|
void focusOutEvent(QFocusEvent* event) override;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void screenLayoutChange();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onOpenFile();
|
||||||
|
void onClickRecentFile();
|
||||||
|
void onClearRecentFiles();
|
||||||
|
void onBootFirmware();
|
||||||
|
void onInsertCart();
|
||||||
|
void onEjectCart();
|
||||||
|
void onInsertGBACart();
|
||||||
|
void onInsertGBAAddon();
|
||||||
|
void onEjectGBACart();
|
||||||
|
void onSaveState();
|
||||||
|
void onLoadState();
|
||||||
|
void onUndoStateLoad();
|
||||||
|
void onImportSavefile();
|
||||||
|
void onQuit();
|
||||||
|
|
||||||
|
void onPause(bool checked);
|
||||||
|
void onReset();
|
||||||
|
void onStop();
|
||||||
|
void onFrameStep();
|
||||||
|
void onOpenPowerManagement();
|
||||||
|
void onOpenDateTime();
|
||||||
|
void onEnableCheats(bool checked);
|
||||||
|
void onSetupCheats();
|
||||||
|
void onCheatsDialogFinished(int res);
|
||||||
|
void onROMInfo();
|
||||||
|
void onRAMInfo();
|
||||||
|
void onOpenTitleManager();
|
||||||
|
void onMPNewInstance();
|
||||||
|
|
||||||
|
void onOpenEmuSettings();
|
||||||
|
void onEmuSettingsDialogFinished(int res);
|
||||||
|
void onOpenInputConfig();
|
||||||
|
void onInputConfigFinished(int res);
|
||||||
|
void onOpenVideoSettings();
|
||||||
|
void onOpenCameraSettings();
|
||||||
|
void onCameraSettingsFinished(int res);
|
||||||
|
void onOpenAudioSettings();
|
||||||
|
void onUpdateAudioSettings();
|
||||||
|
void onAudioSettingsFinished(int res);
|
||||||
|
void onOpenMPSettings();
|
||||||
|
void onMPSettingsFinished(int res);
|
||||||
|
void onOpenWifiSettings();
|
||||||
|
void onWifiSettingsFinished(int res);
|
||||||
|
void onOpenFirmwareSettings();
|
||||||
|
void onFirmwareSettingsFinished(int res);
|
||||||
|
void onOpenPathSettings();
|
||||||
|
void onPathSettingsFinished(int res);
|
||||||
|
void onOpenInterfaceSettings();
|
||||||
|
void onInterfaceSettingsFinished(int res);
|
||||||
|
void onUpdateMouseTimer();
|
||||||
|
void onChangeSavestateSRAMReloc(bool checked);
|
||||||
|
void onChangeScreenSize();
|
||||||
|
void onChangeScreenRotation(QAction* act);
|
||||||
|
void onChangeScreenGap(QAction* act);
|
||||||
|
void onChangeScreenLayout(QAction* act);
|
||||||
|
void onChangeScreenSwap(bool checked);
|
||||||
|
void onChangeScreenSizing(QAction* act);
|
||||||
|
void onChangeScreenAspect(QAction* act);
|
||||||
|
void onChangeIntegerScaling(bool checked);
|
||||||
|
void onChangeScreenFiltering(bool checked);
|
||||||
|
void onChangeShowOSD(bool checked);
|
||||||
|
void onChangeLimitFramerate(bool checked);
|
||||||
|
void onChangeAudioSync(bool checked);
|
||||||
|
|
||||||
|
void onTitleUpdate(QString title);
|
||||||
|
|
||||||
|
void onEmuStart();
|
||||||
|
void onEmuStop();
|
||||||
|
|
||||||
|
void onUpdateVideoSettings(bool glchange);
|
||||||
|
|
||||||
|
void onFullscreenToggled();
|
||||||
|
void onScreenEmphasisToggled();
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void closeEvent(QCloseEvent* event) override;
|
||||||
|
|
||||||
|
QStringList currentROM;
|
||||||
|
QStringList currentGBAROM;
|
||||||
|
QList<QString> recentFileList;
|
||||||
|
QMenu *recentMenu;
|
||||||
|
void updateRecentFilesMenu();
|
||||||
|
|
||||||
|
bool verifySetup();
|
||||||
|
QString pickFileFromArchive(QString archiveFileName);
|
||||||
|
QStringList pickROM(bool gba);
|
||||||
|
void updateCartInserted(bool gba);
|
||||||
|
|
||||||
|
void createScreenPanel();
|
||||||
|
|
||||||
|
bool pausedManually = false;
|
||||||
|
|
||||||
|
int oldW, oldH;
|
||||||
|
bool oldMax;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ScreenHandler* panel;
|
||||||
|
QWidget* panelWidget;
|
||||||
|
|
||||||
|
QAction* actOpenROM;
|
||||||
|
QAction* actBootFirmware;
|
||||||
|
QAction* actCurrentCart;
|
||||||
|
QAction* actInsertCart;
|
||||||
|
QAction* actEjectCart;
|
||||||
|
QAction* actCurrentGBACart;
|
||||||
|
QAction* actInsertGBACart;
|
||||||
|
QAction* actInsertGBAAddon[1];
|
||||||
|
QAction* actEjectGBACart;
|
||||||
|
QAction* actImportSavefile;
|
||||||
|
QAction* actSaveState[9];
|
||||||
|
QAction* actLoadState[9];
|
||||||
|
QAction* actUndoStateLoad;
|
||||||
|
QAction* actQuit;
|
||||||
|
|
||||||
|
QAction* actPause;
|
||||||
|
QAction* actReset;
|
||||||
|
QAction* actStop;
|
||||||
|
QAction* actFrameStep;
|
||||||
|
QAction* actPowerManagement;
|
||||||
|
QAction* actDateTime;
|
||||||
|
QAction* actEnableCheats;
|
||||||
|
QAction* actSetupCheats;
|
||||||
|
QAction* actROMInfo;
|
||||||
|
QAction* actRAMInfo;
|
||||||
|
QAction* actTitleManager;
|
||||||
|
QAction* actMPNewInstance;
|
||||||
|
|
||||||
|
QAction* actEmuSettings;
|
||||||
|
#ifdef __APPLE__
|
||||||
|
QAction* actPreferences;
|
||||||
|
#endif
|
||||||
|
QAction* actInputConfig;
|
||||||
|
QAction* actVideoSettings;
|
||||||
|
QAction* actCameraSettings;
|
||||||
|
QAction* actAudioSettings;
|
||||||
|
QAction* actMPSettings;
|
||||||
|
QAction* actWifiSettings;
|
||||||
|
QAction* actFirmwareSettings;
|
||||||
|
QAction* actPathSettings;
|
||||||
|
QAction* actInterfaceSettings;
|
||||||
|
QAction* actSavestateSRAMReloc;
|
||||||
|
QAction* actScreenSize[4];
|
||||||
|
QActionGroup* grpScreenRotation;
|
||||||
|
QAction* actScreenRotation[Frontend::screenRot_MAX];
|
||||||
|
QActionGroup* grpScreenGap;
|
||||||
|
QAction* actScreenGap[6];
|
||||||
|
QActionGroup* grpScreenLayout;
|
||||||
|
QAction* actScreenLayout[Frontend::screenLayout_MAX];
|
||||||
|
QAction* actScreenSwap;
|
||||||
|
QActionGroup* grpScreenSizing;
|
||||||
|
QAction* actScreenSizing[Frontend::screenSizing_MAX];
|
||||||
|
QAction* actIntegerScaling;
|
||||||
|
QActionGroup* grpScreenAspectTop;
|
||||||
|
QAction** actScreenAspectTop;
|
||||||
|
QActionGroup* grpScreenAspectBot;
|
||||||
|
QAction** actScreenAspectBot;
|
||||||
|
QAction* actScreenFiltering;
|
||||||
|
QAction* actShowOSD;
|
||||||
|
QAction* actLimitFramerate;
|
||||||
|
QAction* actAudioSync;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ToggleFullscreen(MainWindow* mainWindow);
|
||||||
|
|
||||||
|
#endif // WINDOW_H
|
File diff suppressed because it is too large
Load Diff
@ -37,6 +37,7 @@
|
|||||||
#include <variant>
|
#include <variant>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
|
#include "Window.h"
|
||||||
#include "FrontendUtil.h"
|
#include "FrontendUtil.h"
|
||||||
#include "duckstation/gl/context.h"
|
#include "duckstation/gl/context.h"
|
||||||
|
|
||||||
@ -156,110 +157,6 @@ private:
|
|||||||
int lastScreenWidth = -1, lastScreenHeight = -1;
|
int lastScreenWidth = -1, lastScreenHeight = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ScreenHandler
|
|
||||||
{
|
|
||||||
Q_GADGET
|
|
||||||
|
|
||||||
public:
|
|
||||||
ScreenHandler(QWidget* widget);
|
|
||||||
virtual ~ScreenHandler();
|
|
||||||
QTimer* setupMouseTimer();
|
|
||||||
void updateMouseTimer();
|
|
||||||
QTimer* mouseTimer;
|
|
||||||
QSize screenGetMinSize(int factor);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void screenSetupLayout(int w, int h);
|
|
||||||
|
|
||||||
void screenOnMousePress(QMouseEvent* event);
|
|
||||||
void screenOnMouseRelease(QMouseEvent* event);
|
|
||||||
void screenOnMouseMove(QMouseEvent* event);
|
|
||||||
|
|
||||||
void screenHandleTablet(QTabletEvent* event);
|
|
||||||
void screenHandleTouch(QTouchEvent* event);
|
|
||||||
|
|
||||||
float screenMatrix[Frontend::MaxScreenTransforms][6];
|
|
||||||
int screenKind[Frontend::MaxScreenTransforms];
|
|
||||||
int numScreens;
|
|
||||||
|
|
||||||
bool touching = false;
|
|
||||||
|
|
||||||
void showCursor();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ScreenPanelNative : public QWidget, public ScreenHandler
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ScreenPanelNative(QWidget* parent);
|
|
||||||
virtual ~ScreenPanelNative();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void paintEvent(QPaintEvent* event) override;
|
|
||||||
|
|
||||||
void resizeEvent(QResizeEvent* event) override;
|
|
||||||
|
|
||||||
void mousePressEvent(QMouseEvent* event) override;
|
|
||||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
|
||||||
void mouseMoveEvent(QMouseEvent* event) override;
|
|
||||||
|
|
||||||
void tabletEvent(QTabletEvent* event) override;
|
|
||||||
bool event(QEvent* event) override;
|
|
||||||
private slots:
|
|
||||||
void onScreenLayoutChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void setupScreenLayout();
|
|
||||||
|
|
||||||
QImage screen[2];
|
|
||||||
QTransform screenTrans[Frontend::MaxScreenTransforms];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ScreenPanelGL : public QWidget, public ScreenHandler
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ScreenPanelGL(QWidget* parent);
|
|
||||||
virtual ~ScreenPanelGL();
|
|
||||||
|
|
||||||
std::optional<WindowInfo> getWindowInfo();
|
|
||||||
|
|
||||||
bool createContext();
|
|
||||||
|
|
||||||
GL::Context* getContext() { return glContext.get(); }
|
|
||||||
|
|
||||||
void transferLayout(EmuThread* thread);
|
|
||||||
protected:
|
|
||||||
|
|
||||||
qreal devicePixelRatioFromScreen() const;
|
|
||||||
int scaledWindowWidth() const;
|
|
||||||
int scaledWindowHeight() const;
|
|
||||||
|
|
||||||
QPaintEngine* paintEngine() const override;
|
|
||||||
|
|
||||||
void resizeEvent(QResizeEvent* event) override;
|
|
||||||
|
|
||||||
void mousePressEvent(QMouseEvent* event) override;
|
|
||||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
|
||||||
void mouseMoveEvent(QMouseEvent* event) override;
|
|
||||||
|
|
||||||
void tabletEvent(QTabletEvent* event) override;
|
|
||||||
bool event(QEvent* event) override;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onScreenLayoutChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void setupScreenLayout();
|
|
||||||
|
|
||||||
std::unique_ptr<GL::Context> glContext;
|
|
||||||
};
|
|
||||||
|
|
||||||
class MelonApplication : public QApplication
|
class MelonApplication : public QApplication
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -269,199 +166,4 @@ public:
|
|||||||
bool event(QEvent* event) override;
|
bool event(QEvent* event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MainWindow : public QMainWindow
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit MainWindow(QWidget* parent = nullptr);
|
|
||||||
~MainWindow();
|
|
||||||
|
|
||||||
bool hasOGL;
|
|
||||||
GL::Context* getOGLContext();
|
|
||||||
|
|
||||||
bool preloadROMs(QStringList file, QStringList gbafile, bool boot);
|
|
||||||
QStringList splitArchivePath(const QString& filename, bool useMemberSyntax);
|
|
||||||
|
|
||||||
void onAppStateChanged(Qt::ApplicationState state);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void resizeEvent(QResizeEvent* event) override;
|
|
||||||
void changeEvent(QEvent* event) override;
|
|
||||||
|
|
||||||
void keyPressEvent(QKeyEvent* event) override;
|
|
||||||
void keyReleaseEvent(QKeyEvent* event) override;
|
|
||||||
|
|
||||||
void dragEnterEvent(QDragEnterEvent* event) override;
|
|
||||||
void dropEvent(QDropEvent* event) override;
|
|
||||||
|
|
||||||
void focusInEvent(QFocusEvent* event) override;
|
|
||||||
void focusOutEvent(QFocusEvent* event) override;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void screenLayoutChange();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onOpenFile();
|
|
||||||
void onClickRecentFile();
|
|
||||||
void onClearRecentFiles();
|
|
||||||
void onBootFirmware();
|
|
||||||
void onInsertCart();
|
|
||||||
void onEjectCart();
|
|
||||||
void onInsertGBACart();
|
|
||||||
void onInsertGBAAddon();
|
|
||||||
void onEjectGBACart();
|
|
||||||
void onSaveState();
|
|
||||||
void onLoadState();
|
|
||||||
void onUndoStateLoad();
|
|
||||||
void onImportSavefile();
|
|
||||||
void onQuit();
|
|
||||||
|
|
||||||
void onPause(bool checked);
|
|
||||||
void onReset();
|
|
||||||
void onStop();
|
|
||||||
void onFrameStep();
|
|
||||||
void onOpenPowerManagement();
|
|
||||||
void onOpenDateTime();
|
|
||||||
void onEnableCheats(bool checked);
|
|
||||||
void onSetupCheats();
|
|
||||||
void onCheatsDialogFinished(int res);
|
|
||||||
void onROMInfo();
|
|
||||||
void onRAMInfo();
|
|
||||||
void onOpenTitleManager();
|
|
||||||
void onMPNewInstance();
|
|
||||||
|
|
||||||
void onOpenEmuSettings();
|
|
||||||
void onEmuSettingsDialogFinished(int res);
|
|
||||||
void onOpenInputConfig();
|
|
||||||
void onInputConfigFinished(int res);
|
|
||||||
void onOpenVideoSettings();
|
|
||||||
void onOpenCameraSettings();
|
|
||||||
void onCameraSettingsFinished(int res);
|
|
||||||
void onOpenAudioSettings();
|
|
||||||
void onUpdateAudioSettings();
|
|
||||||
void onAudioSettingsFinished(int res);
|
|
||||||
void onOpenMPSettings();
|
|
||||||
void onMPSettingsFinished(int res);
|
|
||||||
void onOpenWifiSettings();
|
|
||||||
void onWifiSettingsFinished(int res);
|
|
||||||
void onOpenFirmwareSettings();
|
|
||||||
void onFirmwareSettingsFinished(int res);
|
|
||||||
void onOpenPathSettings();
|
|
||||||
void onPathSettingsFinished(int res);
|
|
||||||
void onOpenInterfaceSettings();
|
|
||||||
void onInterfaceSettingsFinished(int res);
|
|
||||||
void onUpdateMouseTimer();
|
|
||||||
void onChangeSavestateSRAMReloc(bool checked);
|
|
||||||
void onChangeScreenSize();
|
|
||||||
void onChangeScreenRotation(QAction* act);
|
|
||||||
void onChangeScreenGap(QAction* act);
|
|
||||||
void onChangeScreenLayout(QAction* act);
|
|
||||||
void onChangeScreenSwap(bool checked);
|
|
||||||
void onChangeScreenSizing(QAction* act);
|
|
||||||
void onChangeScreenAspect(QAction* act);
|
|
||||||
void onChangeIntegerScaling(bool checked);
|
|
||||||
void onChangeScreenFiltering(bool checked);
|
|
||||||
void onChangeShowOSD(bool checked);
|
|
||||||
void onChangeLimitFramerate(bool checked);
|
|
||||||
void onChangeAudioSync(bool checked);
|
|
||||||
|
|
||||||
void onTitleUpdate(QString title);
|
|
||||||
|
|
||||||
void onEmuStart();
|
|
||||||
void onEmuStop();
|
|
||||||
|
|
||||||
void onUpdateVideoSettings(bool glchange);
|
|
||||||
|
|
||||||
void onFullscreenToggled();
|
|
||||||
void onScreenEmphasisToggled();
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual void closeEvent(QCloseEvent* event) override;
|
|
||||||
|
|
||||||
QStringList currentROM;
|
|
||||||
QStringList currentGBAROM;
|
|
||||||
QList<QString> recentFileList;
|
|
||||||
QMenu *recentMenu;
|
|
||||||
void updateRecentFilesMenu();
|
|
||||||
|
|
||||||
bool verifySetup();
|
|
||||||
QString pickFileFromArchive(QString archiveFileName);
|
|
||||||
QStringList pickROM(bool gba);
|
|
||||||
void updateCartInserted(bool gba);
|
|
||||||
|
|
||||||
void createScreenPanel();
|
|
||||||
|
|
||||||
bool pausedManually = false;
|
|
||||||
|
|
||||||
int oldW, oldH;
|
|
||||||
bool oldMax;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ScreenHandler* panel;
|
|
||||||
QWidget* panelWidget;
|
|
||||||
|
|
||||||
QAction* actOpenROM;
|
|
||||||
QAction* actBootFirmware;
|
|
||||||
QAction* actCurrentCart;
|
|
||||||
QAction* actInsertCart;
|
|
||||||
QAction* actEjectCart;
|
|
||||||
QAction* actCurrentGBACart;
|
|
||||||
QAction* actInsertGBACart;
|
|
||||||
QAction* actInsertGBAAddon[1];
|
|
||||||
QAction* actEjectGBACart;
|
|
||||||
QAction* actImportSavefile;
|
|
||||||
QAction* actSaveState[9];
|
|
||||||
QAction* actLoadState[9];
|
|
||||||
QAction* actUndoStateLoad;
|
|
||||||
QAction* actQuit;
|
|
||||||
|
|
||||||
QAction* actPause;
|
|
||||||
QAction* actReset;
|
|
||||||
QAction* actStop;
|
|
||||||
QAction* actFrameStep;
|
|
||||||
QAction* actPowerManagement;
|
|
||||||
QAction* actDateTime;
|
|
||||||
QAction* actEnableCheats;
|
|
||||||
QAction* actSetupCheats;
|
|
||||||
QAction* actROMInfo;
|
|
||||||
QAction* actRAMInfo;
|
|
||||||
QAction* actTitleManager;
|
|
||||||
QAction* actMPNewInstance;
|
|
||||||
|
|
||||||
QAction* actEmuSettings;
|
|
||||||
#ifdef __APPLE__
|
|
||||||
QAction* actPreferences;
|
|
||||||
#endif
|
|
||||||
QAction* actInputConfig;
|
|
||||||
QAction* actVideoSettings;
|
|
||||||
QAction* actCameraSettings;
|
|
||||||
QAction* actAudioSettings;
|
|
||||||
QAction* actMPSettings;
|
|
||||||
QAction* actWifiSettings;
|
|
||||||
QAction* actFirmwareSettings;
|
|
||||||
QAction* actPathSettings;
|
|
||||||
QAction* actInterfaceSettings;
|
|
||||||
QAction* actSavestateSRAMReloc;
|
|
||||||
QAction* actScreenSize[4];
|
|
||||||
QActionGroup* grpScreenRotation;
|
|
||||||
QAction* actScreenRotation[Frontend::screenRot_MAX];
|
|
||||||
QActionGroup* grpScreenGap;
|
|
||||||
QAction* actScreenGap[6];
|
|
||||||
QActionGroup* grpScreenLayout;
|
|
||||||
QAction* actScreenLayout[Frontend::screenLayout_MAX];
|
|
||||||
QAction* actScreenSwap;
|
|
||||||
QActionGroup* grpScreenSizing;
|
|
||||||
QAction* actScreenSizing[Frontend::screenSizing_MAX];
|
|
||||||
QAction* actIntegerScaling;
|
|
||||||
QActionGroup* grpScreenAspectTop;
|
|
||||||
QAction** actScreenAspectTop;
|
|
||||||
QActionGroup* grpScreenAspectBot;
|
|
||||||
QAction** actScreenAspectBot;
|
|
||||||
QAction* actScreenFiltering;
|
|
||||||
QAction* actShowOSD;
|
|
||||||
QAction* actLimitFramerate;
|
|
||||||
QAction* actAudioSync;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MAIN_H
|
#endif // MAIN_H
|
||||||
|
Reference in New Issue
Block a user