/* Copyright 2016-2025 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 #include #include #include #include #include #include #include #include #include "glad/glad.h" #include "ScreenLayout.h" #include "duckstation/gl/context.h" class MainWindow; class EmuInstance; 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(); void setFilter(bool filter); void setMouseHide(bool enable, int delay); 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(); 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; struct OSDItem { unsigned int id; qint64 timestamp; char text[256]; unsigned int color; bool rendered; QImage bitmap; int rainbowstart; int rainbowend; }; QMutex osdMutex; bool osdEnabled; unsigned int osdID; std::deque osdItems; QPixmap splashLogo; OSDItem splashText[3]; QPoint splashPos[4]; void loadConfig(); 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; 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(); void calcSplashLayout(); }; 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[kMaxScreenTransforms]; }; class ScreenPanelGL : public ScreenPanel { Q_OBJECT public: explicit ScreenPanelGL(QWidget* parent); virtual ~ScreenPanelGL(); std::optional getWindowInfo(); bool createContext(); void setSwapInterval(int intv); void initOpenGL(); void deinitOpenGL(); void makeCurrentGL(); void releaseGL(); 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 glContext; bool glInited; GLuint screenVertexBuffer, screenVertexArray; GLuint screenTexture; GLuint screenShaderProgram; GLint screenShaderTransformULoc, screenShaderScreenSizeULoc; QMutex screenSettingsLock; WindowInfo windowInfo; int lastScreenWidth = -1, lastScreenHeight = -1; GLuint osdShader; GLint osdScreenSizeULoc, osdPosULoc, osdSizeULoc; GLint osdScaleFactorULoc; GLint osdTexScaleULoc; GLuint osdVertexArray; GLuint osdVertexBuffer; std::map osdTextures; GLuint logoTexture; void osdRenderItem(OSDItem* item) override; void osdDeleteItem(OSDItem* item) override; }; #endif // SCREEN_H