diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 0c93474da9..bff26b63c8 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -90,6 +90,7 @@ target_link_libraries(omwlauncher ${Boost_LIBRARIES} ${OGRE_LIBRARIES} ${OGRE_STATIC_PLUGINS} + ${SDL2_LIBRARY} ${QT_LIBRARIES} components ) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index d9e10e764a..49f7ef7c46 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -42,6 +43,7 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &g connect(rendererComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(rendererChanged(const QString&))); connect(fullScreenCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotFullScreenChanged(int))); connect(standardRadioButton, SIGNAL(toggled(bool)), this, SLOT(slotStandardToggled(bool))); + connect(screenComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(screenChanged(const QString&))); } @@ -144,17 +146,84 @@ bool GraphicsPage::setupOgre() } antiAliasingComboBox->clear(); - resolutionComboBox->clear(); antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem)); - resolutionComboBox->addItems(getAvailableResolutions(mSelectedRenderSystem)); - // Load the rest of the values - loadSettings(); return true; } -void GraphicsPage::loadSettings() +bool GraphicsPage::setupSDL() { + // FIXME: do setupSDLWordaround here instead. + // seems like Qt, SDL and Ogre don't like each other + // results in a segfault if SDL is initialized after Qt + + QStringList screens; + for (int i = 0; i < mScreenCount; i++) + { + screens.append(QString("Screen ") + QString::number(i + 1)); + } + screenComboBox->addItems(screens); + + return true; +} + +std::vector GraphicsPage::mVideoModes; +int GraphicsPage::mScreenCount; + +bool GraphicsPage::setupSDLWordaround() { + if (SDL_Init(SDL_INIT_VIDEO) != 0) + { + std::cout << "SDL_Init failed: " << SDL_GetError() << std::endl; + return false; + } + + SDL_DisplayMode mode; + int displayIndex, modeIndex, displays = SDL_GetNumVideoDisplays(); + mScreenCount = displays; + + if(displays < 0) + { + std::cout << "SDL_GetNumVideoDisplays failed: " << SDL_GetError() << std::endl; + SDL_Quit(); + return false; + } + + for (displayIndex = 0; displayIndex < displays; displayIndex++) + { + int modes = SDL_GetNumDisplayModes(displayIndex); + if(modes < 0) + { + std::cout << "SDL_GetNumDisplayModes failed: " << SDL_GetError() << std::endl; + SDL_Quit(); + return false; + } + for (modeIndex = 0; modeIndex < modes; modeIndex++) + { + if (SDL_GetDisplayMode(displayIndex, modeIndex, &mode) < 0) + { + std::cout << "SDL_GetDisplayMode failed: " << SDL_GetError() << std::endl; + SDL_Quit(); + return false; + } + VideoMode vmode; + vmode.w = mode.w; + vmode.h = mode.h; + vmode.screen = displayIndex; + mVideoModes.push_back(vmode); + } + } + + SDL_Quit(); + return true; +} + +bool GraphicsPage::loadSettings() +{ + if (!setupSDL()) + return false; + if (!setupOgre()) + return false; + if (mGraphicsSettings.value(QString("Video/vsync")) == QLatin1String("true")) vSyncCheckBox->setCheckState(Qt::Checked); @@ -168,6 +237,9 @@ void GraphicsPage::loadSettings() QString width = mGraphicsSettings.value(QString("Video/resolution x")); QString height = mGraphicsSettings.value(QString("Video/resolution y")); QString resolution = width + QString(" x ") + height; + QString screen = mGraphicsSettings.value(QString("Video/screen")); + + screenComboBox->setCurrentIndex(screenComboBox->findText(QString("Screen ") + screen)); int resIndex = resolutionComboBox->findText(resolution, Qt::MatchStartsWith); @@ -180,6 +252,8 @@ void GraphicsPage::loadSettings() customHeightSpinBox->setValue(height.toInt()); } + + return true; } void GraphicsPage::saveSettings() @@ -205,6 +279,11 @@ void GraphicsPage::saveSettings() mGraphicsSettings.setValue(QString("Video/resolution x"), QString::number(customWidthSpinBox->value())); mGraphicsSettings.setValue(QString("Video/resolution y"), QString::number(customHeightSpinBox->value())); } + + QRegExp screenRe(QString(".*(\\d+)")); + if(screenRe.exactMatch(screenComboBox->currentText())) { + mGraphicsSettings.setValue(QString("Video/screen"), screenRe.cap(1)); + } } QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer) @@ -240,6 +319,33 @@ QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSy return result; } +#if 1 +QStringList GraphicsPage::getAvailableResolutions(int screen) +{ + QStringList result; + for (std::vector::iterator it = mVideoModes.begin(); it != mVideoModes.end(); it++) + { + VideoMode mode = *it; + if(mode.screen != screen) + continue; + + QString aspect = getAspect(mode.w, mode.h); + QString resolution = QString::number(mode.w) + QString(" x ") + QString::number(mode.h); + + if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) { + resolution.append(tr("\t(Wide ") + aspect + ")"); + + } else if (aspect == QLatin1String("4:3")) { + resolution.append(tr("\t(Standard 4:3)")); + } + + result.append(resolution); + } + return result; +} +#endif + +#if 0 QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer) { QString key("Video Mode"); @@ -288,14 +394,15 @@ QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer) return result; } +#endif QRect GraphicsPage::getMaximumResolution() { - QRect max, res; + QRect max; int i, screens = QApplication::desktop()->screenCount(); for (i = 0; i < screens; i++) { - res = QApplication::desktop()->screenGeometry(i); + QRect res = QApplication::desktop()->screenGeometry(i); if (res.width() > max.width()) max.setWidth(res.width()); if (res.height() > max.height()) @@ -309,10 +416,17 @@ void GraphicsPage::rendererChanged(const QString &renderer) mSelectedRenderSystem = mOgre->getRenderSystemByName(renderer.toStdString()); antiAliasingComboBox->clear(); - resolutionComboBox->clear(); antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem)); - resolutionComboBox->addItems(getAvailableResolutions(mSelectedRenderSystem)); +} + +void GraphicsPage::screenChanged(const QString &screen) +{ + QRegExp screenRe(QString(".*(\\d+)")); + if(screenRe.exactMatch(screen)) { + resolutionComboBox->clear(); + resolutionComboBox->addItems(getAvailableResolutions(screenRe.cap(1).toInt() - 1)); + } } void GraphicsPage::slotFullScreenChanged(int state) diff --git a/apps/launcher/graphicspage.hpp b/apps/launcher/graphicspage.hpp index 37f56d2bb6..5ed4e5632e 100644 --- a/apps/launcher/graphicspage.hpp +++ b/apps/launcher/graphicspage.hpp @@ -18,6 +18,13 @@ #include "ui_graphicspage.h" +struct VideoMode +{ + int w; + int h; + int screen; +}; + class GraphicsSettings; namespace Files { struct ConfigurationManager; } @@ -30,10 +37,14 @@ public: GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSettings, QWidget *parent = 0); void saveSettings(); - bool setupOgre(); + bool loadSettings(); + + // SDL workaround + static bool setupSDLWordaround(); public slots: void rendererChanged(const QString &renderer); + void screenChanged(const QString &screen); private slots: void slotFullScreenChanged(int state); @@ -55,11 +66,14 @@ private: GraphicsSettings &mGraphicsSettings; QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer); - QStringList getAvailableResolutions(Ogre::RenderSystem *renderer); + QStringList getAvailableResolutions(int screen); QRect getMaximumResolution(); - void loadSettings(); + static std::vector mVideoModes; + static int mScreenCount; + bool setupOgre(); + bool setupSDL(); }; #endif diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index 09da1d615f..e444bb9f2b 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -3,9 +3,14 @@ #include #include "maindialog.hpp" +// SDL workaround +#include "graphicspage.hpp" int main(int argc, char *argv[]) { + // SDL woraround + GraphicsPage::setupSDLWordaround(); + QApplication app(argc, argv); // Now we make sure the current dir is set to application path diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 10a3f015a3..b75d09c51c 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -292,8 +292,8 @@ bool MainDialog::setup() // Now create the pages as they need the settings createPages(); - // Call this so we can exit on Ogre errors before mainwindow is shown - if (!mGraphicsPage->setupOgre()) + // Call this so we can exit on Ogre/SDL errors before mainwindow is shown + if (!mGraphicsPage->loadSettings()) return false; loadSettings(); diff --git a/files/ui/graphicspage.ui b/files/ui/graphicspage.ui index 5c330cebd5..7e9fe00d9e 100644 --- a/files/ui/graphicspage.ui +++ b/files/ui/graphicspage.ui @@ -58,6 +58,13 @@ + + + Screen: + + + + Resolution: @@ -71,6 +78,9 @@ + + +