Files
melonDS/src/frontend/qt_sdl/Screen.h
2023-12-28 14:40:37 +01:00

197 lines
4.6 KiB
C++

/*
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 <optional>
#include <deque>
#include <map>
#include <QWidget>
#include <QImage>
#include <QMutex>
#include <QScreen>
#include <QCloseEvent>
#include <QTimer>
#include "glad/glad.h"
#include "FrontendUtil.h"
#include "duckstation/gl/context.h"
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 ScreenPanel : public QWidget
{
Q_OBJECT
public:
explicit ScreenPanel(QWidget* parent);
virtual ~ScreenPanel();
QTimer* setupMouseTimer();
void updateMouseTimer();
QTimer* mouseTimer;
QSize screenGetMinSize(int factor);
void osdSetEnabled(bool enabled);
void osdAddMessage(unsigned int color, const char* msg);
private slots:
void onScreenLayoutChanged();
protected:
struct OSDItem
{
unsigned int id;
qint64 timestamp;
char text[256];
unsigned int color;
bool rendered;
QImage bitmap;
};
QMutex osdMutex;
bool osdEnabled;
unsigned int osdID;
std::deque<OSDItem> osdItems;
virtual void setupScreenLayout();
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;
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);
void osdLayoutText(const char* text, int* width, int* height, int* breaks);
unsigned int osdRainbowColor(int inc);
virtual void osdRenderItem(OSDItem* item);
virtual void osdDeleteItem(OSDItem* item);
void osdUpdate();
};
class ScreenPanelNative : public ScreenPanel
{
Q_OBJECT
public:
explicit ScreenPanelNative(QWidget* parent);
virtual ~ScreenPanelNative();
protected:
void paintEvent(QPaintEvent* event) override;
private:
void setupScreenLayout() override;
QImage screen[2];
QTransform screenTrans[Frontend::MaxScreenTransforms];
};
class ScreenPanelGL : public ScreenPanel
{
Q_OBJECT
public:
explicit ScreenPanelGL(QWidget* parent);
virtual ~ScreenPanelGL();
std::optional<WindowInfo> getWindowInfo();
bool createContext();
void setSwapInterval(int intv);
void initOpenGL();
void deinitOpenGL();
void drawScreenGL();
GL::Context* getContext() { return glContext.get(); }
void transferLayout();
protected:
qreal devicePixelRatioFromScreen() const;
int scaledWindowWidth() const;
int scaledWindowHeight() const;
QPaintEngine* paintEngine() const override;
private:
void setupScreenLayout() override;
std::unique_ptr<GL::Context> glContext;
GLuint screenVertexBuffer, screenVertexArray;
GLuint screenTexture;
GLuint screenShaderProgram[3];
GLuint screenShaderTransformULoc, screenShaderScreenSizeULoc;
QMutex screenSettingsLock;
WindowInfo windowInfo;
bool filter;
int lastScreenWidth = -1, lastScreenHeight = -1;
GLuint osdShader[3];
GLint osdScreenSizeULoc, osdPosULoc, osdSizeULoc;
GLfloat osdScaleFactorULoc;
GLuint osdVertexArray;
GLuint osdVertexBuffer;
std::map<unsigned int, GLuint> osdTextures;
void osdRenderItem(OSDItem* item) override;
void osdDeleteItem(OSDItem* item) override;
};
#endif // SCREEN_H