From e8ffc699baf40443a348822d9171f0713d26cc9c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Jul 2022 17:54:38 +0600 Subject: [PATCH] qt: Implement per-monitor resizing --- src/86box.c | 6 +++--- src/include/86box/plat.h | 1 - src/include/86box/video.h | 4 ++-- src/qt/qt_main.cpp | 24 ++++++++++++++++-------- src/qt/qt_mainwindow.cpp | 16 ++++++++++++++-- src/qt/qt_mainwindow.hpp | 1 + src/qt/qt_ui.cpp | 3 ++- src/video/video.c | 13 ++++++++++++- vcpkg.json | 1 + 9 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/86box.c b/src/86box.c index 9f62836ad..74d2371e6 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1284,10 +1284,10 @@ set_screen_size(int x, int y) dty = (double)temp_overscan_y; /* Account for possible overscan. */ - if (!(video_is_ega_vga()) && (temp_overscan_y == 16)) { + if (video_get_type_monitor(monitor_index_global) != VIDEO_FLAG_TYPE_SPECIAL && (temp_overscan_y == 16)) { /* CGA */ dy = (((dx - dtx) / 4.0) * 3.0) + dty; - } else if (!(video_is_ega_vga()) && (temp_overscan_y < 16)) { + } else if (video_get_type_monitor(monitor_index_global) != VIDEO_FLAG_TYPE_SPECIAL && (temp_overscan_y < 16)) { /* MDA/Hercules */ dy = (x / 4.0) * 3.0; } else { @@ -1327,7 +1327,7 @@ set_screen_size(int x, int y) /* If the resolution has changed, let the main thread handle it. */ if ((owsx != scrnsz_x) || (owsy != scrnsz_y)) - atomic_flag_clear(&doresize); + atomic_flag_clear(&doresize_monitors[monitor_index_global]); } diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 36c9a9d80..504109dfa 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -77,7 +77,6 @@ extern "C" { /* Global variables residing in the platform module. */ extern int dopause, /* system is paused */ mouse_capture; /* mouse is captured in app */ -extern atomic_flag_t doresize; /* screen resize requested */ extern volatile int is_quit; /* system exit requested */ #ifdef MTR_ENABLED diff --git a/src/include/86box/video.h b/src/include/86box/video.h index a26567eae..5fca74ffb 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -24,7 +24,7 @@ #ifdef __cplusplus #include -using atomic_bool = std::atomic_bool; +using atomic_flag = std::atomic_flag; #else #include #endif @@ -112,7 +112,6 @@ typedef struct monitor_t int mon_force_resize; int mon_fullchange; int mon_changeframecount; - atomic_bool mon_doresize; int mon_screenshots; uint32_t* mon_pal_lookup; int* mon_cga_palette; @@ -125,6 +124,7 @@ typedef struct monitor_t #define MONITORS_NUM 8 extern monitor_t monitors[MONITORS_NUM]; +extern atomic_flag doresize_monitors[MONITORS_NUM]; extern int monitor_index_global; extern int herc_enabled; diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 8700cd643..f0f8f1547 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -122,14 +122,6 @@ main_thread_fn() /* Just so we dont overload the host OS. */ std::this_thread::sleep_for(std::chrono::milliseconds(1)); } - - /* If needed, handle a screen resize. */ - if (!atomic_flag_test_and_set(&doresize) && !video_fullscreen && !is_quit) { - if (vid_resize & 2) - plat_resize_monitor(fixed_size_x, fixed_size_y, 0); - else - plat_resize_monitor(scrnsz_x, scrnsz_y, 0); - } } is_quit = 1; @@ -292,6 +284,22 @@ int main(int argc, char* argv[]) { main_thread = new std::thread(main_thread_fn); }); + QTimer resizeTimer; + resizeTimer.setInterval(0); + resizeTimer.callOnTimeout([]() + { + /* If needed, handle a screen resize. */ + for (int i = 0; i < MONITORS_NUM; i++) { + if (!atomic_flag_test_and_set(&doresize_monitors[i]) && !video_fullscreen && !is_quit) { + if (vid_resize & 2) + plat_resize_monitor(fixed_size_x, fixed_size_y, i); + else + plat_resize_monitor(monitors[i].mon_scrnsz_x, monitors[i].mon_scrnsz_y, i); + } + } + }); + resizeTimer.start(); + auto ret = app.exec(); cpu_thread_run = 0; main_thread->join(); diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 57725e866..a22295058 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -224,7 +224,7 @@ MainWindow::MainWindow(QWidget *parent) : }); connect(this, &MainWindow::resizeContents, this, [this](int w, int h) { - if (!QApplication::platformName().contains("eglfs") && vid_resize == 0) { + if (!QApplication::platformName().contains("eglfs") && vid_resize != 1) { w = (w / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.)); int modifiedHeight = (h / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.)) @@ -237,6 +237,17 @@ MainWindow::MainWindow(QWidget *parent) : } }); + connect(this, &MainWindow::resizeContentsMonitor, this, [this](int w, int h, int monitor_index) + { + if (!QApplication::platformName().contains("eglfs") && vid_resize != 1) { + w = (w / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); + + int modifiedHeight = (h / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); + + renderers[monitor_index]->setFixedSize(w, modifiedHeight); + } + }); + connect(ui->menubar, &QMenuBar::triggered, this, [this] { config_save(); if (QApplication::activeWindow() == this) @@ -1605,7 +1616,8 @@ static void update_scaled_checkboxes(Ui::MainWindow* ui, QAction* selected) { reset_screen_size(); device_force_redraw(); video_force_resize_set(1); - atomic_flag_clear(&doresize); + for (int i = 0; i < MONITORS_NUM; i++) + atomic_flag_clear(&doresize_monitors[i]); config_save(); } diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 026d86802..5279d8997 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -33,6 +33,7 @@ public: signals: void paint(const QImage& image); void resizeContents(int w, int h); + void resizeContentsMonitor(int w, int h, int monitor_index); void pollMouse(); void statusBarMessage(const QString& msg); void updateStatusBarPanes(); diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index 329132557..fd91c3da5 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -65,7 +65,8 @@ void mouse_poll() { } void plat_resize_monitor(int w, int h, int monitor_index) { - main_window->resizeContents(w, h); + if (monitor_index >= 1) main_window->resizeContentsMonitor(w, h, monitor_index); + else main_window->resizeContents(w, h); } void plat_setfullscreen(int on) { diff --git a/src/video/video.c b/src/video/video.c index 419b9b82a..16eab9986 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -48,6 +48,7 @@ * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. */ +#include #define PNG_DEBUG 0 #include #include @@ -101,6 +102,17 @@ static const video_timings_t *vid_timings; static uint32_t cga_2_table[16]; static uint8_t thread_run = 0; monitor_t monitors[MONITORS_NUM]; +atomic_flag doresize_monitors[MONITORS_NUM] = +{ + [0] = ATOMIC_FLAG_INIT, + [1] = ATOMIC_FLAG_INIT, + [2] = ATOMIC_FLAG_INIT, + [3] = ATOMIC_FLAG_INIT, + [4] = ATOMIC_FLAG_INIT, + [5] = ATOMIC_FLAG_INIT, + [6] = ATOMIC_FLAG_INIT, + [7] = ATOMIC_FLAG_INIT +}; int monitor_index_global = 0; int herc_enabled = 0; @@ -922,7 +934,6 @@ video_monitor_init(int index) monitors[index].mon_bpp = 8; monitors[index].mon_changeframecount = 2; monitors[index].target_buffer = create_bitmap(2048, 2048); - atomic_init(&monitors[index].mon_doresize, 0); monitors[index].mon_blit_data_ptr = calloc(1, sizeof(struct blit_data_struct)); monitors[index].mon_blit_data_ptr->wake_blit_thread = thread_create_event(); monitors[index].mon_blit_data_ptr->blit_complete = thread_create_event(); diff --git a/vcpkg.json b/vcpkg.json index 3583bb961..f3b639078 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -25,6 +25,7 @@ "network", "vulkan", "widgets", + "png", "zstd" ] },