diff --git a/src/86box.c b/src/86box.c index f01842465..0769e0c1d 100644 --- a/src/86box.c +++ b/src/86box.c @@ -162,6 +162,7 @@ int postcard_enabled = 0; /* (C) enable POST card */ int isamem_type[ISAMEM_MAX] = { 0,0,0,0 }; /* (C) enable ISA mem cards */ int isartc_type = 0; /* (C) enable ISA RTC card */ int gfxcard = 0; /* (C) graphics/video card */ +int gfxcard_2 = 0; /* (C) graphics/video card */ int sound_is_float = 1; /* (C) sound uses FP values */ int GAMEBLASTER = 0; /* (C) sound option */ int GUS = 0; /* (C) sound option */ diff --git a/src/config.c b/src/config.c index 391d1d301..61fbec740 100644 --- a/src/config.c +++ b/src/config.c @@ -926,7 +926,9 @@ load_video(void) voodoo_enabled = !!config_get_int(cat, "voodoo", 0); ibm8514_enabled = !!config_get_int(cat, "8514a", 0); xga_enabled = !!config_get_int(cat, "xga", 0); - herc_enabled = !!config_get_int(cat, "herc_enabled", 0); + p = config_get_string(cat, "gfxcard_2", NULL); + if (!p) p = "none"; + gfxcard_2 = video_get_video_from_internal_name(p); } @@ -2512,10 +2514,10 @@ save_video(void) else config_set_int(cat, "xga", xga_enabled); - if (herc_enabled == 0) - config_delete_var(cat, "herc_enabled"); + if (gfxcard_2 == 0) + config_delete_var(cat, "gfxcard_2"); else - config_set_int(cat, "herc_enabled", herc_enabled); + config_set_string(cat, "gfxcard_2", video_get_internal_name(gfxcard_2)); delete_section_if_empty(cat); } diff --git a/src/include/86box/video.h b/src/include/86box/video.h index b37cfbcff..5b9f9ab13 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -134,7 +134,7 @@ extern monitor_t monitors[MONITORS_NUM]; extern monitor_settings_t monitor_settings[MONITORS_NUM]; extern atomic_bool doresize_monitors[MONITORS_NUM]; extern int monitor_index_global; -extern int herc_enabled; +extern int gfxcard_2; typedef rgb_t PALETTE[256]; @@ -219,6 +219,7 @@ extern const device_t *video_card_getdevice(int card); extern int video_card_has_config(int card); extern char *video_get_internal_name(int card); extern int video_get_video_from_internal_name(char *s); +extern int video_card_get_flags(int card); extern int video_is_mda(void); extern int video_is_cga(void); extern int video_is_ega_vga(void); diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index cc0eb9bf2..16b5271d4 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -622,8 +622,8 @@ MainWindow::~MainWindow() { void MainWindow::showEvent(QShowEvent *event) { if (shownonce) return; shownonce = true; + if (window_remember) resize(window_w, window_h + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height()) + (hide_tool_bar ? 0 : ui->toolBar->height())); if (window_remember && !QApplication::platformName().contains("wayland")) { - fprintf(stderr, "Geom: %i, %i, %i, %i\n", window_x, window_y, window_w, window_h); setGeometry(window_x, window_y, window_w, window_h + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height()) + (hide_tool_bar ? 0 : ui->toolBar->height())); } if (vid_resize == 2) { @@ -1991,8 +1991,13 @@ void MainWindow::on_actionRenderer_options_triggered() { auto dlg = ui->stackedWidget->getOptions(this); - if (dlg) - dlg->exec(); + if (dlg) { + if (dlg->exec() == QDialog::Accepted) { + for (int i = 1; i < MONITORS_NUM; i++) { + if (renderers[i] && renderers[i]->hasOptions()) renderers[i]->reloadOptions(); + } + } + } } void MainWindow::on_actionMCA_devices_triggered() diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index d4724fdde..918ba155a 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -29,6 +29,7 @@ OpenGLRenderer::OpenGLRenderer(QWidget *parent) : QWindow(parent->windowHandle()) , renderTimer(new QTimer(this)) + , options(nullptr) { renderTimer->setTimerType(Qt::PreciseTimer); /* TODO: need's more accuracy, maybe target 1ms earlier and spin yield */ @@ -165,9 +166,7 @@ OpenGLRenderer::initialize() glTexImage2D(GL_TEXTURE_2D, 0, QOpenGLTexture::RGBA8_UNorm, INIT_WIDTH, INIT_HEIGHT, 0, QOpenGLTexture::BGRA, QOpenGLTexture::UInt32_RGBA8_Rev, NULL); - options = new OpenGLOptions(this, true, glslVersion); - - applyOptions(); + reloadOptions(); glClearColor(0.f, 0.f, 0.f, 1.f); @@ -304,6 +303,15 @@ OpenGLRenderer::applyOptions() currentFilter = options->filter(); } +void +OpenGLRenderer::reloadOptions() +{ + if (options) { delete options; options = nullptr; } + options = new OpenGLOptions(this, true, glslVersion); + + applyOptions(); +} + void OpenGLRenderer::applyShader(const OpenGLShaderPass &shader) { diff --git a/src/qt/qt_openglrenderer.hpp b/src/qt/qt_openglrenderer.hpp index a83eac5dc..a27e0fe21 100644 --- a/src/qt/qt_openglrenderer.hpp +++ b/src/qt/qt_openglrenderer.hpp @@ -53,6 +53,7 @@ public: void finalize() override final; bool hasOptions() const override { return true; } QDialog *getOptions(QWidget *parent) override; + void reloadOptions() override; signals: void initialized(); diff --git a/src/qt/qt_renderercommon.hpp b/src/qt/qt_renderercommon.hpp index 4d346a8e5..1a0bf73e1 100644 --- a/src/qt/qt_renderercommon.hpp +++ b/src/qt/qt_renderercommon.hpp @@ -28,6 +28,8 @@ public: virtual bool hasOptions() const { return false; } /* Returns options dialog for renderer */ virtual QDialog *getOptions(QWidget *parent) { return nullptr; } + /* Reloads options of renderer */ + virtual void reloadOptions() {} virtual bool hasBlitFunc() { return false; } virtual void blit(int x, int y, int w, int h) {} diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index 684a884da..72495ec33 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -53,6 +53,8 @@ public: /* Does current renderer implement options dialog */ bool hasOptions() const { return rendererWindow ? rendererWindow->hasOptions() : false; } + /* Reloads options of current renderer */ + void reloadOptions() const { return rendererWindow->reloadOptions(); } /* Returns options dialog for current renderer */ QDialog *getOptions(QWidget *parent) { return rendererWindow ? rendererWindow->getOptions(parent) : nullptr; } diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index e3fac08ec..872a6d02d 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -87,9 +87,13 @@ void SettingsDisplay::onCurrentMachineChanged(int machineId) { if (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0) { ui->comboBoxVideo->setEnabled(false); + ui->comboBoxVideoSecondary->setEnabled(false); + ui->pushButtonConfigureSecondary->setEnabled(false); selectedRow = 1; } else { ui->comboBoxVideo->setEnabled(true); + ui->comboBoxVideoSecondary->setEnabled(true); + ui->pushButtonConfigureSecondary->setEnabled(true); } ui->comboBoxVideo->setCurrentIndex(selectedRow); } @@ -137,6 +141,30 @@ void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) { ui->checkBoxXga->setChecked(xga_enabled); ui->pushButtonConfigureXga->setEnabled((hasIsa16 || has_MCA) && ui->checkBoxXga->isChecked()); + + int c = 2; + ui->comboBoxVideoSecondary->clear(); + ui->comboBoxVideoSecondary->addItem(QObject::tr("None"), 0); + + while (true) { + const device_t* video_dev = video_card_getdevice(c); + QString name = DeviceConfig::DeviceName(video_dev, video_get_internal_name(c), 1); + if (name.isEmpty()) { + break; + } + + if (video_card_available(c) && + device_is_valid(video_dev, machineId) && + !(video_card_get_flags(c) == video_card_get_flags(videoCard))) { + ui->comboBoxVideoSecondary->addItem(name, c); + if (c == gfxcard_2) + ui->comboBoxVideoSecondary->setCurrentIndex(ui->comboBoxVideoSecondary->count() - 1); + } + + c++; + } + + if (gfxcard_2 == 0 || (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0)) ui->comboBoxVideoSecondary->setCurrentIndex(0); } void SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state) { @@ -146,3 +174,20 @@ void SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state) { void SettingsDisplay::on_checkBoxXga_stateChanged(int state) { ui->pushButtonConfigureXga->setEnabled(state == Qt::Checked); } + +void SettingsDisplay::on_comboBoxVideoSecondary_currentIndexChanged(int index) +{ + if (index < 0) { + return; + } + int videoCard = ui->comboBoxVideoSecondary->currentData().toInt(); + ui->pushButtonConfigureSecondary->setEnabled(video_card_has_config(videoCard) > 0); +} + + +void SettingsDisplay::on_pushButtonConfigureSecondary_clicked() +{ + auto* device = video_card_getdevice(ui->comboBoxVideoSecondary->currentData().toInt()); + DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); +} + diff --git a/src/qt/qt_settingsdisplay.hpp b/src/qt/qt_settingsdisplay.hpp index 44e688d9a..06badd656 100644 --- a/src/qt/qt_settingsdisplay.hpp +++ b/src/qt/qt_settingsdisplay.hpp @@ -20,6 +20,12 @@ public: public slots: void onCurrentMachineChanged(int machineId); +private slots: + void on_pushButtonConfigureSecondary_clicked(); + +private slots: + void on_comboBoxVideoSecondary_currentIndexChanged(int index); + private slots: void on_checkBoxVoodoo_stateChanged(int state); void on_checkBoxXga_stateChanged(int state); diff --git a/src/qt/qt_settingsdisplay.ui b/src/qt/qt_settingsdisplay.ui index 58032a17b..c9bbaf1c7 100644 --- a/src/qt/qt_settingsdisplay.ui +++ b/src/qt/qt_settingsdisplay.ui @@ -26,16 +26,29 @@ 0 - - - - - + + - Video: + 8514/A + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + @@ -49,53 +62,57 @@ - - - - Configure - - - - + Voodoo Graphics - - - - 8514/A - - - - - + + Configure - + + + + Video: + + + + XGA - - - - Qt::Vertical + + + + Configure - - - 20 - 40 - + + + + + + Video #2: - + + + + + + + + + Configure + + diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index ba981e06a..b4a514422 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -80,14 +80,18 @@ typedef struct { uint16_t ma, maback; int con, coff, cursoron; int dispon, blink; - int vsynctime; + int vsynctime; int vadj; + int monitor_index, prev_monitor_index; int cols[256][2][2]; uint8_t *vram; } herculesplus_t; +#define VIDEO_MONITOR_PROLOGUE() { dev->prev_monitor_index = monitor_index_global; monitor_index_global = dev->monitor_index; } +#define VIDEO_MONITOR_EPILOGUE() { monitor_index_global = dev->prev_monitor_index; } + static video_timings_t timing_herculesplus = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; @@ -180,7 +184,7 @@ herculesplus_in(uint16_t port, void *priv) break; case 0x3ba: - /* 0x50: InColor card identity */ + /* 0x10: Hercules Plus card identity */ ret = (dev->stat & 0xf) | ((dev->stat & 8) << 4) | 0x10; break; } @@ -489,6 +493,7 @@ herculesplus_poll(void *priv) uint16_t ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff; int x, oldvc, oldsc; + VIDEO_MONITOR_PROLOGUE(); if (! dev->linepos) { timer_advance_u64(&dev->timer, dev->dispofftime); dev->stat |= 1; @@ -602,6 +607,8 @@ herculesplus_poll(void *priv) if ((dev->sc == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[10] & 31) >> 1)))) dev->con = 1; } + + VIDEO_MONITOR_EPILOGUE(); } @@ -615,10 +622,11 @@ herculesplus_init(const device_t *info) memset(dev, 0, sizeof(herculesplus_t)); dev->vram = (uint8_t *)malloc(0x10000); /* 64k VRAM */ + dev->monitor_index = monitor_index_global; timer_add(&dev->timer, herculesplus_poll, dev, 1); - mem_mapping_add(&dev->mapping, 0xb0000, 0x10000, + mem_mapping_add(&dev->mapping, 0xb0000, 0x08000, herculesplus_read,NULL,NULL, herculesplus_write,NULL,NULL, dev->vram, MEM_MAPPING_EXTERNAL, dev); diff --git a/src/video/vid_table.c b/src/video/vid_table.c index e1a799fbe..ca867263d 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -110,13 +110,13 @@ video_cards[] = { { &cpqega_device }, { &ega_device }, { &g2_gc205_device }, - { &hercules_device }, - { &herculesplus_device }, + { &hercules_device, VIDEO_FLAG_TYPE_MDA }, + { &herculesplus_device, VIDEO_FLAG_TYPE_MDA }, { &incolor_device }, { &im1024_device }, { &iskra_ega_device }, { &et4000_kasan_isa_device }, - { &mda_device }, + { &mda_device, VIDEO_FLAG_TYPE_MDA }, { &genius_device }, { &nga_device }, { &ogc_device }, @@ -299,7 +299,7 @@ video_prepare(void) for (int i = 0; i < MONITORS_NUM; i++) { /* Reset the CGA palette. */ - monitors[i].mon_cga_palette = 0; + if (monitors[i].mon_cga_palette) *monitors[i].mon_cga_palette = 0; cgapal_rebuild_monitor(i); /* Do an inform on the default values, so that that there's some sane values initialized @@ -340,14 +340,17 @@ video_reset(int card) /* Initialize the video card. */ device_add(video_cards[card].device); + } - if (herc_enabled) { + if (!(card == VID_NONE) + && !machine_has_flags(machine, MACHINE_VIDEO_ONLY) + && gfxcard_2 != 0 + && (video_cards[gfxcard_2].flags != video_cards[gfxcard].flags)) { video_monitor_init(1); monitor_index_global = 1; device_add(&hercules_device); monitor_index_global = 0; } - } /* Enable the Voodoo if configured. */ if (voodoo_enabled) @@ -366,6 +369,11 @@ video_card_available(int card) return(1); } +int +video_card_get_flags(int card) +{ + return video_cards[card].flags; +} const device_t * video_card_getdevice(int card) diff --git a/src/video/video.c b/src/video/video.c index b01e00058..1c8312982 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -105,7 +105,6 @@ monitor_t monitors[MONITORS_NUM]; monitor_settings_t monitor_settings[MONITORS_NUM]; atomic_bool doresize_monitors[MONITORS_NUM]; int monitor_index_global = 0; -int herc_enabled = 0; #ifdef _WIN32 void * __cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size) = memcpy; @@ -621,11 +620,16 @@ cgapal_rebuild_monitor(int monitor_index) { int c; uint32_t* palette_lookup = monitors[monitor_index].mon_pal_lookup; - int cga_palette_monitor = *monitors[monitor_index].mon_cga_palette; + int cga_palette_monitor = 0; /* We cannot do this (yet) if we have not been enabled yet. */ if (video_6to8 == NULL) return; + if (monitors[monitor_index].target_buffer == NULL || + monitors[monitor_index].mon_cga_palette == NULL) return; + + cga_palette_monitor = *monitors[monitor_index].mon_cga_palette; + for (c=0; c<256; c++) { palette_lookup[c] = makecol(video_6to8[cgapal[c].r], video_6to8[cgapal[c].g], @@ -737,14 +741,14 @@ video_update_timing(void) *vid_timing_write_b = ISA_CYCLES(monitor_vid_timings->write_b); *vid_timing_write_w = ISA_CYCLES(monitor_vid_timings->write_w); *vid_timing_write_l = ISA_CYCLES(monitor_vid_timings->write_l); - } else if (vid_timings->type == VIDEO_PCI) { + } else if (monitor_vid_timings->type == VIDEO_PCI) { *vid_timing_read_b = (int)(pci_timing * monitor_vid_timings->read_b); *vid_timing_read_w = (int)(pci_timing * monitor_vid_timings->read_w); *vid_timing_read_l = (int)(pci_timing * monitor_vid_timings->read_l); *vid_timing_write_b = (int)(pci_timing * monitor_vid_timings->write_b); *vid_timing_write_w = (int)(pci_timing * monitor_vid_timings->write_w); *vid_timing_write_l = (int)(pci_timing * monitor_vid_timings->write_l); - } else if (vid_timings->type == VIDEO_AGP) { + } else if (monitor_vid_timings->type == VIDEO_AGP) { *vid_timing_read_b = (int)(agp_timing * monitor_vid_timings->read_b); *vid_timing_read_w = (int)(agp_timing * monitor_vid_timings->read_w); *vid_timing_read_l = (int)(agp_timing * monitor_vid_timings->read_l);