From 350246606e2cdae7a381bbd656bbc985d02afea2 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 6 Dec 2021 15:52:19 +0600 Subject: [PATCH 01/21] Remove redundant RtMidi checking --- src/qt/CMakeLists.txt | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 96d3ba6d4..a07887e80 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -4,7 +4,6 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) -find_package(PkgConfig) find_package(Threads REQUIRED) add_library(plat STATIC qt.c qt_main.cpp qt_platform.cpp cpp11_thread.cpp) @@ -107,20 +106,6 @@ target_link_libraries( Threads::Threads ) -if (PkgConfig_FOUND) - pkg_check_modules(RTMIDI rtmidi) - if (RTMIDI_FOUND) - target_include_directories(plat PRIVATE ${RTMIDI_INCLUDE_DIRS}) - target_link_directories(plat INTERFACE ${RTMIDI_LIBRARY_DIRS}) - target_link_libraries(plat PRIVATE ${RTMIDI_LIBRARIES}) - target_sources(plat PRIVATE rtmidi_midi.cpp) - else() - target_sources(plat PRIVATE qt_midi.cpp) - endif() -else() - target_sources(plat PRIVATE qt_midi.cpp) -endif() - if (UNIX AND NOT APPLE) find_package(X11 REQUIRED) target_link_libraries(ui PRIVATE X11::X11) From c376cca71ee4e680bb9543d10b3890e34a32e324 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 6 Dec 2021 16:33:25 +0600 Subject: [PATCH 02/21] Fix mouse wheel scrolling --- src/qt/qt_rendererstack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index cbc0b5e44..3df8c8ab2 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -99,7 +99,7 @@ void RendererStack::wheelEvent(QWheelEvent *event) { if (mouse_capture) { - mousedata.deltay += event->pixelDelta().y(); + mousedata.deltaz += event->pixelDelta().y(); } } From ae477a7c2a0f09c11ebab162d5e12e6d7cc64e2c Mon Sep 17 00:00:00 2001 From: "Joakim L. Gilje" Date: Mon, 6 Dec 2021 21:24:22 +0100 Subject: [PATCH 03/21] implement plat_vidapi_name and plat_vidapi so 86box knows about the qt renderers --- src/qt/qt.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/qt/qt.c b/src/qt/qt.c index 2ebab6f69..40f25135c 100644 --- a/src/qt/qt.c +++ b/src/qt/qt.c @@ -3,6 +3,7 @@ * implemented in Qt */ +#include #include #include @@ -62,9 +63,36 @@ wchar_t* plat_get_string(int i) int plat_vidapi(char* api) { + if (!strcasecmp(api, "default") || !strcasecmp(api, "system")) { + return 0; + } else if (!strcasecmp(api, "qt_software")) { + return 0; + } else if (!strcasecmp(api, "qt_opengl")) { + return 1; + } else if (!strcasecmp(api, "qt_opengles")) { + return 2; + } + return 0; } char* plat_vidapi_name(int api) { - return "default"; + char* name = "default"; + + switch (api) { + case 0: + name = "qt_software"; + break; + case 1: + name = "qt_opengl"; + break; + case 2: + name = "qt_opengles"; + break; + default: + fatal("Unknown renderer: %i\n", api); + break; + } + + return name; } From 021dbf7efaabca8c93925e6de1a1736b5e4e83eb Mon Sep 17 00:00:00 2001 From: "Joakim L. Gilje" Date: Mon, 6 Dec 2021 21:24:53 +0100 Subject: [PATCH 04/21] run init before mainwindow is constructed, so 86box internals are loaded and ready --- src/qt/qt_main.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 40d8680eb..fcd317e54 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -92,6 +92,12 @@ int main(int argc, char* argv[]) { elapsed_timer.start(); SDL_Init(SDL_INIT_TIMER); + pc_init(argc, argv); + if (! pc_init_modules()) { + ui_msgbox_header(MBX_FATAL, VC(L"No ROMs found."), VC(L"86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory.")); + return 6; + } + main_window = new MainWindow(); main_window->show(); main_window->setFocus(); @@ -103,11 +109,6 @@ int main(int argc, char* argv[]) { } main_window->setFocusPolicy(Qt::StrongFocus); - pc_init(argc, argv); - if (! pc_init_modules()) { - ui_msgbox_header(MBX_FATAL, VC(L"No ROMs found."), VC(L"86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory.")); - return 6; - } pc_reset_hard_init(); /* Set the PAUSE mode depending on the renderer. */ From 230c257922103dd7ec650f36dbe58aef5b14d00c Mon Sep 17 00:00:00 2001 From: "Joakim L. Gilje" Date: Mon, 6 Dec 2021 21:26:17 +0100 Subject: [PATCH 05/21] implemented action resizable window --- src/qt/qt_mainwindow.cpp | 20 +++++++++++++++++++- src/qt/qt_mainwindow.hpp | 1 + src/qt/qt_ui.cpp | 8 -------- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index becfd8f9e..fb426ec8d 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -79,8 +79,13 @@ MainWindow::MainWindow(QWidget *parent) : connect(this, &MainWindow::resizeContents, this, [this](int w, int h) { if (!QApplication::platformName().contains("eglfs")) { + int modifiedHeight = h + menuBar()->height() + statusBar()->height(); ui->stackedWidget->resize(w, h); - resize(w, h + menuBar()->height() + statusBar()->height()); + if (vid_resize == 0) { + setFixedSize(w, modifiedHeight); + } else { + resize(w, modifiedHeight); + } } }); @@ -98,6 +103,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionKeyboard_requires_capture->setChecked(kbd_req_capture); ui->actionRight_CTRL_is_left_ALT->setChecked(rctrl_is_lalt); + ui->actionResizable_window->setChecked(vid_resize > 0); setFocusPolicy(Qt::StrongFocus); ui->gles->setFocusPolicy(Qt::NoFocus); @@ -738,6 +744,7 @@ bool MainWindow::eventFilter(QObject* receiver, QEvent* event) return true; } } + return QMainWindow::eventFilter(receiver, event); } @@ -811,3 +818,14 @@ void MainWindow::focusOutEvent(QFocusEvent* event) { this->releaseKeyboard(); } + +void MainWindow::on_actionResizable_window_triggered(bool checked) { + if (checked) { + vid_resize = 1; + setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + } else { + vid_resize = 0; + } + emit resizeContents(scrnsz_x, scrnsz_y); +} + diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 6c56cfd6a..dde4e0fb7 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -56,6 +56,7 @@ private slots: void on_actionHardware_Renderer_OpenGL_ES_triggered(); void on_actionHardware_Renderer_OpenGL_triggered(); void on_actionSoftware_Renderer_triggered(); + void on_actionResizable_window_triggered(bool checked); void refreshMediaMenu(); void showMessage_(const QString& header, const QString& message); diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index cb9646660..4af7423cc 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -7,10 +7,6 @@ #include "qt_mainwindow.hpp" -std::atomic_int resize_pending = 0; -std::atomic_int resize_w = 0; -std::atomic_int resize_h = 0; - MainWindow* main_window = nullptr; extern "C" { @@ -46,10 +42,6 @@ void mouse_poll() { } void plat_resize(int w, int h) { - resize_w = w; - resize_h = h; - resize_pending = 1; - main_window->resizeContents(w, h); } From b03e6b1aee0787b3c3698301bdcfbb8d787dda11 Mon Sep 17 00:00:00 2001 From: "Joakim L. Gilje" Date: Mon, 6 Dec 2021 21:26:44 +0100 Subject: [PATCH 06/21] typed in the view menu, most stuff in here is unimplemented as of now! --- src/qt/qt_mainwindow.ui | 285 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 281 insertions(+), 4 deletions(-) diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 3541a5736..b85e14b4d 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -54,7 +54,7 @@ 0 0 724 - 20 + 19 @@ -83,10 +83,83 @@ View + + + Renderer + + + + + + + + Window scale factor + + + + + + + + + Filter method + + + + + + + Fullscreen stretch mode + + + + + + + + + EGA/(S)VGA settings + + + + VGA screen type + + + + + + + + + + Grayscale conversion type + + + + + + + + + + + + + + + + + + + + + - - - + + + + + @@ -157,20 +230,224 @@ + + true + Software Renderer + + true + Hardware Renderer (OpenGL) + + true + Hardware Renderer (OpenGL ES) + + + true + + + Hide status bar + + + + + true + + + Resizable window + + + + + true + + + Remember size and position + + + + + Specify dimensions... + + + + + true + + + Force 4:3 display ratio + + + + + true + + + HiDPI scaling + + + + + true + + + CGA/PCjr/Tandy/EGA/(S)VGA overscan + + + + + true + + + Change contrast for monochrome display + + + + + 0.5x + + + + + 1x + + + + + 1.5x + + + + + 2x + + + + + Nearest + + + + + Linear + + + + + true + + + Full screen stretch + + + + + true + + + 4:3 + + + + + true + + + Square pixels (Keep ratio) + + + + + true + + + Integer scale + + + + + true + + + Inverted VGA monitor + + + + + true + + + RGB Color + + + + + true + + + RGB Grayscale + + + + + true + + + Amber monitor + + + + + true + + + Green monitor + + + + + true + + + White monitor + + + + + true + + + BT601 (NTSC/PAL) + + + + + true + + + BT709 (HDTV) + + + + + true + + + Average + + From db0c90a835ebdfae465885d2666c27192c2c1982 Mon Sep 17 00:00:00 2001 From: "Joakim L. Gilje" Date: Mon, 6 Dec 2021 21:33:25 +0100 Subject: [PATCH 07/21] replaced sdl_timer with a qtimer, resulting in a binary which does not link sdl --- src/qt/CMakeLists.txt | 1 - src/qt/qt.c | 2 -- src/qt/qt_main.cpp | 17 +++++------------ src/qt/qt_mainwindow.cpp | 2 -- 4 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index a07887e80..a577bcddc 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -10,7 +10,6 @@ add_library(plat STATIC qt.c qt_main.cpp qt_platform.cpp cpp11_thread.cpp) add_library(ui STATIC qt_ui.cpp qt_cdrom.c - qt_sdl.c qt_mainwindow.cpp qt_mainwindow.hpp diff --git a/src/qt/qt.c b/src/qt/qt.c index 40f25135c..5aca045dc 100644 --- a/src/qt/qt.c +++ b/src/qt/qt.c @@ -13,8 +13,6 @@ #include <86box/timer.h> #include <86box/nvr.h> -#include "qt_sdl.h" - int qt_nvr_save(void) { return nvr_save(); } diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index fcd317e54..1f0d3ea72 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -11,11 +11,7 @@ #include -#include "SDL.h" -#include "SDL_mutex.h" -#include "SDL_timer.h" #include "qt_mainwindow.hpp" -#include "qt_sdl.h" #include "cocoa_mouse.hpp" @@ -77,12 +73,6 @@ main_thread_fn() is_quit = 1; } -uint32_t timer_onesec(uint32_t interval, void* param) -{ - pc_onesec(); - return interval; -} - int main(int argc, char* argv[]) { QApplication app(argc, argv); #ifdef __APPLE__ @@ -90,7 +80,6 @@ int main(int argc, char* argv[]) { app.installNativeEventFilter(&cocoafilter); #endif elapsed_timer.start(); - SDL_Init(SDL_INIT_TIMER); pc_init(argc, argv); if (! pc_init_modules()) { @@ -113,7 +102,11 @@ int main(int argc, char* argv[]) { /* Set the PAUSE mode depending on the renderer. */ // plat_pause(0); - SDL_AddTimer(1000, timer_onesec, nullptr); + QTimer onesec; + QObject::connect(&onesec, &QTimer::timeout, &app, [] { + pc_onesec(); + }); + onesec.start(1000); /* Initialize the rendering window, or fullscreen. */ QTimer::singleShot(50, []() { plat_resize(640, 480); } ); diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index fb426ec8d..e0a19a49b 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -7,8 +7,6 @@ extern "C" { #include <86box/keyboard.h> #include <86box/plat.h> #include <86box/video.h> - -#include "qt_sdl.h" }; #include From 431f75ce4ca930248e1862cbcdbe6e4688b82a39 Mon Sep 17 00:00:00 2001 From: "Joakim L. Gilje" Date: Mon, 6 Dec 2021 21:39:39 +0100 Subject: [PATCH 08/21] connected vid_api and menubar actions --- src/qt/qt_mainwindow.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index e0a19a49b..8829f1f91 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -102,6 +102,20 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionKeyboard_requires_capture->setChecked(kbd_req_capture); ui->actionRight_CTRL_is_left_ALT->setChecked(rctrl_is_lalt); ui->actionResizable_window->setChecked(vid_resize > 0); + switch (vid_api) { + case 0: + ui->stackedWidget->setCurrentIndex(0); + ui->actionSoftware_Renderer->setChecked(true); + break; + case 1: + ui->stackedWidget->setCurrentIndex(1); + ui->actionHardware_Renderer_OpenGL->setChecked(true); + break; + case 2: + ui->stackedWidget->setCurrentIndex(2); + ui->actionHardware_Renderer_OpenGL_ES->setChecked(true); + break; + } setFocusPolicy(Qt::StrongFocus); ui->gles->setFocusPolicy(Qt::NoFocus); @@ -797,14 +811,23 @@ void MainWindow::keyReleaseEvent(QKeyEvent* event) void MainWindow::on_actionSoftware_Renderer_triggered() { ui->stackedWidget->setCurrentIndex(0); + ui->actionHardware_Renderer_OpenGL->setChecked(false); + ui->actionHardware_Renderer_OpenGL_ES->setChecked(false); + vid_api = 0; } void MainWindow::on_actionHardware_Renderer_OpenGL_triggered() { ui->stackedWidget->setCurrentIndex(1); + ui->actionSoftware_Renderer->setChecked(false); + ui->actionHardware_Renderer_OpenGL_ES->setChecked(false); + vid_api = 1; } void MainWindow::on_actionHardware_Renderer_OpenGL_ES_triggered() { ui->stackedWidget->setCurrentIndex(2); + ui->actionSoftware_Renderer->setChecked(false); + ui->actionHardware_Renderer_OpenGL->setChecked(false); + vid_api = 2; } void MainWindow::focusInEvent(QFocusEvent* event) From 71dd799936d477525e58537d2c2dbc37e63103a2 Mon Sep 17 00:00:00 2001 From: "Joakim L. Gilje" Date: Mon, 6 Dec 2021 21:45:40 +0100 Subject: [PATCH 09/21] inverted monitor --- src/qt/qt_mainwindow.cpp | 15 +++++++++++++++ src/qt/qt_mainwindow.hpp | 1 + 2 files changed, 16 insertions(+) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 8829f1f91..d113b9296 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -850,3 +850,18 @@ void MainWindow::on_actionResizable_window_triggered(bool checked) { emit resizeContents(scrnsz_x, scrnsz_y); } +static void +video_toggle_option(QAction* action, int *val) +{ + startblit(); + *val ^= 1; + action->setChecked(*val > 0 ? true : false); + endblit(); + config_save(); + device_force_redraw(); +} + +void MainWindow::on_actionInverted_VGA_monitor_triggered() { + video_toggle_option(ui->actionInverted_VGA_monitor, &invert_display); + video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; +} diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index dde4e0fb7..acab69f95 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -57,6 +57,7 @@ private slots: void on_actionHardware_Renderer_OpenGL_triggered(); void on_actionSoftware_Renderer_triggered(); void on_actionResizable_window_triggered(bool checked); + void on_actionInverted_VGA_monitor_triggered(); void refreshMediaMenu(); void showMessage_(const QString& header, const QString& message); From 78de384cc4eb1870569ec51c911031d47bf4fdd8 Mon Sep 17 00:00:00 2001 From: "Joakim L. Gilje" Date: Mon, 6 Dec 2021 21:58:41 +0100 Subject: [PATCH 10/21] scaling actions --- src/qt/qt_mainwindow.cpp | 50 ++++++++++++++++++++++++++++++++++++++++ src/qt/qt_mainwindow.hpp | 4 ++++ src/qt/qt_mainwindow.ui | 12 ++++++++++ 3 files changed, 66 insertions(+) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index d113b9296..e64316f5f 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -102,6 +102,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionKeyboard_requires_capture->setChecked(kbd_req_capture); ui->actionRight_CTRL_is_left_ALT->setChecked(rctrl_is_lalt); ui->actionResizable_window->setChecked(vid_resize > 0); + ui->menuWindow_scale_factor->setEnabled(vid_resize == 0); switch (vid_api) { case 0: ui->stackedWidget->setCurrentIndex(0); @@ -116,6 +117,20 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionHardware_Renderer_OpenGL_ES->setChecked(true); break; } + switch (scale) { + case 0: + ui->action0_5x->setChecked(true); + break; + case 1: + ui->action1x->setChecked(true); + break; + case 2: + ui->action1_5x->setChecked(true); + break; + case 3: + ui->action2x->setChecked(true); + break; + } setFocusPolicy(Qt::StrongFocus); ui->gles->setFocusPolicy(Qt::NoFocus); @@ -847,6 +862,7 @@ void MainWindow::on_actionResizable_window_triggered(bool checked) { } else { vid_resize = 0; } + ui->menuWindow_scale_factor->setEnabled(! checked); emit resizeContents(scrnsz_x, scrnsz_y); } @@ -865,3 +881,37 @@ void MainWindow::on_actionInverted_VGA_monitor_triggered() { video_toggle_option(ui->actionInverted_VGA_monitor, &invert_display); video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; } + +static void update_scaled_checkboxes(Ui::MainWindow* ui, QAction* selected) { + ui->action0_5x->setChecked(ui->action0_5x == selected); + ui->action1x->setChecked(ui->action1x == selected); + ui->action1_5x->setChecked(ui->action1_5x == selected); + ui->action2x->setChecked(ui->action2x == selected); + + reset_screen_size(); + device_force_redraw(); + video_force_resize_set(1); + doresize = 1; + config_save(); +} + +void MainWindow::on_action0_5x_triggered() { + scale = 0; + update_scaled_checkboxes(ui, ui->action0_5x); +} + +void MainWindow::on_action1x_triggered() { + scale = 1; + update_scaled_checkboxes(ui, ui->action1x); +} + +void MainWindow::on_action1_5x_triggered() { + scale = 2; + update_scaled_checkboxes(ui, ui->action1_5x); +} + +void MainWindow::on_action2x_triggered() { + scale = 3; + update_scaled_checkboxes(ui, ui->action2x); +} + diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index acab69f95..97ac840d6 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -58,6 +58,10 @@ private slots: void on_actionSoftware_Renderer_triggered(); void on_actionResizable_window_triggered(bool checked); void on_actionInverted_VGA_monitor_triggered(); + void on_action0_5x_triggered(); + void on_action1x_triggered(); + void on_action1_5x_triggered(); + void on_action2x_triggered(); void refreshMediaMenu(); void showMessage_(const QString& header, const QString& message); diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index b85e14b4d..47a52eed5 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -315,21 +315,33 @@ + + true + 0.5x + + true + 1x + + true + 1.5x + + true + 2x From 2d9020070fd9b04c96636d31eb900a7715cc7bcb Mon Sep 17 00:00:00 2001 From: "Joakim L. Gilje" Date: Mon, 6 Dec 2021 22:02:18 +0100 Subject: [PATCH 11/21] filter actions --- src/qt/qt_mainwindow.cpp | 17 +++++++++++++++++ src/qt/qt_mainwindow.hpp | 2 ++ src/qt/qt_mainwindow.ui | 6 ++++++ 3 files changed, 25 insertions(+) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index e64316f5f..3667a2b59 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -131,6 +131,14 @@ MainWindow::MainWindow(QWidget *parent) : ui->action2x->setChecked(true); break; } + switch (video_filter_method) { + case 0: + ui->actionNearest->setChecked(true); + break; + case 1: + ui->actionLinear->setChecked(true); + break; + } setFocusPolicy(Qt::StrongFocus); ui->gles->setFocusPolicy(Qt::NoFocus); @@ -915,3 +923,12 @@ void MainWindow::on_action2x_triggered() { update_scaled_checkboxes(ui, ui->action2x); } +void MainWindow::on_actionNearest_triggered() { + video_filter_method = 0; + ui->actionLinear->setChecked(false); +} + +void MainWindow::on_actionLinear_triggered() { + video_filter_method = 1; + ui->actionNearest->setChecked(false); +} diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 97ac840d6..e3a80b15d 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -62,6 +62,8 @@ private slots: void on_action1x_triggered(); void on_action1_5x_triggered(); void on_action2x_triggered(); + void on_actionLinear_triggered(); + void on_actionNearest_triggered(); void refreshMediaMenu(); void showMessage_(const QString& header, const QString& message); diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 47a52eed5..fb53af568 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -347,11 +347,17 @@ + + true + Nearest + + true + Linear From 61a2cf986b03f08ad79c4f713c4bf0ee91fcabe0 Mon Sep 17 00:00:00 2001 From: "Joakim L. Gilje" Date: Tue, 7 Dec 2021 13:47:42 +0100 Subject: [PATCH 12/21] implemented fullscreen stretch modes --- src/qt/CMakeLists.txt | 2 + src/qt/qt_hardwarerenderer.cpp | 20 +++----- src/qt/qt_hardwarerenderer.hpp | 9 ++-- src/qt/qt_mainwindow.cpp | 55 +++++++++++++++++++++ src/qt/qt_mainwindow.hpp | 4 ++ src/qt/qt_mainwindow.ui | 16 +++--- src/qt/qt_renderercomon.cpp | 89 ++++++++++++++++++++++++++++++++++ src/qt/qt_renderercomon.hpp | 19 ++++++++ src/qt/qt_softwarerenderer.cpp | 21 +++----- src/qt/qt_softwarerenderer.hpp | 9 ++-- 10 files changed, 201 insertions(+), 43 deletions(-) create mode 100644 src/qt/qt_renderercomon.cpp create mode 100644 src/qt/qt_renderercomon.hpp diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index a577bcddc..7936e3a42 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -21,6 +21,8 @@ add_library(ui STATIC qt_rendererstack.cpp qt_rendererstack.hpp qt_rendererstack.ui + qt_renderercomon.cpp + qt_renderercomon.hpp qt_softwarerenderer.cpp qt_softwarerenderer.hpp qt_hardwarerenderer.cpp diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp index d9a206238..6efa4809c 100644 --- a/src/qt/qt_hardwarerenderer.cpp +++ b/src/qt/qt_hardwarerenderer.cpp @@ -14,14 +14,8 @@ void HardwareRenderer::initializeGL() initializeOpenGLFunctions(); } -void HardwareRenderer::paintGL() -{ - QPainter painter(this); - painter.setRenderHint(QPainter::SmoothPixmapTransform, video_filter_method > 0 ? true : false); - painter.drawImage(QRect(0, 0, width(), height()), image, QRect(sx, sy, sw, sh)); - // "release" image, reducing it's refcount, so renderstack::blit() - // won't have to reallocate - image = QImage(); +void HardwareRenderer::paintGL() { + onPaint(this); } void HardwareRenderer::setRenderType(RenderType type) { @@ -41,9 +35,11 @@ void HardwareRenderer::setRenderType(RenderType type) { void HardwareRenderer::onBlit(const QImage& img, int x, int y, int w, int h) { image = img; - sx = x; - sy = y; - sw = w; - sh = h; + source.setRect(x, y, w, h); update(); } + +void HardwareRenderer::resizeEvent(QResizeEvent *event) { + onResize(width(), height()); + QOpenGLWidget::resizeEvent(event); +} diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp index 4d7f68a08..3a47c6284 100644 --- a/src/qt/qt_hardwarerenderer.hpp +++ b/src/qt/qt_hardwarerenderer.hpp @@ -10,11 +10,13 @@ #include #include +#include "qt_renderercomon.hpp" + #ifdef WAYLAND #include "wl_mouse.hpp" #endif -class HardwareRenderer : public QOpenGLWidget, protected QOpenGLFunctions +class HardwareRenderer : public QOpenGLWidget, protected QOpenGLFunctions, public RendererCommon { Q_OBJECT @@ -49,7 +51,6 @@ public: public slots: void onBlit(const QImage& img, int, int, int, int); -private: - QImage image; - int sx, sy, sw, sh; +protected: + void resizeEvent(QResizeEvent *event) override; }; diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 3667a2b59..e56967892 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -139,6 +139,20 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionLinear->setChecked(true); break; } + switch (video_fullscreen_scale) { + case FULLSCR_SCALE_FULL: + ui->actionFullScreen_stretch->setChecked(true); + break; + case FULLSCR_SCALE_43: + ui->actionFullScreen_43->setChecked(true); + break; + case FULLSCR_SCALE_KEEPRATIO: + ui->actionFullScreen_keepRatio->setChecked(true); + break; + case FULLSCR_SCALE_INT: + ui->actionFullScreen_int->setChecked(true); + break; + } setFocusPolicy(Qt::StrongFocus); ui->gles->setFocusPolicy(Qt::NoFocus); @@ -735,6 +749,10 @@ void MainWindow::on_actionFullscreen_triggered() { showFullScreen(); video_fullscreen = 1; } + + auto widget = ui->stackedWidget->currentWidget(); + auto rc = dynamic_cast(widget); + rc->onResize(widget->width(), widget->height()); } void MainWindow::setTitle_(const wchar_t *title) @@ -932,3 +950,40 @@ void MainWindow::on_actionLinear_triggered() { video_filter_method = 1; ui->actionNearest->setChecked(false); } + +static void update_fullscreen_scale_checkboxes(Ui::MainWindow* ui, QAction* selected) { + ui->actionFullScreen_stretch->setChecked(ui->actionFullScreen_stretch == selected); + ui->actionFullScreen_43->setChecked(ui->actionFullScreen_43 == selected); + ui->actionFullScreen_keepRatio->setChecked(ui->actionFullScreen_keepRatio == selected); + ui->actionFullScreen_int->setChecked(ui->actionFullScreen_int == selected); + + if (video_fullscreen > 0) { + auto widget = ui->stackedWidget->currentWidget(); + auto rc = dynamic_cast(widget); + rc->onResize(widget->width(), widget->height()); + } + + device_force_redraw(); + config_save(); +} + +void MainWindow::on_actionFullScreen_stretch_triggered() { + video_fullscreen_scale = FULLSCR_SCALE_FULL; + update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_stretch); +} + +void MainWindow::on_actionFullScreen_43_triggered() { + video_fullscreen_scale = FULLSCR_SCALE_43; + update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_43); +} + +void MainWindow::on_actionFullScreen_keepRatio_triggered() { + video_fullscreen_scale = FULLSCR_SCALE_KEEPRATIO; + update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_keepRatio); +} + +void MainWindow::on_actionFullScreen_int_triggered() { + video_fullscreen_scale = FULLSCR_SCALE_INT; + update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_int); +} + diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index e3a80b15d..406d9a26a 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -64,6 +64,10 @@ private slots: void on_action2x_triggered(); void on_actionLinear_triggered(); void on_actionNearest_triggered(); + void on_actionFullScreen_int_triggered(); + void on_actionFullScreen_keepRatio_triggered(); + void on_actionFullScreen_43_triggered(); + void on_actionFullScreen_stretch_triggered(); void refreshMediaMenu(); void showMessage_(const QString& header, const QString& message); diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index fb53af568..af8a8a2bd 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -111,10 +111,10 @@ Fullscreen stretch mode - - - - + + + + @@ -362,7 +362,7 @@ Linear - + true @@ -370,7 +370,7 @@ Full screen stretch - + true @@ -378,7 +378,7 @@ 4:3 - + true @@ -386,7 +386,7 @@ Square pixels (Keep ratio) - + true diff --git a/src/qt/qt_renderercomon.cpp b/src/qt/qt_renderercomon.cpp new file mode 100644 index 000000000..173ae1abe --- /dev/null +++ b/src/qt/qt_renderercomon.cpp @@ -0,0 +1,89 @@ +#include "qt_renderercomon.hpp" + +#include +#include + +#include + +extern "C" { +#include <86box/86box.h> +#include <86box/video.h> +} + +RendererCommon::RendererCommon() = default; + +void RendererCommon::onPaint(QPaintDevice* device) { + QPainter painter(device); + painter.setRenderHint(QPainter::SmoothPixmapTransform, video_filter_method > 0 ? true : false); + painter.drawImage(destination, image, source); + // "release" image, reducing it's refcount, so renderstack::blit() + // won't have to reallocate + image = QImage(); +} + +static void integer_scale(double *d, double *g) { + double ratio; + + if (*d > *g) { + ratio = std::floor(*d / *g); + *d = *g * ratio; + } else { + ratio = std::ceil(*d / *g); + *d = *g / ratio; + } +} + +void RendererCommon::onResize(int width, int height) { + if (video_fullscreen == 0) { + destination.setRect(0, 0, width, height); + return; + } + double dx, dy, dw, dh, gsr; + + double hw = width; + double hh = height; + double gw = source.width(); + double gh = source.height(); + double hsr = hw / hh; + + switch (video_fullscreen_scale) { + case FULLSCR_SCALE_INT: + gsr = gw / gh; + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + integer_scale(&dw, &gw); + integer_scale(&dh, &gh); + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + destination.setRect(dx, dy, dw, dh); + break; + case FULLSCR_SCALE_43: + case FULLSCR_SCALE_KEEPRATIO: + if (video_fullscreen_scale == FULLSCR_SCALE_43) { + gsr = 4.0 / 3.0; + } else { + gsr = gw / gh; + } + + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + destination.setRect(dx, dy, dw, dh); + break; + case FULLSCR_SCALE_FULL: + default: + destination.setRect(0, 0, hw, hh); + break; + } +} diff --git a/src/qt/qt_renderercomon.hpp b/src/qt/qt_renderercomon.hpp new file mode 100644 index 000000000..6eed9c9b2 --- /dev/null +++ b/src/qt/qt_renderercomon.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +class QWidget; + +class RendererCommon +{ +public: + RendererCommon(); + + void onResize(int width, int height); +protected: + void onPaint(QPaintDevice* device); + + QImage image; + QRect source, destination; +}; diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index cf69ca2fb..0565d2d6c 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -1,26 +1,19 @@ #include "qt_softwarerenderer.hpp" -extern "C" { -#include <86box/86box.h> -} -#include - SoftwareRenderer::SoftwareRenderer(QWidget *parent) : QWidget(parent) {} void SoftwareRenderer::paintEvent(QPaintEvent *event) { (void) event; - - QPainter painter(this); - painter.setRenderHint(QPainter::SmoothPixmapTransform, video_filter_method > 0 ? true : false); - painter.drawImage(QRect(0, 0, width(), height()), image, QRect(sx, sy, sw, sh)); - image = QImage(); + onPaint(this); } void SoftwareRenderer::onBlit(const QImage& img, int x, int y, int w, int h) { image = img; - sx = x; - sy = y; - sw = w; - sh = h; + source.setRect(x, y, w, h); update(); } + +void SoftwareRenderer::resizeEvent(QResizeEvent *event) { + onResize(width(), height()); + QWidget::resizeEvent(event); +} diff --git a/src/qt/qt_softwarerenderer.hpp b/src/qt/qt_softwarerenderer.hpp index 2a1075023..873e9f732 100644 --- a/src/qt/qt_softwarerenderer.hpp +++ b/src/qt/qt_softwarerenderer.hpp @@ -2,21 +2,20 @@ #define SOFTWARERENDERER_HPP #include +#include "qt_renderercomon.hpp" -class SoftwareRenderer : public QWidget +class SoftwareRenderer : public QWidget, public RendererCommon { Q_OBJECT public: explicit SoftwareRenderer(QWidget *parent = nullptr); void paintEvent(QPaintEvent *event) override; - public slots: void onBlit(const QImage& img, int, int, int, int); -private: - QImage image; - int sx, sy, sw, sh; +protected: + void resizeEvent(QResizeEvent *event) override; }; #endif // SOFTWARERENDERER_HPP From d69e21a3e9deb574e8e7ebd1c399a9f35c4eaa6b Mon Sep 17 00:00:00 2001 From: "Joakim L. Gilje" Date: Wed, 8 Dec 2021 11:05:52 +0100 Subject: [PATCH 13/21] startblit() and endblit(): watch for mutex contention. the mutex is unfair on linux, so sleep if there's contention --- src/qt/qt_mainwindow.cpp | 2 ++ src/qt/qt_platform.cpp | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index e56967892..e417aa304 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -905,7 +905,9 @@ video_toggle_option(QAction* action, int *val) void MainWindow::on_actionInverted_VGA_monitor_triggered() { video_toggle_option(ui->actionInverted_VGA_monitor, &invert_display); + startblit(); video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; + endblit(); } static void update_scaled_checkboxes(Ui::MainWindow* ui, QAction* selected) { diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 6be563814..e2a227472 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -21,6 +22,8 @@ // static QByteArray buf; extern QElapsedTimer elapsed_timer; QElapsedTimer elapsed_timer; + +static std::atomic_int blitmx_contention = 0; static std::mutex blitmx; class CharPointer { @@ -382,12 +385,24 @@ void joystick_close(void) {} void joystick_process(void) {} void startblit() { + blitmx_contention++; + if (blitmx.try_lock()) { + return; + } + blitmx.lock(); } void endblit() { + blitmx_contention--; blitmx.unlock(); + if (blitmx_contention > 0) { + // a deadlock has been observed on linux when toggling via video_toggle_option + // because the mutex is typically unfair on linux + // => sleep if there's contention + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } } } From b7fee7745b84335a0e1b5375286f77377142c4a9 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 8 Dec 2021 16:27:58 +0600 Subject: [PATCH 14/21] Mouse event improvements * Only center the cursor when it leaves the emulator screen * Ignore the very first mouse event that appears after it is captured for the first time after starting --- src/qt/qt_rendererstack.cpp | 17 ++++++++++++++--- src/qt/qt_rendererstack.hpp | 2 ++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 3df8c8ab2..8796d7415 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -103,7 +103,7 @@ void RendererStack::wheelEvent(QWheelEvent *event) } } -int ignoreNextMouseEvent = 0; +int ignoreNextMouseEvent = 1; void RendererStack::mouseMoveEvent(QMouseEvent *event) { if (QApplication::platformName().contains("wayland")) @@ -120,12 +120,23 @@ void RendererStack::mouseMoveEvent(QMouseEvent *event) if (ignoreNextMouseEvent) { oldPos = event->pos(); ignoreNextMouseEvent--; event->accept(); return; } mousedata.deltax += event->pos().x() - oldPos.x(); mousedata.deltay += event->pos().y() - oldPos.y(); - QCursor::setPos(mapToGlobal(QPoint(width() / 2, height() / 2))); oldPos = event->pos(); - ignoreNextMouseEvent = 1; #endif } +void RendererStack::leaveEvent(QEvent* event) +{ + if (QApplication::platformName().contains("wayland")) + { + event->accept(); + return; + } + if (!mouse_capture) return; + QCursor::setPos(mapToGlobal(QPoint(width() / 2, height() / 2))); + ignoreNextMouseEvent = 2; + event->accept(); +} + // called from blitter thread void RendererStack::blit(int x, int y, int w, int h) { diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index 05dd5db5c..239bd5bef 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace Ui { class RendererStack; @@ -20,6 +21,7 @@ public: void mouseReleaseEvent(QMouseEvent* event) override; void mouseMoveEvent(QMouseEvent* event) override; void wheelEvent(QWheelEvent *event) override; + void leaveEvent(QEvent *event) override; void keyPressEvent(QKeyEvent* event) override { event->ignore(); From fa83778c0433b59fbd8ce2ca6b56411d22ebe1ce Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 8 Dec 2021 16:36:55 +0600 Subject: [PATCH 15/21] Avoid transparency/whiteness effects on Wayland and macOS --- src/qt/qt_hardwarerenderer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp index 6efa4809c..0659e41a5 100644 --- a/src/qt/qt_hardwarerenderer.cpp +++ b/src/qt/qt_hardwarerenderer.cpp @@ -1,4 +1,5 @@ #include "qt_hardwarerenderer.hpp" +#include extern "C" { #include <86box/86box.h> @@ -26,7 +27,7 @@ void HardwareRenderer::setRenderType(RenderType type) { format.setRenderableType(QSurfaceFormat::OpenGL); break; case RenderType::OpenGLES: - setTextureFormat(GL_RGBA); + setTextureFormat((QApplication::platformName().contains("wayland") || QApplication::platformName() == "cocoa") ? GL_RGB : GL_RGBA); format.setRenderableType(QSurfaceFormat::OpenGLES); break; } From a0789005466c300ac694b3b7522536b9454300c5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 8 Dec 2021 17:02:28 +0600 Subject: [PATCH 16/21] Fix for fullscreen --- src/qt/qt_rendererstack.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 8796d7415..120e150c7 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -4,6 +4,8 @@ #include "qt_softwarerenderer.hpp" #include "qt_hardwarerenderer.hpp" +#include + #ifdef __APPLE__ #include #endif @@ -120,6 +122,8 @@ void RendererStack::mouseMoveEvent(QMouseEvent *event) if (ignoreNextMouseEvent) { oldPos = event->pos(); ignoreNextMouseEvent--; event->accept(); return; } mousedata.deltax += event->pos().x() - oldPos.x(); mousedata.deltay += event->pos().y() - oldPos.y(); + if (event->pos().x() == 0 || event->pos().y() == 0) leaveEvent((QEvent*)event); + if (event->pos().x() == screen()->geometry().width() || event->pos().y() == screen()->geometry().height()) leaveEvent((QEvent*)event); oldPos = event->pos(); #endif } From a6bddd03279ad1735ba2580379de445bb2462ce1 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 8 Dec 2021 17:04:30 +0600 Subject: [PATCH 17/21] Use globalPos for fullscreen --- src/qt/qt_rendererstack.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 120e150c7..e69647f00 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -122,8 +122,8 @@ void RendererStack::mouseMoveEvent(QMouseEvent *event) if (ignoreNextMouseEvent) { oldPos = event->pos(); ignoreNextMouseEvent--; event->accept(); return; } mousedata.deltax += event->pos().x() - oldPos.x(); mousedata.deltay += event->pos().y() - oldPos.y(); - if (event->pos().x() == 0 || event->pos().y() == 0) leaveEvent((QEvent*)event); - if (event->pos().x() == screen()->geometry().width() || event->pos().y() == screen()->geometry().height()) leaveEvent((QEvent*)event); + if (event->globalPos().x() == 0 || event->globalPos().y() == 0) leaveEvent((QEvent*)event); + if (event->globalPos().x() == screen()->geometry().width() || event->globalPos().y() == screen()->geometry().height()) leaveEvent((QEvent*)event); oldPos = event->pos(); #endif } From fe67c40e3360e595924076a008a3f7573c7f530a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 8 Dec 2021 17:09:55 +0600 Subject: [PATCH 18/21] Take into account max cursor position --- src/qt/qt_rendererstack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index e69647f00..bb80944de 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -123,7 +123,7 @@ void RendererStack::mouseMoveEvent(QMouseEvent *event) mousedata.deltax += event->pos().x() - oldPos.x(); mousedata.deltay += event->pos().y() - oldPos.y(); if (event->globalPos().x() == 0 || event->globalPos().y() == 0) leaveEvent((QEvent*)event); - if (event->globalPos().x() == screen()->geometry().width() || event->globalPos().y() == screen()->geometry().height()) leaveEvent((QEvent*)event); + if (event->globalPos().x() == (screen()->geometry().width() - 1) || event->globalPos().y() == (screen()->geometry().height() - 1)) leaveEvent((QEvent*)event); oldPos = event->pos(); #endif } From 5bc00b220f1228391c765febaa9e62aec43e240f Mon Sep 17 00:00:00 2001 From: "Joakim L. Gilje" Date: Wed, 8 Dec 2021 14:47:09 +0100 Subject: [PATCH 19/21] handle early ui_msgbox_header() calls before main_window has been created --- src/qt/qt_ui.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index 4af7423cc..a62a37de9 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -2,6 +2,7 @@ #include #include +#include #include @@ -60,7 +61,13 @@ int ui_msgbox_header(int flags, void *header, void* message) { auto hdr = QString::fromWCharArray(reinterpret_cast(header)); auto msg = QString::fromWCharArray(reinterpret_cast(message)); - main_window->showMessage(hdr, msg); + // any error in early init + if (main_window == nullptr) { + QMessageBox::critical(nullptr, hdr, msg); + } else { + // else scope it to main_window + main_window->showMessage(hdr, msg); + } return 0; } From ededff3ae1bcb664d2303066930674c392ccf2ea Mon Sep 17 00:00:00 2001 From: "Joakim L. Gilje" Date: Wed, 8 Dec 2021 15:12:21 +0100 Subject: [PATCH 20/21] action checkboxes for greyscale conversion --- src/qt/qt_mainwindow.cpp | 55 +++++++++++++++++++++++++++++++++++++--- src/qt/qt_mainwindow.hpp | 5 ++++ 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index e417aa304..ce114a179 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -153,6 +153,23 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionFullScreen_int->setChecked(true); break; } + switch (video_grayscale) { + case 0: + ui->actionRGB_Color->setChecked(true); + break; + case 1: + ui->actionRGB_Grayscale->setChecked(true); + break; + case 2: + ui->actionAmber_monitor->setChecked(true); + break; + case 3: + ui->actionGreen_monitor->setChecked(true); + break; + case 4: + ui->actionWhite_monitor->setChecked(true); + break; + } setFocusPolicy(Qt::StrongFocus); ui->gles->setFocusPolicy(Qt::NoFocus); @@ -897,6 +914,7 @@ video_toggle_option(QAction* action, int *val) { startblit(); *val ^= 1; + video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; action->setChecked(*val > 0 ? true : false); endblit(); config_save(); @@ -905,9 +923,6 @@ video_toggle_option(QAction* action, int *val) void MainWindow::on_actionInverted_VGA_monitor_triggered() { video_toggle_option(ui->actionInverted_VGA_monitor, &invert_display); - startblit(); - video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; - endblit(); } static void update_scaled_checkboxes(Ui::MainWindow* ui, QAction* selected) { @@ -989,3 +1004,37 @@ void MainWindow::on_actionFullScreen_int_triggered() { update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_int); } +static void update_greyscale_checkboxes(Ui::MainWindow* ui, QAction* selected, int value) { + ui->actionRGB_Color->setChecked(ui->actionRGB_Color == selected); + ui->actionRGB_Grayscale->setChecked(ui->actionRGB_Grayscale == selected); + ui->actionAmber_monitor->setChecked(ui->actionAmber_monitor == selected); + ui->actionGreen_monitor->setChecked(ui->actionGreen_monitor == selected); + ui->actionWhite_monitor->setChecked(ui->actionWhite_monitor == selected); + + startblit(); + video_grayscale = value; + video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; + endblit(); + device_force_redraw(); + config_save(); +} + +void MainWindow::on_actionRGB_Color_triggered() { + update_greyscale_checkboxes(ui, ui->actionRGB_Color, 0); +} + +void MainWindow::on_actionRGB_Grayscale_triggered() { + update_greyscale_checkboxes(ui, ui->actionRGB_Grayscale, 1); +} + +void MainWindow::on_actionAmber_monitor_triggered() { + update_greyscale_checkboxes(ui, ui->actionAmber_monitor, 2); +} + +void MainWindow::on_actionGreen_monitor_triggered() { + update_greyscale_checkboxes(ui, ui->actionGreen_monitor, 3); +} + +void MainWindow::on_actionWhite_monitor_triggered() { + update_greyscale_checkboxes(ui, ui->actionWhite_monitor, 4); +} diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 406d9a26a..ac1fd9da5 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -68,6 +68,11 @@ private slots: void on_actionFullScreen_keepRatio_triggered(); void on_actionFullScreen_43_triggered(); void on_actionFullScreen_stretch_triggered(); + void on_actionWhite_monitor_triggered(); + void on_actionGreen_monitor_triggered(); + void on_actionAmber_monitor_triggered(); + void on_actionRGB_Grayscale_triggered(); + void on_actionRGB_Color_triggered(); void refreshMediaMenu(); void showMessage_(const QString& header, const QString& message); From 5f5828a58d3d738d82510f898a2acdbf0b2efa99 Mon Sep 17 00:00:00 2001 From: "Joakim L. Gilje" Date: Wed, 8 Dec 2021 15:17:33 +0100 Subject: [PATCH 21/21] action checkboxes for greyscale conversion type --- src/qt/qt_mainwindow.cpp | 33 +++++++++++++++++++++++++++++++++ src/qt/qt_mainwindow.hpp | 3 +++ 2 files changed, 36 insertions(+) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index ce114a179..8d6a6b671 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -170,6 +170,17 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionWhite_monitor->setChecked(true); break; } + switch (video_graytype) { + case 0: + ui->actionBT601_NTSC_PAL->setChecked(true); + break; + case 1: + ui->actionBT709_HDTV->setChecked(true); + break; + case 2: + ui->actionAverage->setChecked(true); + break; + } setFocusPolicy(Qt::StrongFocus); ui->gles->setFocusPolicy(Qt::NoFocus); @@ -1038,3 +1049,25 @@ void MainWindow::on_actionGreen_monitor_triggered() { void MainWindow::on_actionWhite_monitor_triggered() { update_greyscale_checkboxes(ui, ui->actionWhite_monitor, 4); } + +static void update_greyscale_type_checkboxes(Ui::MainWindow* ui, QAction* selected, int value) { + ui->actionBT601_NTSC_PAL->setChecked(ui->actionBT601_NTSC_PAL == selected); + ui->actionBT709_HDTV->setChecked(ui->actionBT709_HDTV == selected); + ui->actionAverage->setChecked(ui->actionAverage == selected); + + video_graytype = value; + device_force_redraw(); + config_save(); +} + +void MainWindow::on_actionBT601_NTSC_PAL_triggered() { + update_greyscale_type_checkboxes(ui, ui->actionBT601_NTSC_PAL, 0); +} + +void MainWindow::on_actionBT709_HDTV_triggered() { + update_greyscale_type_checkboxes(ui, ui->actionBT709_HDTV, 1); +} + +void MainWindow::on_actionAverage_triggered() { + update_greyscale_type_checkboxes(ui, ui->actionAverage, 2); +} diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index ac1fd9da5..972b2a161 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -73,6 +73,9 @@ private slots: void on_actionAmber_monitor_triggered(); void on_actionRGB_Grayscale_triggered(); void on_actionRGB_Color_triggered(); + void on_actionAverage_triggered(); + void on_actionBT709_HDTV_triggered(); + void on_actionBT601_NTSC_PAL_triggered(); void refreshMediaMenu(); void showMessage_(const QString& header, const QString& message);