qt: Implement per-monitor resizing

This commit is contained in:
Cacodemon345
2022-07-04 17:54:38 +06:00
parent 7ab71cafd3
commit e8ffc699ba
9 changed files with 51 additions and 18 deletions

View File

@@ -1284,10 +1284,10 @@ set_screen_size(int x, int y)
dty = (double)temp_overscan_y; dty = (double)temp_overscan_y;
/* Account for possible overscan. */ /* 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 */ /* CGA */
dy = (((dx - dtx) / 4.0) * 3.0) + dty; 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 */ /* MDA/Hercules */
dy = (x / 4.0) * 3.0; dy = (x / 4.0) * 3.0;
} else { } else {
@@ -1327,7 +1327,7 @@ set_screen_size(int x, int y)
/* If the resolution has changed, let the main thread handle it. */ /* If the resolution has changed, let the main thread handle it. */
if ((owsx != scrnsz_x) || (owsy != scrnsz_y)) if ((owsx != scrnsz_x) || (owsy != scrnsz_y))
atomic_flag_clear(&doresize); atomic_flag_clear(&doresize_monitors[monitor_index_global]);
} }

View File

@@ -77,7 +77,6 @@ extern "C" {
/* Global variables residing in the platform module. */ /* Global variables residing in the platform module. */
extern int dopause, /* system is paused */ extern int dopause, /* system is paused */
mouse_capture; /* mouse is captured in app */ mouse_capture; /* mouse is captured in app */
extern atomic_flag_t doresize; /* screen resize requested */
extern volatile int is_quit; /* system exit requested */ extern volatile int is_quit; /* system exit requested */
#ifdef MTR_ENABLED #ifdef MTR_ENABLED

View File

@@ -24,7 +24,7 @@
#ifdef __cplusplus #ifdef __cplusplus
#include <atomic> #include <atomic>
using atomic_bool = std::atomic_bool; using atomic_flag = std::atomic_flag;
#else #else
#include <stdatomic.h> #include <stdatomic.h>
#endif #endif
@@ -112,7 +112,6 @@ typedef struct monitor_t
int mon_force_resize; int mon_force_resize;
int mon_fullchange; int mon_fullchange;
int mon_changeframecount; int mon_changeframecount;
atomic_bool mon_doresize;
int mon_screenshots; int mon_screenshots;
uint32_t* mon_pal_lookup; uint32_t* mon_pal_lookup;
int* mon_cga_palette; int* mon_cga_palette;
@@ -125,6 +124,7 @@ typedef struct monitor_t
#define MONITORS_NUM 8 #define MONITORS_NUM 8
extern monitor_t monitors[MONITORS_NUM]; extern monitor_t monitors[MONITORS_NUM];
extern atomic_flag doresize_monitors[MONITORS_NUM];
extern int monitor_index_global; extern int monitor_index_global;
extern int herc_enabled; extern int herc_enabled;

View File

@@ -122,14 +122,6 @@ main_thread_fn()
/* Just so we dont overload the host OS. */ /* Just so we dont overload the host OS. */
std::this_thread::sleep_for(std::chrono::milliseconds(1)); 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; is_quit = 1;
@@ -292,6 +284,22 @@ int main(int argc, char* argv[]) {
main_thread = new std::thread(main_thread_fn); 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(); auto ret = app.exec();
cpu_thread_run = 0; cpu_thread_run = 0;
main_thread->join(); main_thread->join();

View File

@@ -224,7 +224,7 @@ MainWindow::MainWindow(QWidget *parent) :
}); });
connect(this, &MainWindow::resizeContents, this, [this](int w, int h) { 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.)); w = (w / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.));
int modifiedHeight = (h / (!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] { connect(ui->menubar, &QMenuBar::triggered, this, [this] {
config_save(); config_save();
if (QApplication::activeWindow() == this) if (QApplication::activeWindow() == this)
@@ -1605,7 +1616,8 @@ static void update_scaled_checkboxes(Ui::MainWindow* ui, QAction* selected) {
reset_screen_size(); reset_screen_size();
device_force_redraw(); device_force_redraw();
video_force_resize_set(1); 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(); config_save();
} }

View File

@@ -33,6 +33,7 @@ public:
signals: signals:
void paint(const QImage& image); void paint(const QImage& image);
void resizeContents(int w, int h); void resizeContents(int w, int h);
void resizeContentsMonitor(int w, int h, int monitor_index);
void pollMouse(); void pollMouse();
void statusBarMessage(const QString& msg); void statusBarMessage(const QString& msg);
void updateStatusBarPanes(); void updateStatusBarPanes();

View File

@@ -65,7 +65,8 @@ void mouse_poll() {
} }
void plat_resize_monitor(int w, int h, int monitor_index) { 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) { void plat_setfullscreen(int on) {

View File

@@ -48,6 +48,7 @@
* Copyright 2008-2019 Sarah Walker. * Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca. * Copyright 2016-2019 Miran Grca.
*/ */
#include <stdatomic.h>
#define PNG_DEBUG 0 #define PNG_DEBUG 0
#include <png.h> #include <png.h>
#include <stdarg.h> #include <stdarg.h>
@@ -101,6 +102,17 @@ static const video_timings_t *vid_timings;
static uint32_t cga_2_table[16]; static uint32_t cga_2_table[16];
static uint8_t thread_run = 0; static uint8_t thread_run = 0;
monitor_t monitors[MONITORS_NUM]; 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 monitor_index_global = 0;
int herc_enabled = 0; int herc_enabled = 0;
@@ -922,7 +934,6 @@ video_monitor_init(int index)
monitors[index].mon_bpp = 8; monitors[index].mon_bpp = 8;
monitors[index].mon_changeframecount = 2; monitors[index].mon_changeframecount = 2;
monitors[index].target_buffer = create_bitmap(2048, 2048); 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 = 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->wake_blit_thread = thread_create_event();
monitors[index].mon_blit_data_ptr->blit_complete = thread_create_event(); monitors[index].mon_blit_data_ptr->blit_complete = thread_create_event();

View File

@@ -25,6 +25,7 @@
"network", "network",
"vulkan", "vulkan",
"widgets", "widgets",
"png",
"zstd" "zstd"
] ]
}, },