diff options
| author | Arisotura <thetotalworm@gmail.com> | 2020-05-21 18:43:07 +0200 | 
|---|---|---|
| committer | Arisotura <thetotalworm@gmail.com> | 2020-05-21 18:43:07 +0200 | 
| commit | 8f9369beebf60f3b10d75f50507b194f2ccdaceb (patch) | |
| tree | d5336e4598413652175ed485a7c8f5d1b51807f1 /src/frontend | |
| parent | f79583bf1697b4c6a5b40c1e727e2a40c789757d (diff) | |
add screen layout system
Diffstat (limited to 'src/frontend')
| -rw-r--r-- | src/frontend/FrontendUtil.h | 26 | ||||
| -rw-r--r-- | src/frontend/Util_Video.cpp | 334 | ||||
| -rw-r--r-- | src/frontend/qt_sdl/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/frontend/qt_sdl/main.cpp | 213 | ||||
| -rw-r--r-- | src/frontend/qt_sdl/main.h | 17 | 
5 files changed, 545 insertions, 46 deletions
diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index 6a6f8ea..1fd7329 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -89,6 +89,32 @@ bool SaveState(const char* filename);  void UndoStateLoad(); +// 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 +//     0 = natural (top screen above bottom screen always) +//     1 = vertical +//     2 = horizontal +// * rotation: angle at which the DS screens are presented: 0/1/2/3 = 0/90/180/270 +// * sizing: how the display size is shared between the two screens +//     0 = even (both screens get same size) +//     1 = emphasize top screen (make top screen as big as possible, fit bottom screen in remaining space) +//     2 = emphasize bottom screen +// * screenGap: size of the gap between the two screens +// * integerScale: force screens to be scaled up at integer scaling factors +void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int rotation, int sizing, int screenGap, bool integerScale); + +// get a 2x3 transform matrix for the given screen (0=top, 1=bottom) +// note: the transform assumes an origin point at the top left of the display, +// X going left and Y going down +// for each screen the source coordinates should be (0,0) and (256,192) +float* GetScreenTransform(int screen); + +// de-transform the provided host display coordinates to get coordinates +// on the bottom screen +void GetTouchCoords(int& x, int& y); + +  // initialize the audio utility  void Init_Audio(int outputfreq); diff --git a/src/frontend/Util_Video.cpp b/src/frontend/Util_Video.cpp new file mode 100644 index 0000000..cd4e21c --- /dev/null +++ b/src/frontend/Util_Video.cpp @@ -0,0 +1,334 @@ +/* +    Copyright 2016-2020 Arisotura + +    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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <cmath> +#include <algorithm> + +#include "FrontendUtil.h" + + +namespace Frontend +{ + +float TopScreenMtx[6]; +float BotScreenMtx[6]; +float TouchMtx[6]; + + +void M23_Identity(float* m) +{ +    m[0] = 1; m[1] = 0; +    m[2] = 0; m[3] = 1; +    m[4] = 0; m[5] = 0; +} + +void M23_Scale(float* m, float s) +{ +    m[0] *= s; m[1] *= s; +    m[2] *= s; m[3] *= s; +    m[4] *= s; m[5] *= s; +} + +void M23_RotateFast(float* m, int angle) +{ +    if (angle == 0) return; + +    float temp[4]; memcpy(temp, m, sizeof(float)*4); + +    switch (angle) +    { +    case 1: // 90 +        m[0] = temp[2]; +        m[1] = temp[3]; +        m[2] = -temp[0]; +        m[3] = -temp[1]; +        break; + +    case 2: // 180 +        m[0] = -temp[0]; +        m[1] = -temp[1]; +        m[2] = -temp[2]; +        m[3] = -temp[3]; +        break; + +    case 3: // 270 +        m[0] = -temp[2]; +        m[1] = -temp[3]; +        m[2] = temp[0]; +        m[3] = temp[1]; +        break; +    } +} + +void M23_Translate(float* m, float tx, float ty) +{ +    m[4] += tx; +    m[5] += ty; +} + +void M23_Multiply(float* m, float* _a, float* _b) +{ +    float a[6]; memcpy(a, _a, 6*sizeof(float)); +    float b[6]; memcpy(b, _b, 6*sizeof(float)); + +    m[0] = (a[0] * b[0]) + (a[2] * b[1]); +    m[1] = (a[1] * b[0]) + (a[3] * b[1]); + +    m[2] = (a[0] * b[2]) + (a[2] * b[3]); +    m[3] = (a[1] * b[2]) + (a[3] * b[3]); + +    m[4] = (a[0] * b[4]) + (a[2] * b[5]) + a[4]; +    m[5] = (a[1] * b[4]) + (a[3] * b[5]) + a[5]; +} + +void M23_Transform(float* m, float& x, float& y) +{ +    float vx = x; +    float vy = y; + +    x = (vx * m[0]) + (vy * m[2]) + m[4]; +    y = (vx * m[1]) + (vy * m[3]) + m[5]; +} + + +void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int rotation, int sizing, int screenGap, bool integerScale) +{ +    float refpoints[4][2] = +    { +        {0, 0}, {256, 192}, +        {0, 0}, {256, 192} +    }; + +    int layout = screenLayout == 0 +        ? ((rotation % 2 == 0) ? 0 : 1) +        : screenLayout - 1; + +    float botScale = 1; +    float botTrans[4] = {0}; + +    M23_Identity(TopScreenMtx); +    M23_Identity(BotScreenMtx); + +    M23_Translate(TopScreenMtx, -256/2, -192/2); +    M23_Translate(BotScreenMtx, -256/2, -192/2); + +    // rotation +    { +        float rotmtx[6]; +        M23_Identity(rotmtx); + +        M23_RotateFast(rotmtx, rotation); +        M23_Multiply(TopScreenMtx, rotmtx, TopScreenMtx); +        M23_Multiply(BotScreenMtx, rotmtx, BotScreenMtx); + +        M23_Transform(TopScreenMtx, refpoints[0][0], refpoints[0][1]); +        M23_Transform(TopScreenMtx, refpoints[1][0], refpoints[1][1]); +        M23_Transform(BotScreenMtx, refpoints[2][0], refpoints[2][1]); +        M23_Transform(BotScreenMtx, refpoints[3][0], refpoints[3][1]); +    } + +    // move screens apart +    { +        int idx = layout == 0 ? 1 : 0; +        float offset = +            (((layout == 0 && (rotation % 2 == 0)) || (layout == 1 && (rotation % 2 == 1)) +                ? 192.f : 256.f) +            + screenGap) / 2.f; +        if (rotation == 1 || rotation == 2) +            offset *= -1.f; + +        M23_Translate(TopScreenMtx, (idx==0)?-offset:0, (idx==1)?-offset:0); +        M23_Translate(BotScreenMtx, (idx==0)?offset:0, (idx==1)?offset:0); + +        refpoints[0][idx] -= offset; +        refpoints[1][idx] -= offset; +        refpoints[2][idx] += offset; +        refpoints[3][idx] += offset; + +        botTrans[idx] = offset; +    } + +    // scale +    { +        if (sizing == 0) +        { +            float minX = refpoints[0][0], maxX = minX; +            float minY = refpoints[0][1], maxY = minY; + +            for (int i = 1; i < 4; i++) +            { +                minX = std::min(minX, refpoints[i][0]); +                minY = std::min(minY, refpoints[i][1]); +                maxX = std::max(maxX, refpoints[i][0]); +                maxY = std::max(maxY, refpoints[i][1]); +            } + +            float hSize = maxX - minX; +            float vSize = maxY - minY; + +            // scale evenly +            float scale = std::min(screenWidth / hSize, screenHeight / vSize); + +            if (integerScale) +                scale = floor(scale); + +            M23_Scale(TopScreenMtx, scale); +            M23_Scale(BotScreenMtx, scale); + +            for (int i = 0; i < 4; i++) +            { +                refpoints[i][0] *= scale; +                refpoints[i][1] *= scale; +            } + +            botScale = scale; +        } +        else +        { +            int primOffset = (sizing == 1) ? 0 : 2; +            int secOffset = (sizing == 1) ? 2 : 0; +            float* primMtx = (sizing == 1) ? TopScreenMtx : BotScreenMtx; +            float* secMtx = (sizing == 1) ? BotScreenMtx : TopScreenMtx; + +            float primMinX = refpoints[primOffset][0], primMaxX = primMinX; +            float primMinY = refpoints[primOffset][1], primMaxY = primMinY; +            float secMinX = refpoints[secOffset][0], secMaxX = secMinX; +            float secMinY = refpoints[secOffset][1], secMaxY = secMinY; + +            primMinX = std::min(primMinX, refpoints[primOffset+1][0]); +            primMinY = std::min(primMinY, refpoints[primOffset+1][1]); +            primMaxX = std::max(primMaxX, refpoints[primOffset+1][0]); +            primMaxY = std::max(primMaxY, refpoints[primOffset+1][1]); + +            secMinX = std::min(secMinX, refpoints[secOffset+1][0]); +            secMinY = std::min(secMinY, refpoints[secOffset+1][1]); +            secMaxX = std::max(secMaxX, refpoints[secOffset+1][0]); +            secMaxY = std::max(secMaxY, refpoints[secOffset+1][1]); + +            float primHSize = layout == 1 ? std::max(primMaxX, -primMinX) : primMaxX - primMinX; +            float primVSize = layout == 0 ? std::max(primMaxY, -primMinY) : primMaxY - primMinY; + +            float secHSize = layout == 1 ? std::max(secMaxX, -secMinX) : secMaxX - secMinX; +            float secVSize = layout == 0 ? std::max(secMaxY, -secMinY) : secMaxY - secMinY; + +            float primScale = std::min(screenWidth / primHSize, screenHeight / primVSize); +            float secScale = 1.f; + +            if (layout == 0) +            { +                if (screenHeight - primVSize * primScale < secVSize) +                    primScale = std::min((screenWidth - secHSize) / primHSize, (screenHeight - secVSize) / primVSize); +                else +                    secScale = std::min((screenHeight - primVSize * primScale) / secVSize, screenWidth / secHSize); +            } +            else +            { +                if (screenWidth - primHSize * primScale < secHSize) +                    primScale = std::min((screenWidth - secHSize) / primHSize, (screenHeight - secVSize) / primVSize); +                else +                    secScale = std::min((screenWidth - primHSize * primScale) / secHSize, screenHeight / secVSize); +            } + +            if (integerScale) +            { +                primScale = floor(primScale); +                secScale = floor(secScale); +            } + +            M23_Scale(primMtx, primScale); +            M23_Scale(secMtx, secScale); + +            refpoints[primOffset+0][0] *= primScale; +            refpoints[primOffset+0][1] *= primScale; +            refpoints[primOffset+1][0] *= primScale; +            refpoints[primOffset+1][1] *= primScale; +            refpoints[secOffset+0][0] *= secScale; +            refpoints[secOffset+0][1] *= secScale; +            refpoints[secOffset+1][0] *= secScale; +            refpoints[secOffset+1][1] *= secScale; + +            botScale = (sizing == 1) ? secScale : primScale; +        } +    } + +    // position +    { +        float minX = refpoints[0][0], maxX = minX; +        float minY = refpoints[0][1], maxY = minY; + +        for (int i = 1; i < 4; i++) +        { +            minX = std::min(minX, refpoints[i][0]); +            minY = std::min(minY, refpoints[i][1]); +            maxX = std::max(maxX, refpoints[i][0]); +            maxY = std::max(maxY, refpoints[i][1]); +        } + +        float width = maxX - minX; +        float height = maxY - minY; + +        float tx = (screenWidth/2) - (width/2) - minX; +        float ty = (screenHeight/2) - (height/2) - minY; + +        M23_Translate(TopScreenMtx, tx, ty); +        M23_Translate(BotScreenMtx, tx, ty); + +        botTrans[2] = tx; botTrans[3] = ty; +    } + +    // prepare a 'reverse' matrix for the touchscreen +    // this matrix undoes the transforms applied to the bottom screen +    // and can be used to calculate touchscreen coords from host screen coords +    { +        M23_Identity(TouchMtx); + +        M23_Translate(TouchMtx, -botTrans[2], -botTrans[3]); +        M23_Scale(TouchMtx, 1.f / botScale); +        M23_Translate(TouchMtx, -botTrans[0], -botTrans[1]); + +        float rotmtx[6]; +        M23_Identity(rotmtx); +        M23_RotateFast(rotmtx, (4-rotation) & 3); +        M23_Multiply(TouchMtx, rotmtx, TouchMtx); + +        M23_Translate(TouchMtx, 256/2, 192/2); +    } +} + +float* GetScreenTransform(int screen) +{ +    if (screen == 0) return TopScreenMtx; +    else             return BotScreenMtx; +} + +void GetTouchCoords(int& x, int& y) +{ +    float vx = x; +    float vy = y; + +    M23_Transform(TouchMtx, vx, vy); + +    x = (int)vx; +    y = (int)vy; +} + +} + diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index ffd7d17..7bc81f0 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -10,6 +10,7 @@ SET(SOURCES_QT_SDL  	PlatformConfig.cpp  	../Util_ROM.cpp +	../Util_Video.cpp  	../Util_Audio.cpp  	../FrontendUtil.h  	../mic_blow.h diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 245324f..0d10378 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -62,6 +62,8 @@ bool RunningSomething;  MainWindow* mainWindow;  EmuThread* emuThread; +int autoScreenSizing = 0; +  SDL_AudioDeviceID audioDevice;  int audioFreq;  SDL_cond* audioSync; @@ -250,16 +252,19 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent)      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(screenLayoutChange()), mainWindow->panel, SLOT(onScreenLayoutChanged()));  }  void EmuThread::run()  { +    u32 mainScreenPos[3]; +      NDS::Init(); -    /*MainScreenPos[0] = 0; -    MainScreenPos[1] = 0; -    MainScreenPos[2] = 0; -    AutoScreenSizing = 0;*/ +    mainScreenPos[0] = 0; +    mainScreenPos[1] = 0; +    mainScreenPos[2] = 0; +    autoScreenSizing = 0;      /*if (Screen_UseGL)      { @@ -333,14 +338,14 @@ void EmuThread::run()              }*/              // auto screen layout -            /*{ -                MainScreenPos[2] = MainScreenPos[1]; -                MainScreenPos[1] = MainScreenPos[0]; -                MainScreenPos[0] = NDS::PowerControl9 >> 15; +            { +                mainScreenPos[2] = mainScreenPos[1]; +                mainScreenPos[1] = mainScreenPos[0]; +                mainScreenPos[0] = NDS::PowerControl9 >> 15;                  int guess; -                if (MainScreenPos[0] == MainScreenPos[2] && -                    MainScreenPos[0] != MainScreenPos[1]) +                if (mainScreenPos[0] == mainScreenPos[2] && +                    mainScreenPos[0] != mainScreenPos[1])                  {                      // constant flickering, likely displaying 3D on both screens                      // TODO: when both screens are used for 2D only...??? @@ -348,18 +353,18 @@ void EmuThread::run()                  }                  else                  { -                    if (MainScreenPos[0] == 1) +                    if (mainScreenPos[0] == 1)                          guess = 1;                      else                          guess = 2;                  } -                if (guess != AutoScreenSizing) +                if (guess != autoScreenSizing)                  { -                    AutoScreenSizing = guess; -                    SetupScreenRects(WindowWidth, WindowHeight); +                    autoScreenSizing = guess; +                    emit screenLayoutChange();                  } -            }*/ +            }              // emulate              u32 nlines = NDS::RunFrame(); @@ -540,6 +545,9 @@ MainWindowPanel::MainWindowPanel(QWidget* parent) : QWidget(parent)      screen[0] = new QImage(256, 192, QImage::Format_RGB32);      screen[1] = new QImage(256, 192, QImage::Format_RGB32); +    screenTrans[0].reset(); +    screenTrans[1].reset(); +      touching = false;  } @@ -549,6 +557,64 @@ MainWindowPanel::~MainWindowPanel()      delete screen[1];  } +void MainWindowPanel::ensureProperMinSize() +{ +    bool isHori = (Config::ScreenRotation == 1 || Config::ScreenRotation == 3); +    int gap = Config::ScreenGap; + +    int w = 256; +    int h = 192; + +    if (Config::ScreenLayout == 0) // natural +    { +        if (isHori) +            setMinimumSize(h+gap+h, w); +        else +            setMinimumSize(w, h+gap+h); +    } +    else if (Config::ScreenLayout == 1) // vertical +    { +        if (isHori) +            setMinimumSize(h, w+gap+w); +        else +            setMinimumSize(w, h+gap+h); +    } +    else // horizontal +    { +        if (isHori) +            setMinimumSize(h+gap+h, w); +        else +            setMinimumSize(w+gap+w, h); +    } +} + +void MainWindowPanel::setupScreenLayout() +{ +    int w = width(); +    int h = height(); +    float* mtx; + +    int sizing = Config::ScreenSizing; +    if (sizing == 3) sizing = autoScreenSizing; + +    Frontend::SetupScreenLayout(w, h, +                                Config::ScreenLayout, +                                Config::ScreenRotation, +                                sizing, +                                Config::ScreenGap, +                                Config::IntegerScaling != 0); + +    mtx = Frontend::GetScreenTransform(0); +    screenTrans[0].setMatrix(mtx[0], mtx[1], 0.f, +                             mtx[2], mtx[3], 0.f, +                             mtx[4], mtx[5], 1.f); + +    mtx = Frontend::GetScreenTransform(1); +    screenTrans[1].setMatrix(mtx[0], mtx[1], 0.f, +                             mtx[2], mtx[3], 0.f, +                             mtx[4], mtx[5], 1.f); +} +  void MainWindowPanel::paintEvent(QPaintEvent* event)  {      QPainter painter(this); @@ -562,27 +628,18 @@ void MainWindowPanel::paintEvent(QPaintEvent* event)      memcpy(screen[0]->scanLine(0), GPU::Framebuffer[frontbuf][0], 256*192*4);      memcpy(screen[1]->scanLine(0), GPU::Framebuffer[frontbuf][1], 256*192*4); -    QRect src = QRect(0, 0, 256, 192); +    QRect screenrc = QRect(0, 0, 256, 192); -    QRect dstTop = QRect(0, 0, 256, 192); // TODO -    QRect dstBot = QRect(0, 192, 256, 192); // TODO +    painter.setTransform(screenTrans[0]); +    painter.drawImage(screenrc, *screen[0]); -    painter.drawImage(dstTop, *screen[0]); -    painter.drawImage(dstBot, *screen[1]); +    painter.setTransform(screenTrans[1]); +    painter.drawImage(screenrc, *screen[1]);  } - -void MainWindowPanel::transformTSCoords(int& x, int& y) +void MainWindowPanel::resizeEvent(QResizeEvent* event)  { -    // TODO: actual screen de-transform taking screen layout/rotation/etc into account - -    y -= 192; - -    // clamp to screen range -    if (x < 0) x = 0; -    else if (x > 255) x = 255; -    if (y < 0) y = 0; -    else if (y > 191) y = 191; +    setupScreenLayout();  }  void MainWindowPanel::mousePressEvent(QMouseEvent* event) @@ -593,11 +650,11 @@ void MainWindowPanel::mousePressEvent(QMouseEvent* event)      int x = event->pos().x();      int y = event->pos().y(); -    if (x >= 0 && x < 256 && y >= 192 && y < 384) +    Frontend::GetTouchCoords(x, y); + +    if (x >= 0 && x < 256 && y >= 0 && y < 192)      {          touching = true; - -        transformTSCoords(x, y);          NDS::TouchScreen(x, y);      }  } @@ -623,10 +680,22 @@ void MainWindowPanel::mouseMoveEvent(QMouseEvent* event)      int x = event->pos().x();      int y = event->pos().y(); -    transformTSCoords(x, y); +    Frontend::GetTouchCoords(x, y); + +    // clamp to screen range +    if (x < 0) x = 0; +    else if (x > 255) x = 255; +    if (y < 0) y = 0; +    else if (y > 191) y = 191; +      NDS::TouchScreen(x, y);  } +void MainWindowPanel::onScreenLayoutChanged() +{ +    setupScreenLayout(); +} +  MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)  { @@ -750,7 +819,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)                  int data = i*90;                  actScreenRotation[i] = submenu->addAction(QString("%1°").arg(data));                  actScreenRotation[i]->setActionGroup(grpScreenRotation); -                actScreenRotation[i]->setData(QVariant(data)); +                actScreenRotation[i]->setData(QVariant(i));                  actScreenRotation[i]->setCheckable(true);              } @@ -834,8 +903,9 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)      panel = new MainWindowPanel(this);      setCentralWidget(panel); -    panel->setMinimumSize(256, 384); +    panel->ensureProperMinSize(); +    resize(Config::WindowWidth, Config::WindowHeight);      for (int i = 0; i < 9; i++)      { @@ -877,6 +947,16 @@ MainWindow::~MainWindow()  {  } +void MainWindow::resizeEvent(QResizeEvent* event) +{ +    int w = event->size().width(); +    int h = event->size().height(); + +    Config::WindowWidth = w; +    Config::WindowHeight = h; + +    // TODO: detect when the window gets maximized! +}  void MainWindow::keyPressEvent(QKeyEvent* event)  { @@ -1264,32 +1344,79 @@ void MainWindow::onChangeSavestateSRAMReloc(bool checked)  void MainWindow::onChangeScreenSize()  { -    // +    int factor = ((QAction*)sender())->data().toInt(); + +    bool isHori = (Config::ScreenRotation == 1 || Config::ScreenRotation == 3); +    int gap = Config::ScreenGap; + +    int w = 256*factor; +    int h = 192*factor; + +    QSize diff = size() - panel->size(); + +    if (Config::ScreenLayout == 0) // natural +    { +        if (isHori) +            resize(QSize(h+gap+h, w) + diff); +        else +            resize(QSize(w, h+gap+h) + diff); +    } +    else if (Config::ScreenLayout == 1) // vertical +    { +        if (isHori) +            resize(QSize(h, w+gap+w) + diff); +        else +            resize(QSize(w, h+gap+h) + diff); +    } +    else // horizontal +    { +        if (isHori) +            resize(QSize(h+gap+h, w) + diff); +        else +            resize(QSize(w+gap+w, h) + diff); +    }  }  void MainWindow::onChangeScreenRotation(QAction* act)  { -    // +    int rot = act->data().toInt(); +    Config::ScreenRotation = rot; + +    panel->ensureProperMinSize(); +    panel->setupScreenLayout();  }  void MainWindow::onChangeScreenGap(QAction* act)  { -    // +    int gap = act->data().toInt(); +    Config::ScreenGap = gap; + +    panel->ensureProperMinSize(); +    panel->setupScreenLayout();  }  void MainWindow::onChangeScreenLayout(QAction* act)  { -    // +    int layout = act->data().toInt(); +    Config::ScreenLayout = layout; + +    panel->ensureProperMinSize(); +    panel->setupScreenLayout();  }  void MainWindow::onChangeScreenSizing(QAction* act)  { -    // +    int sizing = act->data().toInt(); +    Config::ScreenSizing = sizing; + +    panel->setupScreenLayout();  }  void MainWindow::onChangeIntegerScaling(bool checked)  { -    // +    Config::IntegerScaling = checked?1:0; + +    panel->setupScreenLayout();  }  void MainWindow::onChangeScreenFiltering(bool checked) diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 7051a08..2d14eea 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -54,6 +54,8 @@ signals:      void windowLimitFPSChange(); +    void screenLayoutChange(); +  private:      volatile int EmuStatus;      int PrevEmuStatus; @@ -69,18 +71,25 @@ public:      explicit MainWindowPanel(QWidget* parent);      ~MainWindowPanel(); +    void ensureProperMinSize(); +    void setupScreenLayout(); +  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; +private slots: +    void onScreenLayoutChanged(); +  private:      QImage* screen[2]; +    QTransform screenTrans[2];      bool touching; - -    void transformTSCoords(int& x, int& y);  }; @@ -93,6 +102,8 @@ public:      ~MainWindow();  protected: +    void resizeEvent(QResizeEvent* event) override; +      void keyPressEvent(QKeyEvent* event) override;      void keyReleaseEvent(QKeyEvent* event) override; @@ -138,9 +149,9 @@ private slots:  private:      QString loadErrorStr(int error); +public:      MainWindowPanel* panel; -public:      QAction* actOpenROM;      QAction* actBootFirmware;      QAction* actSaveState[9];  |