From cc68ce9d8becbd429e5e5f56640681395bf3dc86 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 7 May 2023 22:18:01 +0300 Subject: [PATCH] Implemented resolutions selector in Launcher using SDL --- launcher/CMakeLists.txt | 4 + launcher/mainwindow_moc.cpp | 1 - launcher/settingsView/csettingsview_moc.cpp | 96 ++++++++++++--------- launcher/settingsView/csettingsview_moc.h | 4 +- launcher/settingsView/csettingsview_moc.ui | 10 +-- 5 files changed, 64 insertions(+), 51 deletions(-) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index cccde89de..0977e554a 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -133,6 +133,10 @@ if(APPLE) set_property(GLOBAL PROPERTY AUTOGEN_TARGETS_FOLDER vcmilauncher) endif() +if (NOT APPLE_IOS AND NOT ANDROID) + target_link_libraries(vcmilauncher SDL2::SDL2) +endif() + target_link_libraries(vcmilauncher ${VCMI_LIB_TARGET} Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network) target_include_directories(vcmilauncher PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/launcher/mainwindow_moc.cpp b/launcher/mainwindow_moc.cpp index 6833ccd7d..37a190b95 100644 --- a/launcher/mainwindow_moc.cpp +++ b/launcher/mainwindow_moc.cpp @@ -110,7 +110,6 @@ MainWindow::MainWindow(QWidget * parent) else enterSetup(); - ui->settingsView->isExtraResolutionsModEnabled = ui->modlistView->isExtraResolutionsModEnabled(); ui->settingsView->setDisplayList(); connect(ui->modlistView, &CModListView::extraResolutionsEnabledChanged, ui->settingsView, &CSettingsView::fillValidResolutions); diff --git a/launcher/settingsView/csettingsview_moc.cpp b/launcher/settingsView/csettingsview_moc.cpp index 7010db19a..bd19a91e0 100644 --- a/launcher/settingsView/csettingsview_moc.cpp +++ b/launcher/settingsView/csettingsview_moc.cpp @@ -25,6 +25,10 @@ #include "../../lib/CConfigHandler.h" #include "../../lib/VCMIDirs.h" +#ifndef VCMI_MOBILE +#include +#endif + namespace { QString resolutionToString(const QSize & resolution) @@ -67,9 +71,9 @@ void CSettingsView::loadSettings() { ui->comboBoxShowIntro->setCurrentIndex(settings["video"]["showIntro"].Bool()); -#ifdef Q_OS_IOS - ui->comboBoxFullScreen->setCurrentIndex(1); - ui->comboBoxFullScreen->setDisabled(true); +#ifdef VCMI_MOBILE + ui->comboBoxFullScreen->hide(); + ui->labelFullScreen->hide(); #else if (settings["video"]["realFullscreen"].Bool()) ui->comboBoxFullScreen->setCurrentIndex(2); @@ -106,54 +110,54 @@ void CSettingsView::loadSettings() ui->comboBoxCursorType->setCurrentIndex((int)cursorTypeIndex); } -void CSettingsView::fillValidResolutions(bool isExtraResolutionsModEnabled) +void CSettingsView::fillValidResolutions() { - this->isExtraResolutionsModEnabled = isExtraResolutionsModEnabled; fillValidResolutionsForScreen(ui->comboBoxDisplayIndex->isVisible() ? ui->comboBoxDisplayIndex->currentIndex() : 0); } +#ifndef VCMI_MOBILE + +static QVector findAvailableResolutions(int displayIndex) +{ + // Ugly workaround since we don't actually need SDL in Launcher + // However Qt at the moment provides no way to query list of available resolutions + QVector result; + SDL_Init(SDL_INIT_VIDEO); + + int modesCount = SDL_GetNumDisplayModes(displayIndex); + + for (int i =0; i < modesCount; ++i) + { + SDL_DisplayMode mode; + if (SDL_GetDisplayMode(displayIndex, i, &mode) != 0) + continue; + + QSize resolution(mode.w, mode.h); + + result.push_back(resolution); + } + + boost::range::sort(result, [](const auto & left, const auto & right) + { + return left.height() * left.width() < right.height() * right.width(); + }); + + result.erase(boost::unique(result).end(), result.end()); + + SDL_Quit(); + + return result; +} + void CSettingsView::fillValidResolutionsForScreen(int screenIndex) { ui->comboBoxResolution->blockSignals(true); // avoid saving wrong resolution after adding first item from the list ui->comboBoxResolution->clear(); - // TODO: read available resolutions from all mods - QVariantList resolutions; - if(isExtraResolutionsModEnabled) - { - const auto extrasResolutionsPath = settings["launcher"]["extraResolutionsModPath"].String().c_str(); - const auto extrasResolutionsJson = JsonUtils::JsonFromFile(CLauncherDirs::get().modsPath() + extrasResolutionsPath); - resolutions = extrasResolutionsJson.toMap().value(QLatin1String{"GUISettings"}).toList(); - } - if(resolutions.isEmpty()) - { - ui->comboBoxResolution->blockSignals(false); - ui->comboBoxResolution->addItem(resolutionToString({800, 600})); - return; - } - - const auto screens = qGuiApp->screens(); - const auto currentScreen = screenIndex < screens.size() ? screens[screenIndex] : qGuiApp->primaryScreen(); - [[maybe_unused]] const auto screenSize = currentScreen->size(); + QVector resolutions = findAvailableResolutions(screenIndex); for(const auto & entry : resolutions) - { - const auto resolutionMap = entry.toMap().value(QLatin1String{"resolution"}).toMap(); - if(resolutionMap.isEmpty()) - continue; - - const auto widthValue = resolutionMap[QLatin1String{"x"}]; - const auto heightValue = resolutionMap[QLatin1String{"y"}]; - if(!widthValue.isValid() || !heightValue.isValid()) - continue; - - const QSize resolution{widthValue.toInt(), heightValue.toInt()}; -#ifndef VCMI_IOS - if(screenSize.width() < resolution.width() || screenSize.height() < resolution.height()) - continue; -#endif - ui->comboBoxResolution->addItem(resolutionToString(resolution)); - } + ui->comboBoxResolution->addItem(resolutionToString(entry)); int resX = settings["video"]["resolution"]["width"].Integer(); int resY = settings["video"]["resolution"]["height"].Integer(); @@ -162,10 +166,18 @@ void CSettingsView::fillValidResolutionsForScreen(int screenIndex) ui->comboBoxResolution->blockSignals(false); - // if selected resolution no longer exists, force update value to the first resolution + // if selected resolution no longer exists, force update value to the largest (last) resolution if(resIndex == -1) - ui->comboBoxResolution->setCurrentIndex(0); + ui->comboBoxResolution->setCurrentIndex(ui->comboBoxResolution->count() - 1); } +#else +void CSettingsView::fillValidResolutionsForScreen(int screenIndex) +{ + // resolutions are not selectable on mobile platforms + ui->comboBoxResolution->hide(); + ui->labelResolution->hide(); +} +#endif CSettingsView::CSettingsView(QWidget * parent) : QWidget(parent), ui(new Ui::CSettingsView) diff --git a/launcher/settingsView/csettingsview_moc.h b/launcher/settingsView/csettingsview_moc.h index 49cdb822a..2818a2193 100644 --- a/launcher/settingsView/csettingsview_moc.h +++ b/launcher/settingsView/csettingsview_moc.h @@ -29,10 +29,8 @@ public: void changeEvent(QEvent *event) override; void showEvent(QShowEvent * event) override; - bool isExtraResolutionsModEnabled{}; - public slots: - void fillValidResolutions(bool isExtraResolutionsModEnabled); + void fillValidResolutions(); private slots: void on_comboBoxResolution_currentTextChanged(const QString & arg1); diff --git a/launcher/settingsView/csettingsview_moc.ui b/launcher/settingsView/csettingsview_moc.ui index 4e46c899f..84f4592e1 100644 --- a/launcher/settingsView/csettingsview_moc.ui +++ b/launcher/settingsView/csettingsview_moc.ui @@ -112,9 +112,9 @@ 0 - 0 + -107 620 - 793 + 745 @@ -253,17 +253,17 @@ - Off + Windowed - On + Borderless fullscreen - Real + Exclusive fullscreen